From 4d471839a80b397c844d7fb365171d9e5f480dc7 Mon Sep 17 00:00:00 2001 From: "Mateusz \"Serafin\" Gajewski" Date: Fri, 22 Nov 2024 15:28:37 +0100 Subject: [PATCH] Add per-jdk version configuration support --- src/main/go/args/java_execution.go | 35 +++++++++++++++++++++++++ src/main/go/args/java_execution_test.go | 29 ++++++++++++++++++++ src/main/go/args/java_static_config.go | 10 +++++++ 3 files changed, 74 insertions(+) create mode 100644 src/main/go/args/java_execution_test.go create mode 100644 src/main/go/args/java_static_config.go diff --git a/src/main/go/args/java_execution.go b/src/main/go/args/java_execution.go index 1e7ca8d..ba12eee 100644 --- a/src/main/go/args/java_execution.go +++ b/src/main/go/args/java_execution.go @@ -6,6 +6,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "runtime" "strings" ) @@ -14,6 +15,30 @@ func getArchSpecificDirectory() string { return fmt.Sprintf("%s-%s", runtime.GOOS, runtime.GOARCH) } +func DetectJvmVersion(javaBin string) (string, error) { + command := exec.Command(javaBin, "-version") + output, err := command.CombinedOutput() + if err != nil { + return "", fmt.Errorf("could not exec java to determine jvm version: %w", err) + } + + return ExtractJvmVersion(string(output)) +} + +func ExtractJvmVersion(output string) (string, error) { + regex := regexp.MustCompile("version \"(.*)\"") + matches := regex.FindStringSubmatch(output) + if len(matches) != 2 { + return "", fmt.Errorf("unrecognized java version output: %s", output) + } + return matches[1], nil +} + +func GetMajorJavaVersion(javaVersion string) string { + components := strings.Split(javaVersion, ".") + return components[0] +} + func (options *Options) JavaExecution(daemonize bool) ([]string, []string, error) { var javaBin = "java" @@ -27,6 +52,11 @@ func (options *Options) JavaExecution(daemonize bool) ([]string, []string, error javaBin = filepath.Join(options.JvmDir, "bin/java") } + jdkVersion, err := DetectJvmVersion(javaBin) + if err != nil { + return nil, nil, err + } + properties := make(map[string]string) for k, v := range options.SystemProperties { properties[k] = v @@ -61,6 +91,11 @@ func (options *Options) JavaExecution(daemonize bool) ([]string, []string, error command := []string{javaBin, "-cp", classpath} command = append(command, options.JvmConfig...) + + if perJdkConfig, exists := jvmSpecificConfig[GetMajorJavaVersion(jdkVersion)]; exists { + command = append(command, perJdkConfig...) + } + if len(options.JvmOptions) != 0 { command = append(command, strings.Join(options.JvmOptions, " ")) } diff --git a/src/main/go/args/java_execution_test.go b/src/main/go/args/java_execution_test.go new file mode 100644 index 0000000..89b03f4 --- /dev/null +++ b/src/main/go/args/java_execution_test.go @@ -0,0 +1,29 @@ +package args + +import "testing" + +func TestParsingJvmVersion(t *testing.T) { + testCases := []struct { + output string + expectedVersion string + }{ + { + output: "openjdk version \"24-ea\" 2025-03-18\nOpenJDK Runtime Environment (build 24-ea+24-2960)\nOpenJDK 64-Bit Server VM (build 24-ea+24-2960, mixed mode, sharing)", + expectedVersion: "24-ea", + }, + { + output: "openjdk version \"23\" 2024-09-17\nOpenJDK Runtime Environment Temurin-23+37 (build 23+37)\nOpenJDK 64-Bit Server VM Temurin-23+37 (build 23+37, mixed mode, sharing)", + expectedVersion: "23", + }, + } + + for _, testCase := range testCases { + actualVersion, err := ExtractJvmVersion(testCase.output) + if err != nil { + t.Fatalf("Unexpected error while extracting JVM version: %v", err) + } + if actualVersion != testCase.expectedVersion { + t.Fatalf("Expected Java version %s for output %s", testCase.expectedVersion, testCase.output) + } + } +} diff --git a/src/main/go/args/java_static_config.go b/src/main/go/args/java_static_config.go new file mode 100644 index 0000000..dfd4420 --- /dev/null +++ b/src/main/go/args/java_static_config.go @@ -0,0 +1,10 @@ +package args + +const vectorApiIncubating = "--add-modules=jdk.incubator.vector" + +var jvmSpecificConfig = map[string][]string{ + "22": {vectorApiIncubating}, + "23": {vectorApiIncubating}, + // 24 is not released yet, but vector API will be still incubating + "24": {vectorApiIncubating}, +}