Skip to content

Commit

Permalink
Merge pull request #131 from sap-contributions/jvm-version-from-maven
Browse files Browse the repository at this point in the history
Extract JVM version from Maven MANIFEST.MF entries
  • Loading branch information
Daniel Mikusa authored Jan 3, 2022
2 parents 72621c4 + a44f048 commit a1b5761
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 1 deletion.
6 changes: 5 additions & 1 deletion build.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ func (b Build) Build(context libcnb.BuildContext) (libcnb.BuildResult, error) {
cl := NewCertificateLoader()
cl.Logger = b.Logger.BodyWriter()

v, _ := cr.Resolve("BP_JVM_VERSION")
jvmVersion := JVMVersion{Logger: b.Logger}
v, err := jvmVersion.GetJVMVersion(context.Application.Path, cr)
if err != nil {
return libcnb.BuildResult{}, fmt.Errorf("unable to determine jvm version\n%w", err)
}

jreSkipped := false
if t, _ := cr.Resolve("BP_JVM_TYPE"); strings.ToLower(t) == "jdk" {
Expand Down
1 change: 1 addition & 0 deletions init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ func TestUnit(t *testing.T) {
suite("Manifest", testManifest)
suite("MavenJARListing", testMavenJARListing)
suite("Versions", testVersions)
suite("JVMVersions", testJVMVersion)
suite.Run(t)
}
55 changes: 55 additions & 0 deletions jvm_version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package libjvm

import (
"strings"

"github.com/heroku/color"
"github.com/paketo-buildpacks/libpak"
"github.com/paketo-buildpacks/libpak/bard"
)

type JVMVersion struct {
Logger bard.Logger
}

func (jvmVersion JVMVersion) GetJVMVersion(appPath string, cr libpak.ConfigurationResolver) (string, error) {
version, explicit := cr.Resolve("BP_JVM_VERSION")

if !explicit {
manifest, err := NewManifest(appPath)
if err != nil {
return version, err
}

javaVersion := ""

buildJdkSpecVersion, ok := manifest.Get("Build-Jdk-Spec")
if ok {
javaVersion = buildJdkSpecVersion
}

buildJdkVersion, ok := manifest.Get("Build-Jdk")
if ok {
javaVersion = buildJdkVersion
}

if len(javaVersion) > 0 {
javaVersionFromMaven := extractMajorVersion(javaVersion)
f := color.New(color.Faint)
jvmVersion.Logger.Body(f.Sprintf("Using Java version %s extracted from METADATA.MF", javaVersionFromMaven))
return javaVersionFromMaven, nil
}
}

return version, nil
}

func extractMajorVersion(version string) string {
versionParts := strings.Split(version, ".")

if versionParts[0] == "1" {
return versionParts[1]
}

return versionParts[0]
}
150 changes: 150 additions & 0 deletions jvm_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2018-2020 the original author or authors.
*
* 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
*
* https://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.
*/

package libjvm_test

import (
"github.com/paketo-buildpacks/libpak"
"github.com/paketo-buildpacks/libpak/bard"
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/buildpacks/libcnb"
. "github.com/onsi/gomega"
"github.com/sclevine/spec"

"github.com/paketo-buildpacks/libjvm"
)

func testJVMVersion(t *testing.T, context spec.G, it spec.S) {
var (
Expect = NewWithT(t).Expect
appPath string
logger bard.Logger
buildpack libcnb.Buildpack
)

it.Before(func() {
buildpack = libcnb.Buildpack{
Metadata: map[string]interface{}{
"configurations": []map[string]interface{}{
{
"name": "BP_JVM_VERSION",
"default": "1.1.1",
},
},
},
}
logger = bard.NewLogger(ioutil.Discard)
})

it("detecting JVM version from default", func() {
jvmVersion := libjvm.JVMVersion{Logger: logger}

cr, err := libpak.NewConfigurationResolver(buildpack, &logger)
Expect(err).ToNot(HaveOccurred())
version, err := jvmVersion.GetJVMVersion(appPath, cr)
Expect(err).ToNot(HaveOccurred())
Expect(version).To(Equal("1.1.1"))
})

context("detecting JVM version", func() {
it.Before(func() {
Expect(os.Setenv("BP_JVM_VERSION", "17")).To(Succeed())
})

it.After(func() {
Expect(os.Unsetenv("BP_JVM_VERSION")).To(Succeed())
})

it("from environment variable", func() {
jvmVersion := libjvm.JVMVersion{Logger: logger}

cr, err := libpak.NewConfigurationResolver(buildpack, &logger)
Expect(err).ToNot(HaveOccurred())
version, err := jvmVersion.GetJVMVersion(appPath, cr)
Expect(err).ToNot(HaveOccurred())
Expect(version).To(Equal("17"))
})
})

context("detecting JVM version", func() {
it.Before(func() {
temp, err := prepareAppWithEntry("Build-Jdk: 1.8")
Expect(err).ToNot(HaveOccurred())
appPath = temp
})

it.After(func() {
os.RemoveAll(appPath)
})

it("from manifest via Build-Jdk-Spec", func() {
jvmVersion := libjvm.JVMVersion{Logger: logger}

cr, err := libpak.NewConfigurationResolver(buildpack, &logger)
Expect(err).ToNot(HaveOccurred())
version, err := jvmVersion.GetJVMVersion(appPath, cr)
Expect(err).ToNot(HaveOccurred())
Expect(version).To(Equal("8"))
})
})

context("detecting JVM version", func() {
it.Before(func() {
Expect(os.Setenv("BP_JVM_VERSION", "17")).To(Succeed())
temp, err := prepareAppWithEntry("Build-Jdk: 1.8")
Expect(err).ToNot(HaveOccurred())
appPath = temp
})

it.After(func() {
Expect(os.Unsetenv("BP_JVM_VERSION")).To(Succeed())
os.RemoveAll(appPath)
})

it("prefers environment variable over manifest", func() {
jvmVersion := libjvm.JVMVersion{Logger: logger}

cr, err := libpak.NewConfigurationResolver(buildpack, &logger)
Expect(err).ToNot(HaveOccurred())
version, err := jvmVersion.GetJVMVersion(appPath, cr)
Expect(err).ToNot(HaveOccurred())
Expect(version).To(Equal("17"))
})
})

}

func prepareAppWithEntry(entry string) (string, error) {
temp, err := ioutil.TempDir("", "jre-app")
if err != nil {
return "", err
}
err = os.Mkdir(filepath.Join(temp, "META-INF"), 0744)
if err != nil {
return "", err
}
manifest := filepath.Join(temp, "META-INF", "MANIFEST.MF")
manifestContent := []byte(entry)
err = ioutil.WriteFile(manifest, manifestContent, 0644)
if err != nil {
return "", err
}
return temp, nil
}

0 comments on commit a1b5761

Please sign in to comment.