• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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