1// Copyright 2019 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17import ( 18 "path/filepath" 19 "strings" 20 "testing" 21 22 "github.com/google/blueprint/proptools" 23 24 "android/soong/android" 25 "android/soong/java/config" 26) 27 28func TestClasspath(t *testing.T) { 29 const frameworkAidl = "-I" + defaultJavaDir + "/framework/aidl" 30 var classpathTestcases = []struct { 31 name string 32 unbundled bool 33 moduleType string 34 host android.OsClass 35 properties string 36 37 // for java 8 38 bootclasspath []string 39 java8classpath []string 40 41 // for java 9 42 system string 43 java9classpath []string 44 45 forces8 bool // if set, javac will always be called with java 8 arguments 46 47 aidl string 48 }{ 49 { 50 name: "default", 51 bootclasspath: config.StableCorePlatformBootclasspathLibraries, 52 system: config.StableCorePlatformSystemModules, 53 java8classpath: config.FrameworkLibraries, 54 java9classpath: config.FrameworkLibraries, 55 aidl: frameworkAidl, 56 }, 57 { 58 name: `sdk_version:"core_platform"`, 59 properties: `sdk_version:"core_platform"`, 60 bootclasspath: config.StableCorePlatformBootclasspathLibraries, 61 system: config.StableCorePlatformSystemModules, 62 java8classpath: []string{}, 63 aidl: "", 64 }, 65 { 66 name: "blank sdk version", 67 properties: `sdk_version: "",`, 68 bootclasspath: config.StableCorePlatformBootclasspathLibraries, 69 system: config.StableCorePlatformSystemModules, 70 java8classpath: config.FrameworkLibraries, 71 java9classpath: config.FrameworkLibraries, 72 aidl: frameworkAidl, 73 }, 74 { 75 76 name: "sdk v29", 77 properties: `sdk_version: "29",`, 78 bootclasspath: []string{`""`}, 79 forces8: true, 80 java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 81 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 82 }, 83 { 84 85 name: "sdk v30", 86 properties: `sdk_version: "30",`, 87 bootclasspath: []string{`""`}, 88 system: "sdk_public_30_system_modules", 89 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 90 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 91 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 92 }, 93 { 94 95 name: "current", 96 properties: `sdk_version: "current",`, 97 bootclasspath: []string{"android_stubs_current", "core-lambda-stubs"}, 98 system: "core-current-stubs-system-modules", 99 java9classpath: []string{"android_stubs_current"}, 100 aidl: "-pout/soong/framework.aidl", 101 }, 102 { 103 104 name: "system_current", 105 properties: `sdk_version: "system_current",`, 106 bootclasspath: []string{"android_system_stubs_current", "core-lambda-stubs"}, 107 system: "core-current-stubs-system-modules", 108 java9classpath: []string{"android_system_stubs_current"}, 109 aidl: "-pout/soong/framework.aidl", 110 }, 111 { 112 113 name: "system_29", 114 properties: `sdk_version: "system_29",`, 115 bootclasspath: []string{`""`}, 116 forces8: true, 117 java8classpath: []string{"prebuilts/sdk/29/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 118 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 119 }, 120 { 121 122 name: "system_30", 123 properties: `sdk_version: "system_30",`, 124 bootclasspath: []string{`""`}, 125 system: "sdk_public_30_system_modules", 126 java8classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 127 java9classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 128 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 129 }, 130 { 131 132 name: "test_current", 133 properties: `sdk_version: "test_current",`, 134 bootclasspath: []string{"android_test_stubs_current", "core-lambda-stubs"}, 135 system: "core-current-stubs-system-modules", 136 java9classpath: []string{"android_test_stubs_current"}, 137 aidl: "-pout/soong/framework.aidl", 138 }, 139 { 140 141 name: "core_current", 142 properties: `sdk_version: "core_current",`, 143 bootclasspath: []string{"core.current.stubs", "core-lambda-stubs"}, 144 system: "core-current-stubs-system-modules", 145 }, 146 { 147 148 name: "nostdlib", 149 properties: `sdk_version: "none", system_modules: "none"`, 150 system: "none", 151 bootclasspath: []string{`""`}, 152 java8classpath: []string{}, 153 }, 154 { 155 156 name: "nostdlib system_modules", 157 properties: `sdk_version: "none", system_modules: "stable-core-platform-api-stubs-system-modules"`, 158 system: "stable-core-platform-api-stubs-system-modules", 159 bootclasspath: []string{"stable-core-platform-api-stubs-system-modules-lib"}, 160 java8classpath: []string{}, 161 }, 162 { 163 164 name: "host default", 165 moduleType: "java_library_host", 166 properties: ``, 167 host: android.Host, 168 bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"}, 169 java8classpath: []string{}, 170 }, 171 { 172 173 name: "host supported default", 174 host: android.Host, 175 properties: `host_supported: true,`, 176 java8classpath: []string{}, 177 bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"}, 178 }, 179 { 180 name: "host supported nostdlib", 181 host: android.Host, 182 properties: `host_supported: true, sdk_version: "none", system_modules: "none"`, 183 java8classpath: []string{}, 184 }, 185 { 186 187 name: "unbundled sdk v29", 188 unbundled: true, 189 properties: `sdk_version: "29",`, 190 bootclasspath: []string{`""`}, 191 forces8: true, 192 java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 193 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 194 }, 195 { 196 197 name: "unbundled sdk v30", 198 unbundled: true, 199 properties: `sdk_version: "30",`, 200 bootclasspath: []string{`""`}, 201 system: "sdk_public_30_system_modules", 202 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 203 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 204 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 205 }, 206 { 207 208 name: "unbundled current", 209 unbundled: true, 210 properties: `sdk_version: "current",`, 211 bootclasspath: []string{`""`}, 212 system: "sdk_public_current_system_modules", 213 java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 214 java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 215 aidl: "-pprebuilts/sdk/current/public/framework.aidl", 216 }, 217 218 { 219 name: "module_current", 220 properties: `sdk_version: "module_current",`, 221 bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"}, 222 system: "core-module-lib-stubs-system-modules", 223 java9classpath: []string{"android_module_lib_stubs_current"}, 224 aidl: "-pout/soong/framework_non_updatable.aidl", 225 }, 226 { 227 name: "system_server_current", 228 properties: `sdk_version: "system_server_current",`, 229 bootclasspath: []string{"android_system_server_stubs_current", "core-lambda-stubs"}, 230 system: "core-module-lib-stubs-system-modules", 231 java9classpath: []string{"android_system_server_stubs_current"}, 232 aidl: "-pout/soong/framework.aidl", 233 }, 234 } 235 236 for _, testcase := range classpathTestcases { 237 t.Run(testcase.name, func(t *testing.T) { 238 moduleType := "java_library" 239 if testcase.moduleType != "" { 240 moduleType = testcase.moduleType 241 } 242 243 props := ` 244 name: "foo", 245 srcs: ["a.java"], 246 target: { 247 android: { 248 srcs: ["bar-doc/IFoo.aidl"], 249 }, 250 }, 251 ` 252 bp := moduleType + " {" + props + testcase.properties + ` 253 }` 254 bpJava8 := moduleType + " {" + props + `java_version: "1.8", 255 ` + testcase.properties + ` 256 }` 257 258 variant := "android_common" 259 if testcase.host == android.Host { 260 variant = android.BuildOs.String() + "_common" 261 } 262 263 convertModulesToPaths := func(cp []string) []string { 264 ret := make([]string, len(cp)) 265 for i, e := range cp { 266 ret[i] = defaultModuleToPath(e) 267 } 268 return ret 269 } 270 271 bootclasspath := convertModulesToPaths(testcase.bootclasspath) 272 java8classpath := convertModulesToPaths(testcase.java8classpath) 273 java9classpath := convertModulesToPaths(testcase.java9classpath) 274 275 bc := "" 276 var bcDeps []string 277 if len(bootclasspath) > 0 { 278 bc = "-bootclasspath " + strings.Join(bootclasspath, ":") 279 if bootclasspath[0] != `""` { 280 bcDeps = bootclasspath 281 } 282 } 283 284 j8c := "" 285 if len(java8classpath) > 0 { 286 j8c = "-classpath " + strings.Join(java8classpath, ":") 287 } 288 289 j9c := "" 290 if len(java9classpath) > 0 { 291 j9c = "-classpath " + strings.Join(java9classpath, ":") 292 } 293 294 system := "" 295 var systemDeps []string 296 if testcase.system == "none" { 297 system = "--system=none" 298 } else if testcase.system != "" { 299 dir := "" 300 if strings.HasPrefix(testcase.system, "sdk_public_") { 301 dir = "prebuilts/sdk" 302 } else { 303 dir = defaultJavaDir 304 } 305 system = "--system=" + filepath.Join("out", "soong", ".intermediates", dir, testcase.system, "android_common", "system") 306 // The module-relative parts of these paths are hardcoded in system_modules.go: 307 systemDeps = []string{ 308 filepath.Join("out", "soong", ".intermediates", dir, testcase.system, "android_common", "system", "lib", "modules"), 309 filepath.Join("out", "soong", ".intermediates", dir, testcase.system, "android_common", "system", "lib", "jrt-fs.jar"), 310 filepath.Join("out", "soong", ".intermediates", dir, testcase.system, "android_common", "system", "release"), 311 } 312 } 313 314 checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) { 315 foo := result.ModuleForTests("foo", variant) 316 javac := foo.Rule("javac") 317 var deps []string 318 319 aidl := foo.MaybeRule("aidl") 320 if aidl.Rule != nil { 321 deps = append(deps, android.PathRelativeToTop(aidl.Output)) 322 } 323 324 got := javac.Args["bootClasspath"] 325 expected := "" 326 if isJava8 || testcase.forces8 { 327 expected = bc 328 deps = append(deps, bcDeps...) 329 } else { 330 expected = system 331 deps = append(deps, systemDeps...) 332 } 333 if got != expected { 334 t.Errorf("bootclasspath expected %q != got %q", expected, got) 335 } 336 337 if isJava8 || testcase.forces8 { 338 expected = j8c 339 deps = append(deps, java8classpath...) 340 } else { 341 expected = j9c 342 deps = append(deps, java9classpath...) 343 } 344 got = javac.Args["classpath"] 345 if got != expected { 346 t.Errorf("classpath expected %q != got %q", expected, got) 347 } 348 349 android.AssertPathsRelativeToTopEquals(t, "implicits", deps, javac.Implicits) 350 } 351 352 fixtureFactory := android.GroupFixturePreparers( 353 prepareForJavaTest, 354 FixtureWithPrebuiltApis(map[string][]string{ 355 "29": {}, 356 "30": {}, 357 "current": {}, 358 }), 359 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 360 if testcase.unbundled { 361 variables.Unbundled_build = proptools.BoolPtr(true) 362 variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) 363 } 364 }), 365 android.FixtureModifyEnv(func(env map[string]string) { 366 if env["ANDROID_JAVA8_HOME"] == "" { 367 env["ANDROID_JAVA8_HOME"] = "jdk8" 368 } 369 }), 370 ) 371 372 // Test with legacy javac -source 1.8 -target 1.8 373 t.Run("Java language level 8", func(t *testing.T) { 374 result := fixtureFactory.RunTestWithBp(t, bpJava8) 375 376 checkClasspath(t, result, true /* isJava8 */) 377 378 if testcase.host != android.Host { 379 aidl := result.ModuleForTests("foo", variant).Rule("aidl") 380 381 android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.") 382 } 383 }) 384 385 // Test with default javac -source 9 -target 9 386 t.Run("Java language level 9", func(t *testing.T) { 387 result := fixtureFactory.RunTestWithBp(t, bp) 388 389 checkClasspath(t, result, false /* isJava8 */) 390 391 if testcase.host != android.Host { 392 aidl := result.ModuleForTests("foo", variant).Rule("aidl") 393 394 android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.") 395 } 396 }) 397 398 prepareWithPlatformVersionRel := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 399 variables.Platform_sdk_codename = proptools.StringPtr("REL") 400 variables.Platform_sdk_final = proptools.BoolPtr(true) 401 }) 402 403 // Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8 404 t.Run("REL + Java language level 8", func(t *testing.T) { 405 result := android.GroupFixturePreparers( 406 fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8) 407 408 checkClasspath(t, result, true /* isJava8 */) 409 }) 410 411 // Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9 412 t.Run("REL + Java language level 9", func(t *testing.T) { 413 result := android.GroupFixturePreparers( 414 fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bp) 415 416 checkClasspath(t, result, false /* isJava8 */) 417 }) 418 }) 419 } 420} 421