Merge "Update java_api_library prop name"
diff --git a/android/bazel.go b/android/bazel.go
index d30cb80..60989f6 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -341,16 +341,19 @@
 		// Exact dir match
 		return true
 	}
+	var i int
 	// Check if subtree match
-	for prefix, recursive := range a.keepExistingBuildFile {
-		if recursive {
-			if strings.HasPrefix(dir, prefix+"/") {
-				return true
-			}
+	for {
+		j := strings.Index(dir[i:], "/")
+		if j == -1 {
+			return false //default
+		}
+		prefix := dir[0 : i+j]
+		i = i + j + 1 // skip the "/"
+		if recursive, ok := a.keepExistingBuildFile[prefix]; ok && recursive {
+			return true
 		}
 	}
-	// Default
-	return false
 }
 
 var bp2BuildAllowListKey = NewOnceKey("Bp2BuildAllowlist")
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index b3b698e..e2751d6 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -150,8 +150,9 @@
 	// ** end Cquery Results Retrieval Functions
 
 	// Issues commands to Bazel to receive results for all cquery requests
-	// queued in the BazelContext.
-	InvokeBazel(config Config) error
+	// queued in the BazelContext. The ctx argument is optional and is only
+	// used for performance data collection
+	InvokeBazel(config Config, ctx *Context) error
 
 	// Returns true if Bazel handling is enabled for the module with the given name.
 	// Note that this only implies "bazel mixed build" allowlisting. The caller
@@ -259,7 +260,7 @@
 	return result, nil
 }
 
-func (m MockBazelContext) InvokeBazel(_ Config) error {
+func (m MockBazelContext) InvokeBazel(_ Config, ctx *Context) error {
 	panic("unimplemented")
 }
 
@@ -355,7 +356,7 @@
 	panic("implement me")
 }
 
-func (n noopBazelContext) InvokeBazel(_ Config) error {
+func (n noopBazelContext) InvokeBazel(_ Config, ctx *Context) error {
 	panic("unimplemented")
 }
 
@@ -865,11 +866,48 @@
 	return filepath.Dir(p.soongOutDir)
 }
 
+const buildrootLabel = "@soong_injection//mixed_builds:buildroot"
+
+var (
+	cqueryCmd = bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}
+	aqueryCmd = bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}
+	buildCmd  = bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}
+)
+
 // Issues commands to Bazel to receive results for all cquery requests
 // queued in the BazelContext.
-func (context *bazelContext) InvokeBazel(config Config) error {
-	context.results = make(map[cqueryKey]string)
+func (context *bazelContext) InvokeBazel(config Config, ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("bazel")
+		defer ctx.EventHandler.End("bazel")
+	}
 
+	if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
+		if err := os.MkdirAll(metricsDir, 0777); err != nil {
+			return err
+		}
+	}
+	context.results = make(map[cqueryKey]string)
+	if err := context.runCquery(ctx); err != nil {
+		return err
+	}
+	if err := context.runAquery(config, ctx); err != nil {
+		return err
+	}
+	if err := context.generateBazelSymlinks(ctx); err != nil {
+		return err
+	}
+
+	// Clear requests.
+	context.requests = map[cqueryKey]bool{}
+	return nil
+}
+
+func (context *bazelContext) runCquery(ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("cquery")
+		defer ctx.EventHandler.End("cquery")
+	}
 	soongInjectionPath := absolutePath(context.paths.injectedFilesDir())
 	mixedBuildsPath := filepath.Join(soongInjectionPath, "mixed_builds")
 	if _, err := os.Stat(mixedBuildsPath); os.IsNotExist(err) {
@@ -878,13 +916,6 @@
 			return err
 		}
 	}
-
-	if metricsDir := context.paths.BazelMetricsDir(); metricsDir != "" {
-		err := os.MkdirAll(metricsDir, 0777)
-		if err != nil {
-			return err
-		}
-	}
 	if err := ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666); err != nil {
 		return err
 	}
@@ -899,8 +930,6 @@
 		return err
 	}
 
-	const buildrootLabel = "@soong_injection//mixed_builds:buildroot"
-	cqueryCmd := bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}
 	cqueryCommandWithFlag := context.createBazelCommand(context.paths, bazel.CqueryBuildRootRunName, cqueryCmd,
 		"--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath))
 	cqueryOutput, cqueryErrorMessage, cqueryErr := context.issueBazelCommand(cqueryCommandWithFlag)
@@ -926,7 +955,14 @@
 				getCqueryId(val), cqueryOutput, cqueryErrorMessage)
 		}
 	}
+	return nil
+}
 
+func (context *bazelContext) runAquery(config Config, ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("aquery")
+		defer ctx.EventHandler.End("aquery")
+	}
 	// Issue an aquery command to retrieve action information about the bazel build tree.
 	//
 	// Use jsonproto instead of proto; actual proto parsing would require a dependency on Bazel's
@@ -951,25 +987,25 @@
 			extraFlags = append(extraFlags, "--instrumentation_filter="+strings.Join(paths, ","))
 		}
 	}
-	aqueryCmd := bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}
-	if aqueryOutput, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.AqueryBuildRootRunName, aqueryCmd,
-		extraFlags...)); err == nil {
-		context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
-	} else {
+	aqueryOutput, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.AqueryBuildRootRunName, aqueryCmd,
+		extraFlags...))
+	if err != nil {
 		return err
 	}
+	context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput))
+	return err
+}
 
+func (context *bazelContext) generateBazelSymlinks(ctx *Context) error {
+	if ctx != nil {
+		ctx.EventHandler.Begin("symlinks")
+		defer ctx.EventHandler.End("symlinks")
+	}
 	// Issue a build command of the phony root to generate symlink forests for dependencies of the
 	// Bazel build. This is necessary because aquery invocations do not generate this symlink forest,
 	// but some of symlinks may be required to resolve source dependencies of the build.
-	buildCmd := bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}
-	if _, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.BazelBuildPhonyRootRunName, buildCmd)); err != nil {
-		return err
-	}
-
-	// Clear requests.
-	context.requests = map[cqueryKey]bool{}
-	return nil
+	_, _, err := context.issueBazelCommand(context.createBazelCommand(context.paths, bazel.BazelBuildPhonyRootRunName, buildCmd))
+	return err
 }
 
 func (context *bazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index 4b8f0f6..bc16cb5 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -23,7 +23,7 @@
 		bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `@//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
 	})
 	bazelContext.QueueBazelRequest(label, cquery.GetOutputFiles, cfg)
-	err := bazelContext.InvokeBazel(testConfig)
+	err := bazelContext.InvokeBazel(testConfig, nil)
 	if err != nil {
 		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
 	}
@@ -37,7 +37,7 @@
 
 func TestInvokeBazelWritesBazelFiles(t *testing.T) {
 	bazelContext, baseDir := testBazelContext(t, map[bazelCommand]string{})
-	err := bazelContext.InvokeBazel(testConfig)
+	err := bazelContext.InvokeBazel(testConfig, nil)
 	if err != nil {
 		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
 	}
@@ -118,7 +118,7 @@
 		bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
 			bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}: string(data)})
 
-		err = bazelContext.InvokeBazel(testConfig)
+		err = bazelContext.InvokeBazel(testConfig, nil)
 		if err != nil {
 			t.Fatalf("testCase #%d: did not expect error invoking Bazel, but got %s", i+1, err)
 		}
@@ -170,7 +170,7 @@
 func verifyExtraFlags(t *testing.T, config Config, expected string) string {
 	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
 
-	err := bazelContext.InvokeBazel(config)
+	err := bazelContext.InvokeBazel(config, nil)
 	if err != nil {
 		t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
 	}
@@ -197,7 +197,7 @@
 	}
 	aqueryCommand := bazelCommand{command: "aquery", expression: "deps(@soong_injection//mixed_builds:buildroot)"}
 	if _, exists := bazelCommandResults[aqueryCommand]; !exists {
-		bazelCommandResults[aqueryCommand] = "{}\n"
+		bazelCommandResults[aqueryCommand] = ""
 	}
 	runner := &mockBazelRunner{bazelCommandResults: bazelCommandResults}
 	return &bazelContext{
diff --git a/android/sdk.go b/android/sdk.go
index fc0a84e..bd2f5d1 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -232,6 +232,12 @@
 	// relative path) and add the dest to the zip.
 	CopyToSnapshot(src Path, dest string)
 
+	// EmptyFile returns the path to an empty file.
+	//
+	// This can be used by sdk member types that need to create an empty file in the snapshot, simply
+	// pass the value returned from this to the CopyToSnapshot() method.
+	EmptyFile() Path
+
 	// UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
 	// directory destDir.
 	UnzipToSnapshot(zipPath Path, destDir string)
@@ -258,14 +264,6 @@
 	// See sdk/update.go for more information.
 	AddPrebuiltModule(member SdkMember, moduleType string) BpModule
 
-	// AddInternalModule creates a new module in the generated Android.bp file that can only be
-	// referenced by one of the other modules in the snapshot.
-	//
-	// The created module's name is constructed by concatenating the name of this member and the
-	// nameSuffix, separated by "-". It also has the visibility property set to "//visibility:private"
-	// to prevent it from being inadvertently accessed from outside the snapshot.
-	AddInternalModule(properties SdkMemberProperties, moduleType string, nameSuffix string) BpModule
-
 	// SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
 	// BpModule that contains references to other sdk members.
 	//
@@ -924,12 +922,6 @@
 //
 // Contains common properties that apply across many different member types.
 type SdkMemberPropertiesBase struct {
-	// The name of the member.
-	//
-	// Ignore this property during optimization. This is needed because this property is the same for
-	// all variants of a member and so would be optimized away if it was not ignored.
-	MemberName string `sdk:"ignore"`
-
 	// The number of unique os types supported by the member variants.
 	//
 	// If a member has a variant with more than one os type then it will need to differentiate
@@ -953,10 +945,6 @@
 	Compile_multilib string `android:"arch_variant"`
 }
 
-func (b *SdkMemberPropertiesBase) Name() string {
-	return b.MemberName
-}
-
 // OsPrefix returns the os prefix to use for any file paths in the sdk.
 //
 // Is an empty string if the member only provides variants for a single os type, otherwise
@@ -982,8 +970,6 @@
 	// Base returns the base structure.
 	Base() *SdkMemberPropertiesBase
 
-	Name() string
-
 	// PopulateFromVariant populates this structure with information from a module variant.
 	//
 	// It will typically be called once for each variant of a member module that the SDK depends upon.
diff --git a/cc/config/global.go b/cc/config/global.go
index 9f18784..e5c0a8e 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -292,6 +292,8 @@
 	llvmNextExtraCommonGlobalCflags = []string{
 		// New warnings to be fixed after clang-r475365
 		"-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
+		// Skip deprecated flags.
+		"-Wno-unused-command-line-argument",
 	}
 
 	IllegalFlags = []string{
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 51d2345..bc2d5cb 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -157,9 +157,7 @@
 	defer ctx.EventHandler.End("mixed_build")
 
 	bazelHook := func() error {
-		ctx.EventHandler.Begin("bazel")
-		defer ctx.EventHandler.End("bazel")
-		return configuration.BazelContext.InvokeBazel(configuration)
+		return configuration.BazelContext.InvokeBazel(configuration, ctx)
 	}
 	ctx.SetBeforePrepareBuildActionsHook(bazelHook)
 	ninjaDeps := bootstrap.RunBlueprint(cmdlineArgs, bootstrap.DoEverything, ctx.Context, configuration)
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index af3bdbe..1ee0edc 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -23,10 +23,6 @@
 	"android/soong/android"
 )
 
-func init() {
-	android.RegisterModuleType("avb_add_hash_footer", avbAddHashFooterFactory)
-}
-
 type avbAddHashFooter struct {
 	android.ModuleBase
 
@@ -36,6 +32,17 @@
 	installDir android.InstallPath
 }
 
+type avbProp struct {
+	// Name of a property
+	Name *string
+
+	// Value of a property. Can't be used together with `file`.
+	Value *string
+
+	// File from which the value of the prop is read from. Can't be used together with `value`.
+	File *string `android:"path,arch_variant"`
+}
+
 type avbAddHashFooterProperties struct {
 	// Source file of this image. Can reference a genrule type module with the ":module" syntax.
 	Src *string `android:"path,arch_variant"`
@@ -57,6 +64,9 @@
 
 	// The salt in hex. Required for reproducible builds.
 	Salt *string
+
+	// List of properties to add to the footer
+	Props []avbProp
 }
 
 // The AVB footer adds verification information to the image.
@@ -106,6 +116,10 @@
 	}
 	cmd.FlagWithArg("--salt ", proptools.String(a.properties.Salt))
 
+	for _, prop := range a.properties.Props {
+		addAvbProp(ctx, cmd, prop)
+	}
+
 	cmd.FlagWithOutput("--image ", a.output)
 
 	builder.Build("avbAddHashFooter", fmt.Sprintf("avbAddHashFooter %s", ctx.ModuleName()))
@@ -114,6 +128,32 @@
 	ctx.InstallFile(a.installDir, a.installFileName(), a.output)
 }
 
+func addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) {
+	name := proptools.String(prop.Name)
+	value := proptools.String(prop.Value)
+	file := proptools.String(prop.File)
+	if name == "" {
+		ctx.PropertyErrorf("name", "can't be empty")
+		return
+	}
+	if value == "" && file == "" {
+		ctx.PropertyErrorf("value", "either value or file should be set")
+		return
+	}
+	if value != "" && file != "" {
+		ctx.PropertyErrorf("value", "value and file can't be set at the same time")
+		return
+	}
+
+	if value != "" {
+		cmd.FlagWithArg("--prop ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, value)))
+	} else {
+		p := android.PathForModuleSrc(ctx, file)
+		cmd.Input(p)
+		cmd.FlagWithArg("--prop_from_file ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, cmd.PathForInput(p))))
+	}
+}
+
 var _ android.AndroidMkEntriesProvider = (*avbAddHashFooter)(nil)
 
 // Implements android.AndroidMkEntriesProvider
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 6e1e78a..1365d4a 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -34,6 +34,7 @@
 func registerBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("android_filesystem", filesystemFactory)
 	ctx.RegisterModuleType("android_system_image", systemImageFactory)
+	ctx.RegisterModuleType("avb_add_hash_footer", avbAddHashFooterFactory)
 }
 
 type filesystem struct {
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index cda06d9..9bfcc3d 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -125,3 +125,37 @@
 	module := result.ModuleForTests("myfilesystem", "android_common").Module().(*systemImage)
 	android.AssertDeepEquals(t, "entries should have foo only", []string{"components/foo"}, module.entries)
 }
+
+func TestAvbAddHashFooter(t *testing.T) {
+	result := fixture.RunTestWithBp(t, `
+		avb_add_hash_footer {
+			name: "myfooter",
+			src: "input.img",
+			filename: "output.img",
+			partition_name: "mypartition",
+			private_key: "mykey",
+			salt: "1111",
+			props: [
+				{
+					name: "prop1",
+					value: "value1",
+				},
+				{
+					name: "prop2",
+					file: "value_file",
+				},
+			],
+		}
+	`)
+	cmd := result.ModuleForTests("myfooter", "android_arm64_armv8-a").Rule("avbAddHashFooter").RuleParams.Command
+	android.AssertStringDoesContain(t, "Can't find correct --partition_name argument",
+		cmd, "--partition_name mypartition")
+	android.AssertStringDoesContain(t, "Can't find correct --key argument",
+		cmd, "--key mykey")
+	android.AssertStringDoesContain(t, "Can't find --salt argument",
+		cmd, "--salt 1111")
+	android.AssertStringDoesContain(t, "Can't find --prop argument",
+		cmd, "--prop 'prop1:value1'")
+	android.AssertStringDoesContain(t, "Can't find --prop_from_file argument",
+		cmd, "--prop_from_file 'prop2:value_file'")
+}
diff --git a/java/app.go b/java/app.go
index e36808f..a822cbf 100755
--- a/java/app.go
+++ b/java/app.go
@@ -591,7 +591,7 @@
 		// Set a certificate to avoid panics later when accessing it.
 		mainCertificate = Certificate{
 			Key: android.PathForModuleOut(ctx, "missing.pk8"),
-			Pem: android.PathForModuleOut(ctx, "missing.pem"),
+			Pem: android.PathForModuleOut(ctx, "missing.x509.pem"),
 		}
 	}
 
diff --git a/java/invalid_implementation_jar.sh b/java/invalid_implementation_jar.sh
deleted file mode 100755
index 3820058..0000000
--- a/java/invalid_implementation_jar.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/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 ac52e22..25b6349 100644
--- a/java/java.go
+++ b/java/java.go
@@ -89,11 +89,11 @@
 var (
 	// Supports adding java header libraries to module_exports and sdk.
 	javaHeaderLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_header_libs",
 			SupportsSdk:  true,
 		},
-		jarToExportGetter: func(_ android.SdkMemberContext, j *Library) android.Path {
+		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()))
@@ -101,8 +101,8 @@
 
 			return headerJars[0]
 		},
-		snapshotPathGetter:    sdkSnapshotFilePathForJar,
-		onlyCopyJarToSnapshot: copyEverythingToSnapshot,
+		sdkSnapshotFilePathForJar,
+		copyEverythingToSnapshot,
 	}
 
 	// Export implementation classes jar as part of the sdk.
@@ -116,12 +116,12 @@
 
 	// Supports adding java implementation libraries to module_exports but not sdk.
 	javaLibsSdkMemberType = &librarySdkMemberType{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_libs",
 		},
-		jarToExportGetter:     exportImplementationClassesJar,
-		snapshotPathGetter:    sdkSnapshotFilePathForJar,
-		onlyCopyJarToSnapshot: copyEverythingToSnapshot,
+		exportImplementationClassesJar,
+		sdkSnapshotFilePathForJar,
+		copyEverythingToSnapshot,
 	}
 
 	snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
@@ -146,11 +146,11 @@
 	// 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{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_boot_libs",
 			SupportsSdk:  true,
 		},
-		jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
+		func(ctx android.SdkMemberContext, j *Library) android.Path {
 			if snapshotRequiresImplementationJar(ctx) {
 				return exportImplementationClassesJar(ctx, j)
 			}
@@ -159,9 +159,9 @@
 			// 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 nil
+			return ctx.SnapshotBuilder().EmptyFile()
 		},
-		snapshotPathGetter: func(ctx android.SdkMemberContext, osPrefix, name string) string {
+		func(ctx android.SdkMemberContext, osPrefix, name string) string {
 			if snapshotRequiresImplementationJar(ctx) {
 				return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
 			}
@@ -171,7 +171,7 @@
 			// 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.
@@ -185,27 +185,27 @@
 	// 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{
-		SdkMemberTypeBase: android.SdkMemberTypeBase{
+		android.SdkMemberTypeBase{
 			PropertyName: "java_systemserver_libs",
 			SupportsSdk:  true,
 
 			// This was only added in Tiramisu.
 			SupportedBuildReleaseSpecification: "Tiramisu+",
 		},
-		jarToExportGetter: func(ctx android.SdkMemberContext, j *Library) android.Path {
+		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 nil
+			return ctx.SnapshotBuilder().EmptyFile()
 		},
-		snapshotPathGetter: func(_ android.SdkMemberContext, osPrefix, name string) string {
+		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.
@@ -235,7 +235,7 @@
 	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.
@@ -721,8 +721,7 @@
 	android.SdkMemberTypeBase
 
 	// Function to retrieve the appropriate output jar (implementation or header) from
-	// the library, if this returns nil then it is assumed that the snapshot must not provide access
-	// to the jar.
+	// the library.
 	jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path
 
 	// Function to compute the snapshot relative path to which the named library's
@@ -759,11 +758,7 @@
 type librarySdkMemberProperties struct {
 	android.SdkMemberPropertiesBase
 
-	JarToExport android.Path `android:"arch_variant"`
-
-	// The path to a script to use when the jar is invalid.
-	InvalidJarScript android.Path
-
+	JarToExport     android.Path `android:"arch_variant"`
 	AidlIncludeDirs android.Paths
 
 	// The list of permitted packages that need to be passed to the prebuilts as they are used to
@@ -774,15 +769,7 @@
 func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
 	j := variant.(*Library)
 
-	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.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j)
 
 	p.AidlIncludeDirs = j.AidlIncludeDirs()
 
@@ -805,21 +792,6 @@
 		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)
 	}
@@ -1852,7 +1824,7 @@
 }
 
 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)
 
@@ -2455,7 +2427,7 @@
 		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,
@@ -2617,7 +2589,7 @@
 	}
 
 	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...)
 	}
@@ -2871,7 +2843,7 @@
 		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)
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 1a1eaf2..1f374b4 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -20,43 +20,29 @@
 )
 
 var legacyCorePlatformApiModules = []string{
-	"AAECarSystemUI",
-	"AAECarSystemUI-tests",
 	"ArcSettings",
 	"BTTestApp",
 	"CapCtrlInterface",
 	"com.qti.location.sdk",
-	"com.qti.media.secureprocessor",
-	"DeviceInfo",
-	"DocumentsUIGoogleTests",
-	"DocumentsUIUnitTests",
 	"face-V1-0-javalib",
 	"FloralClocks",
 	"framework-jobscheduler",
 	"framework-minus-apex",
 	"framework-minus-apex-intdefs",
 	"FrameworksCoreTests",
-	"GtsIncrementalInstallTestCases",
-	"GtsIncrementalInstallTriggerApp",
-	"GtsInstallerV2TestCases",
 	"HelloOslo",
-	"imssettings",
 	"izat.lib.glue",
 	"mediatek-ims-base",
 	"ModemTestMode",
 	"MtkCapCtrl",
 	"my.tests.snapdragonsdktest",
 	"NetworkSetting",
-	"online-gcm-ref-docs",
-	"online-gts-docs",
 	"PerformanceMode",
 	"pxp-monitor",
 	"QColor",
 	"qcom.fmradio",
-	"QDCMMobileApp",
 	"Qmmi",
 	"QPerformance",
-	"remotesimlockmanagerlibrary",
 	"sam",
 	"saminterfacelibrary",
 	"sammanagerlibrary",
@@ -75,9 +61,6 @@
 	"SettingsOverlayG020P",
 	"SettingsOverlayG020Q",
 	"SettingsOverlayG025H",
-	"SettingsOverlayG025J",
-	"SettingsOverlayG025M",
-	"SettingsOverlayG025N",
 	"SettingsOverlayG5NZ6",
 	"SettingsRoboTests",
 	"SimContact",
@@ -86,8 +69,6 @@
 	"tcmiface",
 	"telephony-common",
 	"TeleService",
-	"TMobilePlanProvider",
-	"uimgbamanagerlibrary",
 	"UxPerformance",
 	"WfdCommon",
 }
diff --git a/java/lint.go b/java/lint.go
index 9827159..7a6e5d9 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -190,10 +190,8 @@
 
 	extraCheckModules := l.properties.Lint.Extra_check_modules
 
-	if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
-		if checkOnlyModules := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); checkOnlyModules != "" {
-			extraCheckModules = strings.Split(checkOnlyModules, ",")
-		}
+	if extraCheckModulesEnv := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); extraCheckModulesEnv != "" {
+		extraCheckModules = append(extraCheckModules, strings.Split(extraCheckModulesEnv, ",")...)
 	}
 
 	ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
diff --git a/rust/library.go b/rust/library.go
index c2ce9de..bc9c9aa 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -267,84 +267,94 @@
 var _ libraryInterface = (*libraryDecorator)(nil)
 var _ exportedFlagsProducer = (*libraryDecorator)(nil)
 
-// rust_library produces all rust variants.
+// rust_library produces all Rust variants (rust_library_dylib and
+// rust_library_rlib).
 func RustLibraryFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyRust()
 	return module.Init()
 }
 
-// rust_ffi produces all ffi variants.
+// rust_ffi produces all FFI variants (rust_ffi_shared and
+// rust_ffi_static).
 func RustFFIFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyFFI()
 	return module.Init()
 }
 
-// rust_library_dylib produces a dylib.
+// rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
 func RustLibraryDylibFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyDylib()
 	return module.Init()
 }
 
-// rust_library_rlib produces an rlib.
+// rust_library_rlib produces an rlib (Rust crate type "rlib").
 func RustLibraryRlibFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyRlib()
 	return module.Init()
 }
 
-// rust_ffi_shared produces a shared library.
+// rust_ffi_shared produces a shared library (Rust crate type
+// "cdylib").
 func RustFFISharedFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyShared()
 	return module.Init()
 }
 
-// rust_ffi_static produces a static library.
+// rust_ffi_static produces a static library (Rust crate type
+// "staticlib").
 func RustFFIStaticFactory() android.Module {
 	module, library := NewRustLibrary(android.HostAndDeviceSupported)
 	library.BuildOnlyStatic()
 	return module.Init()
 }
 
-// rust_library_host produces all rust variants.
+// rust_library_host produces all Rust variants for the host
+// (rust_library_dylib_host and rust_library_rlib_host).
 func RustLibraryHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyRust()
 	return module.Init()
 }
 
-// rust_ffi_host produces all FFI variants.
+// rust_ffi_host produces all FFI variants for the host
+// (rust_ffi_static_host and rust_ffi_shared_host).
 func RustFFIHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyFFI()
 	return module.Init()
 }
 
-// rust_library_dylib_host produces a dylib.
+// rust_library_dylib_host produces a dylib for the host (Rust crate
+// type "dylib").
 func RustLibraryDylibHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyDylib()
 	return module.Init()
 }
 
-// rust_library_rlib_host produces an rlib.
+// rust_library_rlib_host produces an rlib for the host (Rust crate
+// type "rlib").
 func RustLibraryRlibHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyRlib()
 	return module.Init()
 }
 
-// rust_ffi_static_host produces a static library.
+// rust_ffi_static_host produces a static library for the host (Rust
+// crate type "staticlib").
 func RustFFIStaticHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyStatic()
 	return module.Init()
 }
 
-// rust_ffi_shared_host produces an shared library.
+// rust_ffi_shared_host produces an shared library for the host (Rust
+// crate type "cdylib").
 func RustFFISharedHostFactory() android.Module {
 	module, library := NewRustLibrary(android.HostSupported)
 	library.BuildOnlyShared()
diff --git a/rust/library_test.go b/rust/library_test.go
index 4633cc7..e3e4d0f 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -30,11 +30,11 @@
 			srcs: ["foo.rs"],
 			crate_name: "foo",
 		}
-                rust_ffi_host {
-                        name: "libfoo.ffi",
-                        srcs: ["foo.rs"],
-                        crate_name: "foo"
-                }`)
+		rust_ffi_host {
+			name: "libfoo.ffi",
+			srcs: ["foo.rs"],
+			crate_name: "foo"
+		}`)
 
 	// Test all variants are being built.
 	libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
@@ -45,7 +45,7 @@
 	rlibCrateType := "rlib"
 	dylibCrateType := "dylib"
 	sharedCrateType := "cdylib"
-	staticCrateType := "static"
+	staticCrateType := "staticlib"
 
 	// Test crate type for rlib is correct.
 	if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 58c1647..1b64130 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -169,15 +169,7 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["com.android.art"],
-    jars: [":mysdk_core1-error"],
-}
-
-genrule {
-    name: "mysdk_core1-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) core1",
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/core1.jar"],
 }
 
 java_import {
@@ -185,15 +177,7 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["com.android.art"],
-    jars: [":mysdk_core2-error"],
-}
-
-genrule {
-    name: "mysdk_core2-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) core2",
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/core2.jar"],
 }
 `),
 		checkAllCopyRules(`
@@ -203,7 +187,8 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar
 		`),
 		snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
 
@@ -372,18 +357,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mybootlib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
     permitted_packages: ["mybootlib"],
 }
 
-genrule {
-    name: "mysdk_mybootlib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
-}
-
 java_sdk_library_import {
     name: "myothersdklibrary",
     prefer: false,
@@ -490,7 +467,7 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -510,7 +487,7 @@
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt
 .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt
@@ -899,18 +876,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mybootlib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
     permitted_packages: ["mybootlib"],
 }
 
-genrule {
-    name: "mysdk_mybootlib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mybootlib",
-}
-
 java_sdk_library_import {
     name: "mynewlibrary",
     prefer: false,
@@ -961,7 +930,7 @@
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
 .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar
 .intermediates/mynewlibrary.stubs/android_common/javac/mynewlibrary.stubs.jar -> sdk_library/public/mynewlibrary-stubs.jar
 .intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_api.txt -> sdk_library/public/mynewlibrary.txt
 .intermediates/mynewlibrary.stubs.source/android_common/metalava/mynewlibrary.stubs.source_removed.txt -> sdk_library/public/mynewlibrary-removed.txt
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index c6cb6c2..51903ce3 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -19,13 +19,11 @@
 	"testing"
 
 	"android/soong/android"
-	"android/soong/genrule"
 	"android/soong/java"
 )
 
 var prepareForSdkTestWithJava = android.GroupFixturePreparers(
 	java.PrepareForTestWithJavaBuildComponents,
-	genrule.PrepareForTestWithGenRuleBuildComponents,
 	PrepareForTestWithSdkBuildComponents,
 
 	// Ensure that all source paths are provided. This helps ensure that the snapshot generation is
@@ -36,7 +34,6 @@
 	// Files needs by most of the tests.
 	android.MockFS{
 		"Test.java": nil,
-		"build/soong/java/invalid_implementation_jar.sh": nil,
 	}.AddToFixture(),
 )
 
@@ -291,26 +288,18 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    jars: [":mysdk_myjavalib-error"],
+    jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"],
     permitted_packages: ["pkg.myjavalib"],
 }
-
-genrule {
-    name: "mysdk_myjavalib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
-}
 `),
 		checkAllCopyRules(`
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
 `),
 	)
 }
 
 func TestSnapshotWithJavaBootLibrary_UpdatableMedia(t *testing.T) {
-	runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedGenRule, expectedCopyRule string) {
+	runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedCopyRule string) {
 		result := android.GroupFixturePreparers(
 			prepareForSdkTestWithJava,
 			android.FixtureMergeEnv(map[string]string{
@@ -345,27 +334,20 @@
     jars: ["%s"],
     permitted_packages: ["pkg.media"],
 }
-%s`, expectedJarPath, expectedGenRule)),
+`, expectedJarPath)),
 			checkAllCopyRules(expectedCopyRule),
 		)
 	}
 
 	t.Run("updatable-media in S", func(t *testing.T) {
-		runTest(t, "S", "java/updatable-media.jar", "", `
+		runTest(t, "S", "java/updatable-media.jar", `
 .intermediates/updatable-media/android_common/package-check/updatable-media.jar -> java/updatable-media.jar
 `)
 	})
 
 	t.Run("updatable-media in T", func(t *testing.T) {
-		runTest(t, "Tiramisu", ":mysdk_updatable-media-error", `
-genrule {
-    name: "mysdk_updatable-media-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) updatable-media",
-}`, `
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+		runTest(t, "Tiramisu", "java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar", `
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar
 `)
 	})
 }
@@ -407,20 +389,12 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["//apex_available:platform"],
-    jars: [":myexports_myjavalib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
     permitted_packages: ["pkg.myjavalib"],
 }
-
-genrule {
-    name: "myexports_myjavalib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) myjavalib",
-}
 `),
 		checkAllCopyRules(`
-build/soong/java/invalid_implementation_jar.sh -> scripts/invalid_implementation_jar.sh
+.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar
 `),
 	)
 }
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 9540a6b..1ac405d 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -119,18 +119,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mylib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
     permitted_packages: ["mylib"],
 }
 
-genrule {
-    name: "mysdk_mylib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
-}
-
 prebuilt_systemserverclasspath_fragment {
     name: "mysystemserverclasspathfragment",
     prefer: false,
@@ -188,18 +180,10 @@
     prefer: false,
     visibility: ["//visibility:public"],
     apex_available: ["myapex"],
-    jars: [":mysdk_mylib-error"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
     permitted_packages: ["mylib"],
 }
 
-genrule {
-    name: "mysdk_mylib-error",
-    visibility: ["//visibility:private"],
-    out: ["this-file-will-never-be-created.jar"],
-    tool_files: ["scripts/invalid_implementation_jar.sh"],
-    cmd: "$(location scripts/invalid_implementation_jar.sh) mylib",
-}
-
 prebuilt_systemserverclasspath_fragment {
     name: "mysystemserverclasspathfragment",
     prefer: false,
diff --git a/sdk/update.go b/sdk/update.go
index 6ebbf09..92a13fa 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1049,6 +1049,9 @@
 	filesToZip  android.Paths
 	zipsToMerge android.Paths
 
+	// The path to an empty file.
+	emptyFile android.WritablePath
+
 	prebuiltModules map[string]*bpModule
 	prebuiltOrder   []*bpModule
 
@@ -1108,6 +1111,19 @@
 	s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
 }
 
+func (s *snapshotBuilder) EmptyFile() android.Path {
+	if s.emptyFile == nil {
+		ctx := s.ctx
+		s.emptyFile = android.PathForModuleOut(ctx, "empty")
+		s.ctx.Build(pctx, android.BuildParams{
+			Rule:   android.Touch,
+			Output: s.emptyFile,
+		})
+	}
+
+	return s.emptyFile
+}
+
 func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule {
 	name := member.Name()
 	if s.prebuiltModules[name] != nil {
@@ -1184,24 +1200,6 @@
 	return m
 }
 
-func (s *snapshotBuilder) AddInternalModule(properties android.SdkMemberProperties, moduleType string, nameSuffix string) android.BpModule {
-	name := properties.Name() + "-" + nameSuffix
-
-	if s.prebuiltModules[name] != nil {
-		panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
-	}
-
-	m := s.bpFile.newModule(moduleType)
-	m.AddProperty("name", name)
-	m.AddProperty("visibility", []string{"//visibility:private"})
-
-	s.prebuiltModules[name] = m
-	s.prebuiltOrder = append(s.prebuiltOrder, m)
-
-	s.allMembersByName[name] = struct{}{}
-	return m
-}
-
 func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, bpModule *bpModule) {
 	// If neither device or host is supported then this module does not support either so will not
 	// recognize the properties.
@@ -1232,23 +1230,18 @@
 // Get a name for sdk snapshot member. If the member is private then generate a snapshot specific
 // name. As part of the processing this checks to make sure that any required members are part of
 // the snapshot.
-func (s *snapshotBuilder) snapshotSdkMemberName(reference string, required bool) string {
-	prefix := ""
-	name := strings.TrimPrefix(reference, ":")
-	if name != reference {
-		prefix = ":"
-	}
+func (s *snapshotBuilder) snapshotSdkMemberName(name string, required bool) string {
 	if _, ok := s.allMembersByName[name]; !ok {
 		if required {
 			s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", name)
 		}
-		return reference
+		return name
 	}
 
 	if s.isInternalMember(name) {
-		return prefix + s.ctx.ModuleName() + "_" + name
+		return s.ctx.ModuleName() + "_" + name
 	} else {
-		return reference
+		return name
 	}
 }
 
@@ -2064,7 +2057,6 @@
 	variantPropertiesFactory := func() android.SdkMemberProperties {
 		properties := memberType.CreateVariantPropertiesStruct()
 		base := properties.Base()
-		base.MemberName = member.Name()
 		base.Os_count = osCount
 		return properties
 	}