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 "reflect" 20 "strings" 21 "testing" 22 23 "github.com/google/blueprint/proptools" 24 25 "android/soong/android" 26 "android/soong/java/config" 27) 28 29func TestClasspath(t *testing.T) { 30 var classpathTestcases = []struct { 31 name string 32 unbundled bool 33 pdk bool 34 moduleType string 35 host android.OsClass 36 properties string 37 38 // for java 8 39 bootclasspath []string 40 java8classpath []string 41 42 // for java 9 43 system string 44 java9classpath []string 45 46 forces8 bool // if set, javac will always be called with java 8 arguments 47 48 aidl string 49 }{ 50 { 51 name: "default", 52 bootclasspath: config.DefaultBootclasspathLibraries, 53 system: config.DefaultSystemModules, 54 java8classpath: config.DefaultLibraries, 55 java9classpath: config.DefaultLibraries, 56 aidl: "-Iframework/aidl", 57 }, 58 { 59 name: `sdk_version:"core_platform"`, 60 properties: `sdk_version:"core_platform"`, 61 bootclasspath: config.DefaultBootclasspathLibraries, 62 system: config.DefaultSystemModules, 63 java8classpath: []string{}, 64 aidl: "", 65 }, 66 { 67 name: "blank sdk version", 68 properties: `sdk_version: "",`, 69 bootclasspath: config.DefaultBootclasspathLibraries, 70 system: config.DefaultSystemModules, 71 java8classpath: config.DefaultLibraries, 72 java9classpath: config.DefaultLibraries, 73 aidl: "-Iframework/aidl", 74 }, 75 { 76 77 name: "sdk v29", 78 properties: `sdk_version: "29",`, 79 bootclasspath: []string{`""`}, 80 forces8: true, 81 java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 82 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 83 }, 84 { 85 86 name: "sdk v30", 87 properties: `sdk_version: "30",`, 88 bootclasspath: []string{`""`}, 89 system: "sdk_public_30_system_modules", 90 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 91 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 92 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 93 }, 94 { 95 96 name: "current", 97 properties: `sdk_version: "current",`, 98 bootclasspath: []string{"android_stubs_current", "core-lambda-stubs"}, 99 system: "core-current-stubs-system-modules", 100 java9classpath: []string{"android_stubs_current"}, 101 aidl: "-p" + buildDir + "/framework.aidl", 102 }, 103 { 104 105 name: "system_current", 106 properties: `sdk_version: "system_current",`, 107 bootclasspath: []string{"android_system_stubs_current", "core-lambda-stubs"}, 108 system: "core-current-stubs-system-modules", 109 java9classpath: []string{"android_system_stubs_current"}, 110 aidl: "-p" + buildDir + "/framework.aidl", 111 }, 112 { 113 114 name: "system_29", 115 properties: `sdk_version: "system_29",`, 116 bootclasspath: []string{`""`}, 117 forces8: true, 118 java8classpath: []string{"prebuilts/sdk/29/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 119 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 120 }, 121 { 122 123 name: "system_30", 124 properties: `sdk_version: "system_30",`, 125 bootclasspath: []string{`""`}, 126 system: "sdk_public_30_system_modules", 127 java8classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 128 java9classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 129 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 130 }, 131 { 132 133 name: "test_current", 134 properties: `sdk_version: "test_current",`, 135 bootclasspath: []string{"android_test_stubs_current", "core-lambda-stubs"}, 136 system: "core-current-stubs-system-modules", 137 java9classpath: []string{"android_test_stubs_current"}, 138 aidl: "-p" + buildDir + "/framework.aidl", 139 }, 140 { 141 142 name: "core_current", 143 properties: `sdk_version: "core_current",`, 144 bootclasspath: []string{"core.current.stubs", "core-lambda-stubs"}, 145 system: "core-current-stubs-system-modules", 146 java9classpath: []string{"core.current.stubs"}, 147 }, 148 { 149 150 name: "nostdlib", 151 properties: `sdk_version: "none", system_modules: "none"`, 152 system: "none", 153 bootclasspath: []string{`""`}, 154 java8classpath: []string{}, 155 }, 156 { 157 158 name: "nostdlib system_modules", 159 properties: `sdk_version: "none", system_modules: "core-platform-api-stubs-system-modules"`, 160 system: "core-platform-api-stubs-system-modules", 161 bootclasspath: []string{"core-platform-api-stubs-system-modules-lib"}, 162 java8classpath: []string{}, 163 }, 164 { 165 166 name: "host default", 167 moduleType: "java_library_host", 168 properties: ``, 169 host: android.Host, 170 bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"}, 171 java8classpath: []string{}, 172 }, 173 { 174 175 name: "host supported default", 176 host: android.Host, 177 properties: `host_supported: true,`, 178 java8classpath: []string{}, 179 bootclasspath: []string{"jdk8/jre/lib/jce.jar", "jdk8/jre/lib/rt.jar"}, 180 }, 181 { 182 name: "host supported nostdlib", 183 host: android.Host, 184 properties: `host_supported: true, sdk_version: "none", system_modules: "none"`, 185 java8classpath: []string{}, 186 }, 187 { 188 189 name: "unbundled sdk v29", 190 unbundled: true, 191 properties: `sdk_version: "29",`, 192 bootclasspath: []string{`""`}, 193 forces8: true, 194 java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 195 aidl: "-pprebuilts/sdk/29/public/framework.aidl", 196 }, 197 { 198 199 name: "unbundled sdk v30", 200 unbundled: true, 201 properties: `sdk_version: "30",`, 202 bootclasspath: []string{`""`}, 203 system: "sdk_public_30_system_modules", 204 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 205 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 206 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 207 }, 208 { 209 210 name: "unbundled current", 211 unbundled: true, 212 properties: `sdk_version: "current",`, 213 bootclasspath: []string{`""`}, 214 system: "sdk_public_current_system_modules", 215 java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 216 java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 217 aidl: "-pprebuilts/sdk/current/public/framework.aidl", 218 }, 219 220 { 221 name: "pdk default", 222 pdk: true, 223 bootclasspath: []string{`""`}, 224 system: "sdk_public_30_system_modules", 225 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 226 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 227 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 228 }, 229 { 230 name: "pdk current", 231 pdk: true, 232 properties: `sdk_version: "current",`, 233 bootclasspath: []string{`""`}, 234 system: "sdk_public_30_system_modules", 235 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 236 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 237 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 238 }, 239 { 240 name: "pdk 29", 241 pdk: true, 242 properties: `sdk_version: "29",`, 243 bootclasspath: []string{`""`}, 244 system: "sdk_public_30_system_modules", 245 java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 246 java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, 247 aidl: "-pprebuilts/sdk/30/public/framework.aidl", 248 }, 249 { 250 name: "module_current", 251 properties: `sdk_version: "module_current",`, 252 bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"}, 253 system: "core-current-stubs-system-modules", 254 java9classpath: []string{"android_module_lib_stubs_current"}, 255 aidl: "-p" + buildDir + "/framework_non_updatable.aidl", 256 }, 257 { 258 name: "system_server_current", 259 properties: `sdk_version: "system_server_current",`, 260 bootclasspath: []string{"android_system_server_stubs_current", "core-lambda-stubs"}, 261 system: "core-current-stubs-system-modules", 262 java9classpath: []string{"android_system_server_stubs_current"}, 263 aidl: "-p" + buildDir + "/framework.aidl", 264 }, 265 } 266 267 for _, testcase := range classpathTestcases { 268 t.Run(testcase.name, func(t *testing.T) { 269 moduleType := "java_library" 270 if testcase.moduleType != "" { 271 moduleType = testcase.moduleType 272 } 273 274 props := ` 275 name: "foo", 276 srcs: ["a.java"], 277 target: { 278 android: { 279 srcs: ["bar-doc/IFoo.aidl"], 280 }, 281 }, 282 ` 283 bp := moduleType + " {" + props + testcase.properties + ` 284 }` 285 bpJava8 := moduleType + " {" + props + `java_version: "1.8", 286 ` + testcase.properties + ` 287 }` 288 289 variant := "android_common" 290 if testcase.host == android.Host { 291 variant = android.BuildOs.String() + "_common" 292 } 293 294 convertModulesToPaths := func(cp []string) []string { 295 ret := make([]string, len(cp)) 296 for i, e := range cp { 297 ret[i] = moduleToPath(e) 298 } 299 return ret 300 } 301 302 bootclasspath := convertModulesToPaths(testcase.bootclasspath) 303 java8classpath := convertModulesToPaths(testcase.java8classpath) 304 java9classpath := convertModulesToPaths(testcase.java9classpath) 305 306 bc := "" 307 var bcDeps []string 308 if len(bootclasspath) > 0 { 309 bc = "-bootclasspath " + strings.Join(bootclasspath, ":") 310 if bootclasspath[0] != `""` { 311 bcDeps = bootclasspath 312 } 313 } 314 315 j8c := "" 316 if len(java8classpath) > 0 { 317 j8c = "-classpath " + strings.Join(java8classpath, ":") 318 } 319 320 j9c := "" 321 if len(java9classpath) > 0 { 322 j9c = "-classpath " + strings.Join(java9classpath, ":") 323 } 324 325 system := "" 326 var systemDeps []string 327 if testcase.system == "none" { 328 system = "--system=none" 329 } else if testcase.system != "" { 330 dir := "" 331 if strings.HasPrefix(testcase.system, "sdk_public_") { 332 dir = "prebuilts/sdk" 333 } 334 system = "--system=" + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system") 335 // The module-relative parts of these paths are hardcoded in system_modules.go: 336 systemDeps = []string{ 337 filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "modules"), 338 filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "jrt-fs.jar"), 339 filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "release"), 340 } 341 } 342 343 checkClasspath := func(t *testing.T, ctx *android.TestContext, isJava8 bool) { 344 foo := ctx.ModuleForTests("foo", variant) 345 javac := foo.Rule("javac") 346 var deps []string 347 348 aidl := foo.MaybeRule("aidl") 349 if aidl.Rule != nil { 350 deps = append(deps, aidl.Output.String()) 351 } 352 353 got := javac.Args["bootClasspath"] 354 expected := "" 355 if isJava8 || testcase.forces8 { 356 expected = bc 357 deps = append(deps, bcDeps...) 358 } else { 359 expected = system 360 deps = append(deps, systemDeps...) 361 } 362 if got != expected { 363 t.Errorf("bootclasspath expected %q != got %q", expected, got) 364 } 365 366 if isJava8 || testcase.forces8 { 367 expected = j8c 368 deps = append(deps, java8classpath...) 369 } else { 370 expected = j9c 371 deps = append(deps, java9classpath...) 372 } 373 got = javac.Args["classpath"] 374 if got != expected { 375 t.Errorf("classpath expected %q != got %q", expected, got) 376 } 377 378 if !reflect.DeepEqual(javac.Implicits.Strings(), deps) { 379 t.Errorf("implicits expected %q != got %q", deps, javac.Implicits.Strings()) 380 } 381 } 382 383 // Test with legacy javac -source 1.8 -target 1.8 384 t.Run("Java language level 8", func(t *testing.T) { 385 config := testConfig(nil, bpJava8, nil) 386 if testcase.unbundled { 387 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) 388 } 389 if testcase.pdk { 390 config.TestProductVariables.Pdk = proptools.BoolPtr(true) 391 } 392 ctx := testContext() 393 run(t, ctx, config) 394 395 checkClasspath(t, ctx, true /* isJava8 */) 396 397 if testcase.host != android.Host { 398 aidl := ctx.ModuleForTests("foo", variant).Rule("aidl") 399 400 if g, w := aidl.RuleParams.Command, testcase.aidl+" -I."; !strings.Contains(g, w) { 401 t.Errorf("want aidl command to contain %q, got %q", w, g) 402 } 403 } 404 }) 405 406 // Test with default javac -source 9 -target 9 407 t.Run("Java language level 9", func(t *testing.T) { 408 config := testConfig(nil, bp, nil) 409 if testcase.unbundled { 410 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) 411 } 412 if testcase.pdk { 413 config.TestProductVariables.Pdk = proptools.BoolPtr(true) 414 } 415 ctx := testContext() 416 run(t, ctx, config) 417 418 checkClasspath(t, ctx, false /* isJava8 */) 419 420 if testcase.host != android.Host { 421 aidl := ctx.ModuleForTests("foo", variant).Rule("aidl") 422 423 if g, w := aidl.RuleParams.Command, testcase.aidl+" -I."; !strings.Contains(g, w) { 424 t.Errorf("want aidl command to contain %q, got %q", w, g) 425 } 426 } 427 }) 428 429 // Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8 430 t.Run("REL + Java language level 8", func(t *testing.T) { 431 config := testConfig(nil, bpJava8, nil) 432 config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("REL") 433 config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(true) 434 435 if testcase.unbundled { 436 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) 437 } 438 if testcase.pdk { 439 config.TestProductVariables.Pdk = proptools.BoolPtr(true) 440 } 441 ctx := testContext() 442 run(t, ctx, config) 443 444 checkClasspath(t, ctx, true /* isJava8 */) 445 }) 446 447 // Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9 448 t.Run("REL + Java language level 9", func(t *testing.T) { 449 config := testConfig(nil, bp, nil) 450 config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("REL") 451 config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(true) 452 453 if testcase.unbundled { 454 config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) 455 } 456 if testcase.pdk { 457 config.TestProductVariables.Pdk = proptools.BoolPtr(true) 458 } 459 ctx := testContext() 460 run(t, ctx, config) 461 462 checkClasspath(t, ctx, false /* isJava8 */) 463 }) 464 }) 465 } 466} 467