-
Notifications
You must be signed in to change notification settings - Fork 21
/
jvm_version.go
118 lines (98 loc) · 3.57 KB
/
jvm_version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package libjvm
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/heroku/color"
"github.com/paketo-buildpacks/libpak"
"github.com/paketo-buildpacks/libpak/bard"
)
type JVMVersion struct {
Logger bard.Logger
}
func NewJVMVersion(logger bard.Logger) JVMVersion {
return JVMVersion{Logger: logger}
}
func (j JVMVersion) GetJVMVersion(appPath string, cr libpak.ConfigurationResolver, dr libpak.DependencyResolver) (string, error) {
version, explicit := cr.Resolve("BP_JVM_VERSION")
if explicit {
f := color.New(color.Faint)
j.Logger.Body(f.Sprintf("Using Java version %s from BP_JVM_VERSION", version))
return version, nil
}
sdkmanrcJavaVersion, err := readJavaVersionFromSDKMANRCFile(appPath)
if err != nil {
return "", fmt.Errorf("unable to read Java version from SDMANRC file\n%w", err)
}
if len(sdkmanrcJavaVersion) > 0 {
sdkmanrcJavaMajorVersion := extractMajorVersion(sdkmanrcJavaVersion)
f := color.New(color.Faint)
j.Logger.Body(f.Sprintf("Using Java version %s extracted from .sdkmanrc", sdkmanrcJavaMajorVersion))
return sdkmanrcJavaMajorVersion, nil
}
mavenJavaVersion, err := readJavaVersionFromMavenMetadata(appPath)
if err != nil {
return "", fmt.Errorf("unable to read Java version from Maven metadata\n%w", err)
}
if len(mavenJavaVersion) > 0 {
mavenJavaMajorVersion := extractMajorVersion(mavenJavaVersion)
retrieveNextAvailableJavaVersionIfMavenVersionNotAvailable(dr, &mavenJavaMajorVersion)
f := color.New(color.Faint)
j.Logger.Body(f.Sprintf("Using Java version %s extracted from MANIFEST.MF", mavenJavaMajorVersion))
return mavenJavaMajorVersion, nil
}
f := color.New(color.Faint)
j.Logger.Body(f.Sprintf("Using buildpack default Java version %s", version))
return version, nil
}
func retrieveNextAvailableJavaVersionIfMavenVersionNotAvailable(dr libpak.DependencyResolver, mavenJavaMajorVersion *string) {
_, jdkErr := dr.Resolve("jdk", *mavenJavaMajorVersion)
_, jreErr := dr.Resolve("jre", *mavenJavaMajorVersion)
if libpak.IsNoValidDependencies(jdkErr) && libpak.IsNoValidDependencies(jreErr) {
// the buildpack does not provide the wanted JDK or JRE version - let's check if we can choose a more recent version
mavenJavaMajorVersionAsInt, _ := strconv.ParseInt(*mavenJavaMajorVersion, 10, 64)
nextVersionToEvaluate := mavenJavaMajorVersionAsInt + 1
_, jdkErr := dr.Resolve("jdk", strconv.FormatInt(nextVersionToEvaluate, 10))
_, jreErr := dr.Resolve("jre", strconv.FormatInt(nextVersionToEvaluate, 10))
if libpak.IsNoValidDependencies(jdkErr) && libpak.IsNoValidDependencies(jreErr) {
// we tried with the next major version, still no Java candidate, we are done trying.
} else {
*mavenJavaMajorVersion = strconv.FormatInt(nextVersionToEvaluate, 10)
}
}
}
func readJavaVersionFromSDKMANRCFile(appPath string) (string, error) {
components, err := ReadSDKMANRC(filepath.Join(appPath, ".sdkmanrc"))
if err != nil && errors.Is(err, os.ErrNotExist) {
return "", nil
} else if err != nil {
return "", err
}
for _, component := range components {
if component.Type == "java" {
return component.Version, nil
}
}
return "", nil
}
func readJavaVersionFromMavenMetadata(appPath string) (string, error) {
manifest, err := NewManifest(appPath)
if err != nil {
return "", err
}
javaVersion, ok := manifest.Get("Build-Jdk-Spec")
if !ok {
javaVersion, _ = manifest.Get("Build-Jdk")
}
return javaVersion, nil
}
func extractMajorVersion(version string) string {
versionParts := strings.Split(version, ".")
if versionParts[0] == "1" {
return versionParts[1]
}
return versionParts[0]
}