diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/base.go | 2 | ||||
| -rwxr-xr-x | java/invalid_implementation_jar.sh | 61 | ||||
| -rw-r--r-- | java/java.go | 80 |
3 files changed, 116 insertions, 27 deletions
diff --git a/java/base.go b/java/base.go index 602e8d882..5d2498169 100644 --- a/java/base.go +++ b/java/base.go @@ -868,7 +868,7 @@ func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.Opt flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs)) sdkVersion := (j.SdkVersion(ctx)).Kind - defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform)) + defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule)) if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) { flags = append(flags, "-t") } diff --git a/java/invalid_implementation_jar.sh b/java/invalid_implementation_jar.sh new file mode 100755 index 000000000..3820058d0 --- /dev/null +++ b/java/invalid_implementation_jar.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright 2022 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script to detect and report an attempt to access an invalid implementation +# jar. + +MOD=$1 + +cat <<EOF + + $MOD is a java_library that generates a jar file which must not be accessed + from outside the mainline module that provides it. If you are seeing this + message it means that you are incorrectly attempting to use the jar file + from a java_import prebuilt of $MOD. + + This is most likely due to an incorrect dependency on $MOD in an Android.mk + or Android.bp file. Please remove that dependency and replace with + something more appropriate, e.g. a dependency on an API provided by the + module. + + If you do not know where the extraneous dependency was added then you can + run the following command to find a list of all the paths from the target + which you are trying to build to the target which produced this error. + + prebuilts/build-tools/linux-x86/bin/ninja -f out/combined-\${TARGET_PRODUCT}.ninja -t path <target> <invalid-jar> + + Where <target> is the build target you specified on the command line which + produces this error and <invalid-jar> is the rule that failed with this + message. If you are specifying multiple build targets then you will need to + run the above command for every target until you find the cause. + + The command will output one (of the possibly many) dependency paths from + <target> to <invalid-jar>, one file/phony target per line. e.g. it may + output something like this: + + .... + out/soong/.intermediates/acme/broken/android_common/combined/broken.jar + out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/prebuilt_core-libart/android_common/combined/core-libart.jar + out/soong/.intermediates/prebuilts/module_sdk/art/current/sdk/art-module-sdk_core-libart-error/gen/this-file-will-never-be-created.jar + + The last line is the failing target, the second to last line is a dependency + from the core-libart java_import onto the failing target, the third to last + line is the source of the dependency so you should look in acme/Android.bp + file for the "broken" module. + +EOF + +exit 1 diff --git a/java/java.go b/java/java.go index b6fc6b831..3471abb79 100644 --- a/java/java.go +++ b/java/java.go @@ -86,11 +86,11 @@ func RegisterJavaSdkMemberTypes() { var ( // Supports adding java header libraries to module_exports and sdk. javaHeaderLibsSdkMemberType = &librarySdkMemberType{ - android.SdkMemberTypeBase{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "java_header_libs", SupportsSdk: true, }, - func(_ android.SdkMemberContext, j *Library) android.Path { + jarToExportGetter: func(_ android.SdkMemberContext, j *Library) android.Path { headerJars := j.HeaderJars() if len(headerJars) != 1 { panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) @@ -98,8 +98,8 @@ var ( return headerJars[0] }, - sdkSnapshotFilePathForJar, - copyEverythingToSnapshot, + snapshotPathGetter: sdkSnapshotFilePathForJar, + onlyCopyJarToSnapshot: copyEverythingToSnapshot, } // Export implementation classes jar as part of the sdk. @@ -113,12 +113,12 @@ var ( // Supports adding java implementation libraries to module_exports but not sdk. javaLibsSdkMemberType = &librarySdkMemberType{ - android.SdkMemberTypeBase{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "java_libs", }, - exportImplementationClassesJar, - sdkSnapshotFilePathForJar, - copyEverythingToSnapshot, + jarToExportGetter: exportImplementationClassesJar, + snapshotPathGetter: sdkSnapshotFilePathForJar, + onlyCopyJarToSnapshot: copyEverythingToSnapshot, } snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { @@ -143,11 +143,11 @@ var ( // necessary. The java_boot_libs property to allow those modules to be exported as part of the // sdk/module_exports without exposing any unnecessary information. javaBootLibsSdkMemberType = &librarySdkMemberType{ - android.SdkMemberTypeBase{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "java_boot_libs", SupportsSdk: true, }, - func(ctx android.SdkMemberContext, j *Library) android.Path { + jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path { if snapshotRequiresImplementationJar(ctx) { return exportImplementationClassesJar(ctx, j) } @@ -156,9 +156,9 @@ var ( // jar for use by dexpreopting and boot jars package check. They do not need to provide an // actual implementation jar but the java_import will need a file that exists so just copy an // empty file. Any attempt to use that file as a jar will cause a build error. - return ctx.SnapshotBuilder().EmptyFile() + return nil }, - func(ctx android.SdkMemberContext, osPrefix, name string) string { + snapshotPathGetter: func(ctx android.SdkMemberContext, osPrefix, name string) string { if snapshotRequiresImplementationJar(ctx) { return sdkSnapshotFilePathForJar(ctx, osPrefix, name) } @@ -168,7 +168,7 @@ var ( // TODO(b/175714559): Provide a proper error message in Soong not ninja. return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) }, - onlyCopyJarToSnapshot, + onlyCopyJarToSnapshot: onlyCopyJarToSnapshot, } // Supports adding java systemserver libraries to module_exports and sdk. @@ -182,27 +182,27 @@ var ( // necessary. The java_systemserver_libs property to allow those modules to be exported as part of // the sdk/module_exports without exposing any unnecessary information. javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ - android.SdkMemberTypeBase{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "java_systemserver_libs", SupportsSdk: true, // This was only added in Tiramisu. SupportedBuildReleaseSpecification: "Tiramisu+", }, - func(ctx android.SdkMemberContext, j *Library) android.Path { + jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path { // Java systemserver libs are only provided in the SDK to provide access to their dex // implementation jar for use by dexpreopting. They do not need to provide an actual // implementation jar but the java_import will need a file that exists so just copy an empty // file. Any attempt to use that file as a jar will cause a build error. - return ctx.SnapshotBuilder().EmptyFile() + return nil }, - func(_ android.SdkMemberContext, osPrefix, name string) string { + snapshotPathGetter: func(_ android.SdkMemberContext, osPrefix, name string) string { // Create a special name for the implementation jar to try and provide some useful information // to a developer that attempts to compile against this. // TODO(b/175714559): Provide a proper error message in Soong not ninja. return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) }, - onlyCopyJarToSnapshot, + onlyCopyJarToSnapshot: onlyCopyJarToSnapshot, } // Supports adding java test libraries to module_exports but not sdk. @@ -232,7 +232,7 @@ type JavaInfo struct { ImplementationAndResourcesJars android.Paths // ImplementationJars is a list of jars that contain the implementations of classes in the - //module. + // module. ImplementationJars android.Paths // ResourceJars is a list of jars that contain the resources included in the module. @@ -718,7 +718,8 @@ type librarySdkMemberType struct { android.SdkMemberTypeBase // Function to retrieve the appropriate output jar (implementation or header) from - // the library. + // the library, if this returns nil then it is assumed that the snapshot must not provide access + // to the jar. jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path // Function to compute the snapshot relative path to which the named library's @@ -755,7 +756,11 @@ func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMembe type librarySdkMemberProperties struct { android.SdkMemberPropertiesBase - JarToExport android.Path `android:"arch_variant"` + JarToExport android.Path `android:"arch_variant"` + + // The path to a script to use when the jar is invalid. + InvalidJarScript android.Path + AidlIncludeDirs android.Paths // The list of permitted packages that need to be passed to the prebuilts as they are used to @@ -766,7 +771,15 @@ type librarySdkMemberProperties struct { func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { j := variant.(*Library) - p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) + memberType := ctx.MemberType().(*librarySdkMemberType) + p.JarToExport = memberType.jarToExportGetter(ctx, j) + + // If no jar was provided for export then disallow access to it completely. + if p.JarToExport == nil { + // Copy the script to prevent access to the jar into the snapshot. + p.InvalidJarScript = android.PathForSource(ctx.SdkModuleContext(), + "build/soong/java/invalid_implementation_jar.sh") + } p.AidlIncludeDirs = j.AidlIncludeDirs() @@ -789,6 +802,21 @@ func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberConte propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) } + if scriptSrc := p.InvalidJarScript; scriptSrc != nil { + // Copy the script to prevent access to the jar into the snapshot. + scriptDest := filepath.Join("scripts", scriptSrc.Base()) + builder.CopyToSnapshot(scriptSrc, scriptDest) + + // Generate a genrule module that will invoke the script passing in the module name. + genrule := builder.AddInternalModule(p, "genrule", "error") + genRuleName := genrule.Name() + genrule.AddProperty("out", []string{"this-file-will-never-be-created.jar"}) + genrule.AddProperty("tool_files", []string{scriptDest}) + genrule.AddProperty("cmd", fmt.Sprintf("$(location %s) %s", scriptDest, p.Name())) + + propertySet.AddPropertyWithTag("jars", []string{":" + genRuleName}, builder.SdkMemberReferencePropertyTag(true)) + } + if len(p.PermittedPackages) > 0 { propertySet.AddProperty("permitted_packages", p.PermittedPackages) } @@ -1650,7 +1678,7 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { } func (j *Import) commonBuildActions(ctx android.ModuleContext) { - //TODO(b/231322772) these should come from Bazel once available + // TODO(b/231322772) these should come from Bazel once available j.sdkVersion = j.SdkVersion(ctx) j.minSdkVersion = j.MinSdkVersion(ctx) @@ -2253,7 +2281,7 @@ func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorConte resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources)) } - //TODO(b/179889880) handle case where glob includes files outside package + // TODO(b/179889880) handle case where glob includes files outside package resDeps := ResourceDirsToFiles( ctx, m.properties.Java_resource_dirs, @@ -2401,7 +2429,7 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) } epEnabled := m.properties.Errorprone.Enabled - //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable + // TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable if Bool(epEnabled) { javacopts = append(javacopts, m.properties.Errorprone.Javacflags...) } @@ -2637,7 +2665,7 @@ func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), - //TODO(b/240308299) include AIDL information from Bazel + // TODO(b/240308299) include AIDL information from Bazel }) i.maybeInstall(ctx, jarName, outputFile) |