func genJavaConfigs()

in pkg/rbeconfigsgen/rbeconfigsgen.go [565:632]


func genJavaConfigs(d *dockerRunner, o *Options) (generatedFile, error) {
	if !o.GenJavaConfigs {
		return generatedFile{}, nil
	}
	imageEnv, err := d.getEnv()
	if err != nil {
		return generatedFile{}, fmt.Errorf("unable to get the environment of the toolchain image to determine JAVA_HOME: %w", err)
	}
	javaHome, ok := imageEnv["JAVA_HOME"]
	if !ok {
		return generatedFile{}, fmt.Errorf("toolchain image didn't specify environment value JAVA_HOME")
	}
	if len(javaHome) == 0 {
		return generatedFile{}, fmt.Errorf("the value of the JAVA_HOME environment variable was blank in the toolchain image")
	}
	log.Printf("JAVA_HOME was %q.", javaHome)
	javaBin := path.Join(javaHome, "bin/java")
	// "-XshowSettings:properties" is actually what makes java output the version string we're
	// looking for in a more deterministic format. "-version" is just a placeholder so that the
	// command doesn't error out. Although it will likely print the same version string but with
	// some non-deterministic prefix.
	out, err := d.execCmd(javaBin, "-XshowSettings:properties", "-version")
	if err != nil {
		return generatedFile{}, fmt.Errorf("unable to determine the Java version installed in the toolchain container: %w", err)
	}
	javaVersion := ""
	for _, line := range strings.Split(out, "\n") {
		// We're looking for a line that looks like `java.version = <version>` and we want to
		// extract <version>.
		splitVersion := strings.SplitN(line, "=", 2)
		if len(splitVersion) != 2 {
			continue
		}
		key := strings.TrimSpace(splitVersion[0])
		val := strings.TrimSpace(splitVersion[1])
		if key != "java.version" {
			continue
		}
		javaVersion = val
	}
	if len(javaVersion) == 0 {
		return generatedFile{}, fmt.Errorf("unable to determine the java version installed in the container by running 'java -XshowSettings:properties' in the container because it didn't return a line that looked like java.version = <version>")
	}
	log.Printf("Java version: '%s'.", javaVersion)

	usesNewJavaRule := o.JavaUseLocalRuntime
	if !usesNewJavaRule {
		usesNewJavaRule, err = UsesLocalJavaRuntime(o.BazelVersion)
		if err != nil {
			return generatedFile{}, fmt.Errorf("unable to determine what Java toolchain rule to use for Bazel %q: %w", o.BazelVersion, err)
		}
	}
	t := legacyJavaBuildTemplate
	if usesNewJavaRule {
		t = javaBuildTemplate
	}
	buf := bytes.NewBuffer(nil)
	if err := t.Execute(buf, &javaBuildTemplateParams{
		JavaHome:    javaHome,
		JavaVersion: javaVersion,
	}); err != nil {
		return generatedFile{}, fmt.Errorf("failed to generate the contents of the BUILD file with the Java toolchain definition: %w", err)
	}
	return generatedFile{
		name:     "java/BUILD",
		contents: buf.Bytes(),
	}, nil
}