Merge changes from topic "java_test_junit"

* changes:
  Don't pass resources to r8
  Support patch_module in java modules
  Make :module provide the output file for java modules
  Don't link java tests against junit by default
diff --git a/android/paths.go b/android/paths.go
index c9e7150..e69fbe7 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -663,6 +663,11 @@
 	return p
 }
 
+func (p OutputPath) WithoutRel() OutputPath {
+	p.basePath.rel = filepath.Base(p.basePath.path)
+	return p
+}
+
 var _ Path = OutputPath{}
 
 // PathForOutput joins the provided paths and returns an OutputPath that is
diff --git a/java/aar.go b/java/aar.go
index de67da6..e90f984 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -498,6 +498,14 @@
 	return android.Paths{a.classpathFile}
 }
 
+func (a *AARImport) ResourceJars() android.Paths {
+	return nil
+}
+
+func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
+	return android.Paths{a.classpathFile}
+}
+
 func (a *AARImport) AidlIncludeDirs() android.Paths {
 	return nil
 }
diff --git a/java/androidmk.go b/java/androidmk.go
index 384d7e8..aebbcc8 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -25,7 +25,7 @@
 func (library *Library) AndroidMk() android.AndroidMkData {
 	return android.AndroidMkData{
 		Class:      "JAVA_LIBRARIES",
-		OutputFile: android.OptionalPathForPath(library.implementationJarFile),
+		OutputFile: android.OptionalPathForPath(library.implementationAndResourcesJar),
 		Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
 		Extra: []android.AndroidMkExtraFunc{
 			func(w io.Writer, outputFile android.Path) {
@@ -84,14 +84,14 @@
 				fmt.Fprintln(w, "LOCAL_MODULE := "+name+"-hostdex")
 				fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
 				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := JAVA_LIBRARIES")
-				fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", library.implementationJarFile.String())
+				fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", library.implementationAndResourcesJar.String())
 				if library.installFile == nil {
 					fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
 				}
 				if library.dexJarFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
 				}
-				fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.implementationJarFile.String())
+				fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String())
 				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(data.Required, " "))
 				fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
 			}
@@ -159,8 +159,13 @@
 	if !binary.isWrapperVariant {
 		return android.AndroidMkData{
 			Class:      "JAVA_LIBRARIES",
-			OutputFile: android.OptionalPathForPath(binary.implementationJarFile),
+			OutputFile: android.OptionalPathForPath(binary.outputFile),
 			Include:    "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+			Extra: []android.AndroidMkExtraFunc{
+				func(w io.Writer, outputFile android.Path) {
+					fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", binary.headerJarFile.String())
+				},
+			},
 			Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 				android.WriteAndroidMkData(w, data)
 
@@ -198,8 +203,8 @@
 				if app.dexJarFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", app.dexJarFile.String())
 				}
-				if app.implementationJarFile != nil {
-					fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", app.implementationJarFile)
+				if app.implementationAndResourcesJar != nil {
+					fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", app.implementationAndResourcesJar.String())
 				}
 				if app.headerJarFile != nil {
 					fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", app.headerJarFile.String())
diff --git a/java/builder.go b/java/builder.go
index 55be3a6..ff5de09 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -125,6 +125,7 @@
 )
 
 func init() {
+	pctx.Import("android/soong/common")
 	pctx.Import("android/soong/java/config")
 }
 
@@ -374,8 +375,11 @@
 type classpath []android.Path
 
 func (x *classpath) FormJavaClassPath(optName string) string {
+	if optName != "" && !strings.HasSuffix(optName, "=") && !strings.HasSuffix(optName, " ") {
+		optName += " "
+	}
 	if len(*x) > 0 {
-		return optName + " " + strings.Join(x.Strings(), ":")
+		return optName + strings.Join(x.Strings(), ":")
 	} else {
 		return ""
 	}
diff --git a/java/dex.go b/java/dex.go
index 8363a7d..77a3644 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -140,7 +140,7 @@
 }
 
 func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags,
-	classesJar android.Path, jarName string) android.Path {
+	classesJar android.Path, jarName string) android.ModuleOutPath {
 
 	useR8 := Bool(j.deviceProperties.Optimize.Enabled)
 
@@ -183,6 +183,5 @@
 		})
 	}
 
-	j.dexJarFile = javalibJar
 	return javalibJar
 }
diff --git a/java/java.go b/java/java.go
index a015a99..7057046 100644
--- a/java/java.go
+++ b/java/java.go
@@ -135,6 +135,15 @@
 		Javacflags []string
 	}
 
+	// When compiling language level 9+ .java code in packages that are part of
+	// a system module, patch_module names the module that your sources and
+	// dependencies should be patched into. The Android runtime currently
+	// doesn't implement the JEP 261 module system so this option is only
+	// supported at compile time. It should only be needed to compile tests in
+	// packages that exist in libcore and which are inconvenient to move
+	// elsewhere.
+	Patch_module *string
+
 	Jacoco struct {
 		// List of classes to include for instrumentation with jacoco to collect coverage
 		// information at runtime when building with coverage enabled.  If unset defaults to all
@@ -263,13 +272,22 @@
 	protoProperties  android.ProtoProperties
 	deviceProperties CompilerDeviceProperties
 
-	// header jar file suitable for inserting into the bootclasspath/classpath of another compile
+	// jar file containing header classes including static library dependencies, suitable for
+	// inserting into the bootclasspath/classpath of another compile
 	headerJarFile android.Path
 
-	// full implementation jar file suitable for static dependency of another module compile
+	// jar file containing implementation classes including static library dependencies but no
+	// resources
 	implementationJarFile android.Path
 
-	// output file containing classes.dex
+	// jar file containing only resources including from static library dependencies
+	resourceJar android.Path
+
+	// jar file containing implementation classes and resources including static library
+	// dependencies
+	implementationAndResourcesJar android.Path
+
+	// output file containing classes.dex and resources
 	dexJarFile android.Path
 
 	// output file containing uninstrumented classes that will be instrumented by jacoco
@@ -278,7 +296,7 @@
 	// output file containing mapping of obfuscated names
 	proguardDictionary android.Path
 
-	// output file suitable for installing or running
+	// output file of the module, which may be a classes jar or a dex jar
 	outputFile android.Path
 
 	exportAidlIncludeDirs android.Paths
@@ -300,7 +318,7 @@
 }
 
 func (j *Module) Srcs() android.Paths {
-	return android.Paths{j.implementationJarFile}
+	return android.Paths{j.outputFile}
 }
 
 var _ android.SourceFileProducer = (*Module)(nil)
@@ -308,6 +326,8 @@
 type Dependency interface {
 	HeaderJars() android.Paths
 	ImplementationJars() android.Paths
+	ResourceJars() android.Paths
+	ImplementationAndResourcesJars() android.Paths
 	AidlIncludeDirs() android.Paths
 	ExportedSdkLibs() []string
 }
@@ -664,7 +684,7 @@
 	processorPath      classpath
 	staticJars         android.Paths
 	staticHeaderJars   android.Paths
-	staticJarResources android.Paths
+	staticResourceJars android.Paths
 	aidlIncludeDirs    android.Paths
 	srcs               android.Paths
 	srcJars            android.Paths
@@ -785,10 +805,11 @@
 				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
 				deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
 				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
+				deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
 				// sdk lib names from dependencies are re-exported
 				j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)
 			case annoTag:
-				deps.processorPath = append(deps.processorPath, dep.ImplementationJars()...)
+				deps.processorPath = append(deps.processorPath, dep.ImplementationAndResourcesJars()...)
 			case frameworkResTag:
 				if ctx.ModuleName() == "framework" {
 					// framework.jar has a one-off dependency on the R.java and Manifest.java files
@@ -808,7 +829,7 @@
 					// Normally the package rule runs aapt, which includes the resource,
 					// but we're not running that in our package rule so just copy in the
 					// resource files here.
-					deps.staticJarResources = append(deps.staticJarResources, dep.(*AndroidApp).exportPackage)
+					deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage)
 				}
 			case kotlinStdlibTag:
 				deps.kotlinStdlib = dep.HeaderJars()
@@ -899,11 +920,6 @@
 		// disk and memory usage.
 		javacFlags = append(javacFlags, "-g:source,lines")
 	}
-	if len(javacFlags) > 0 {
-		// optimization.
-		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
-		flags.javacFlags = "$javacFlags"
-	}
 
 	if ctx.Config().RunErrorProne() {
 		if config.ErrorProneClasspath == nil {
@@ -955,6 +971,11 @@
 		}
 	}
 
+	if j.properties.Patch_module != nil && ctx.Config().TargetOpenJDK9() {
+		patchClasspath := ".:" + flags.classpath.FormJavaClassPath("")
+		javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchClasspath)
+	}
+
 	// systemModules
 	if deps.systemModules != nil {
 		flags.systemModules = append(flags.systemModules, deps.systemModules)
@@ -968,6 +989,12 @@
 		flags.aidlFlags = "$aidlFlags"
 	}
 
+	if len(javacFlags) > 0 {
+		// optimization.
+		ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
+		flags.javacFlags = "$javacFlags"
+	}
+
 	return flags
 }
 
@@ -1134,16 +1161,27 @@
 	if len(resArgs) > 0 {
 		resourceJar := android.PathForModuleOut(ctx, "res", jarName)
 		TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
+		j.resourceJar = resourceJar
 		if ctx.Failed() {
 			return
 		}
-
-		jars = append(jars, resourceJar)
 	}
 
-	// static classpath jars have the resources in them, so the resource jars aren't necessary here
+	if len(deps.staticResourceJars) > 0 {
+		var jars android.Paths
+		if j.resourceJar != nil {
+			jars = append(jars, j.resourceJar)
+		}
+		jars = append(jars, deps.staticResourceJars...)
+
+		combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
+		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+			false, nil, nil)
+		j.resourceJar = combinedJar
+	}
+
 	jars = append(jars, deps.staticJars...)
-	jars = append(jars, deps.staticJarResources...)
+	jars = append(jars, deps.staticResourceJars...)
 
 	var manifest android.OptionalPath
 	if j.properties.Manifest != nil {
@@ -1152,14 +1190,24 @@
 
 	// Combine the classes built from sources, any manifests, and any static libraries into
 	// classes.jar. If there is only one input jar this step will be skipped.
-	var outputFile android.Path
+	var outputFile android.ModuleOutPath
 
 	if len(jars) == 1 && !manifest.Valid() {
-		// Optimization: skip the combine step if there is nothing to do
-		// TODO(ccross): this leaves any module-info.class files, but those should only come from
-		// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
-		// any if len(jars) == 1.
-		outputFile = jars[0]
+		if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok {
+			// Optimization: skip the combine step if there is nothing to do
+			// TODO(ccross): this leaves any module-info.class files, but those should only come from
+			// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
+			// any if len(jars) == 1.
+			outputFile = moduleOutPath
+		} else {
+			combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
+			ctx.Build(pctx, android.BuildParams{
+				Rule:   android.Cp,
+				Input:  jars[0],
+				Output: combinedJar,
+			})
+			outputFile = combinedJar
+		}
 	} else {
 		combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
 		TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest,
@@ -1178,12 +1226,21 @@
 		}
 	}
 
+	// jarjar implementation jar if necessary
 	if j.properties.Jarjar_rules != nil {
 		jarjar_rules := android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
 		// Transform classes.jar into classes-jarjar.jar
 		jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName)
 		TransformJarJar(ctx, jarjarFile, outputFile, jarjar_rules)
 		outputFile = jarjarFile
+
+		// jarjar resource jar if necessary
+		if j.resourceJar != nil {
+			resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName)
+			TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, jarjar_rules)
+			j.resourceJar = resourceJarJarFile
+		}
+
 		if ctx.Failed() {
 			return
 		}
@@ -1203,18 +1260,45 @@
 		outputFile = j.instrument(ctx, flags, outputFile, jarName)
 	}
 
+	// merge implementation jar with resources if necessary
+	implementationAndResourcesJar := outputFile
+	if j.resourceJar != nil {
+		jars := android.Paths{implementationAndResourcesJar, j.resourceJar}
+		combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
+		TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
+			false, nil, nil)
+		implementationAndResourcesJar = combinedJar
+	}
+
+	j.implementationAndResourcesJar = implementationAndResourcesJar
+
 	if ctx.Device() && (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) {
-		var dexOutputFile android.Path
+		var dexOutputFile android.ModuleOutPath
 		dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName)
 		if ctx.Failed() {
 			return
 		}
-		if Bool(j.properties.Installable) {
-			outputFile = dexOutputFile
+
+		// merge dex jar with resources if necessary
+		if j.resourceJar != nil {
+			jars := android.Paths{dexOutputFile, j.resourceJar}
+			combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
+			TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
+				false, nil, nil)
+			dexOutputFile = combinedJar
 		}
+
+		j.dexJarFile = dexOutputFile
+
+		outputFile = dexOutputFile
+	} else {
+		outputFile = implementationAndResourcesJar
 	}
+
 	ctx.CheckbuildFile(outputFile)
-	j.outputFile = outputFile
+
+	// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
+	j.outputFile = outputFile.WithoutRel()
 }
 
 func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
@@ -1258,7 +1342,7 @@
 }
 
 func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
-	classesJar android.Path, jarName string) android.Path {
+	classesJar android.Path, jarName string) android.ModuleOutPath {
 
 	specs := j.jacocoModuleToZipCommand(ctx)
 
@@ -1282,6 +1366,17 @@
 	return android.Paths{j.implementationJarFile}
 }
 
+func (j *Module) ResourceJars() android.Paths {
+	if j.resourceJar == nil {
+		return nil
+	}
+	return android.Paths{j.resourceJar}
+}
+
+func (j *Module) ImplementationAndResourcesJars() android.Paths {
+	return android.Paths{j.implementationAndResourcesJar}
+}
+
 func (j *Module) AidlIncludeDirs() android.Paths {
 	return j.exportAidlIncludeDirs
 }
@@ -1343,13 +1438,10 @@
 }
 
 //
-// Java Junit Tests
+// Java Tests
 //
 
 type testProperties struct {
-	// If true, add a static dependency on the platform junit library.  Defaults to true.
-	Junit *bool
-
 	// list of compatibility suites (for example "cts", "vts") that the module should be
 	// installed into.
 	Test_suites []string `android:"arch_variant"`
@@ -1381,9 +1473,6 @@
 
 func (j *Test) DepsMutator(ctx android.BottomUpMutatorContext) {
 	j.deps(ctx)
-	if BoolDefault(j.testProperties.Junit, true) {
-		ctx.AddDependency(ctx.Module(), staticLibTag, "junit")
-	}
 	android.ExtractSourceDeps(ctx, j.testProperties.Test_config)
 	android.ExtractSourcesDeps(ctx, j.testProperties.Data)
 }
@@ -1606,6 +1695,14 @@
 	return android.Paths{j.combinedClasspathFile}
 }
 
+func (j *Import) ResourceJars() android.Paths {
+	return nil
+}
+
+func (j *Import) ImplementationAndResourcesJars() android.Paths {
+	return android.Paths{j.combinedClasspathFile}
+}
+
 func (j *Import) AidlIncludeDirs() android.Paths {
 	return nil
 }
diff --git a/java/java_test.go b/java/java_test.go
index 434bcc7..72341ee 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -719,7 +719,7 @@
 				}
 			`+test.extra)
 
-			foo := ctx.ModuleForTests("foo", "android_common").Output("combined/foo.jar")
+			foo := ctx.ModuleForTests("foo", "android_common").Output("withres/foo.jar")
 			fooRes := ctx.ModuleForTests("foo", "android_common").Output("res/foo.jar")
 
 			if !inList(fooRes.Output.String(), foo.Inputs.Strings()) {