diff --git a/manifest.yml b/manifest.yml index f97db6566..e2ad36bb5 100644 --- a/manifest.yml +++ b/manifest.yml @@ -97,9 +97,16 @@ dependencies: cf_stacks: - cflinuxfs3 - cflinuxfs4 - - cflinuxfs5 source: https://java-buildpack.cloudfoundry.org/openjdk-jdk/bionic/x86_64/openjdk-jdk-1.8.0_242-bionic.tar.gz source_sha256: dcb9fea2fc3a9b003031874ed17aa5d5a7ebbe397b276ecc8c814633003928fe +- name: openjdk + version: 17.0.13 + uri: https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jre_x64_linux_hotspot_17.0.13_11.tar.gz + sha256: 4086cc7cb2d9e7810141f255063caad10a8a018db5e6b47fa5394c506ab65bff + cf_stacks: + - cflinuxfs5 + source: https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.13%2B11/OpenJDK17U-jre_x64_linux_hotspot_17.0.13_11.tar.gz + source_sha256: 4086cc7cb2d9e7810141f255063caad10a8a018db5e6b47fa5394c506ab65bff - name: ruby version: 3.2.8 uri: https://buildpacks.cloudfoundry.org/dependencies/ruby/ruby_3.2.8_linux_x64_cflinuxfs3_f36a7c8d.tgz diff --git a/src/ruby/supply/mocks_test.go b/src/ruby/supply/mocks_test.go index 626d847a3..98050dfad 100644 --- a/src/ruby/supply/mocks_test.go +++ b/src/ruby/supply/mocks_test.go @@ -193,6 +193,20 @@ func (mr *MockInstallerMockRecorder) InstallOnlyVersion(arg0, arg1 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallOnlyVersion", reflect.TypeOf((*MockInstaller)(nil).InstallOnlyVersion), arg0, arg1) } +// InstallOnlyVersionWithStrip mocks base method. +func (m *MockInstaller) InstallOnlyVersionWithStrip(arg0, arg1 string, arg2 int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InstallOnlyVersionWithStrip", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// InstallOnlyVersionWithStrip indicates an expected call of InstallOnlyVersionWithStrip. +func (mr *MockInstallerMockRecorder) InstallOnlyVersionWithStrip(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstallOnlyVersionWithStrip", reflect.TypeOf((*MockInstaller)(nil).InstallOnlyVersionWithStrip), arg0, arg1, arg2) +} + // MockVersions is a mock of Versions interface. type MockVersions struct { ctrl *gomock.Controller diff --git a/src/ruby/supply/supply.go b/src/ruby/supply/supply.go index 987bdd16d..10e590c82 100644 --- a/src/ruby/supply/supply.go +++ b/src/ruby/supply/supply.go @@ -30,6 +30,7 @@ type Manifest interface { type Installer interface { InstallDependency(libbuildpack.Dependency, string) error InstallOnlyVersion(string, string) error + InstallOnlyVersionWithStrip(string, string, int) error } type Versions interface { @@ -386,8 +387,17 @@ func (s *Supplier) InstallJVM() error { } jvmInstallDir := filepath.Join(s.Stager.DepDir(), "jvm") - if err := s.Installer.InstallOnlyVersion("openjdk1.8-latest", jvmInstallDir); err != nil { - return err + if len(s.Manifest.AllDependencyVersions("openjdk")) > 0 { + // New naming used in cflinuxfs5: openjdk with semantic version (8.x, 17.x, 21.x,…) + // BellSoft Liberica / Temurin tarballs have a top-level jdk-XX/ directory, strip it. + if err := s.Installer.InstallOnlyVersionWithStrip("openjdk", jvmInstallDir, 1); err != nil { + return err + } + } else { + // Legacy naming used in cflinuxfs3/4: flat tarball, no strip needed. + if err := s.Installer.InstallOnlyVersion("openjdk1.8-latest", jvmInstallDir); err != nil { + return err + } } if err := s.Stager.LinkDirectoryInDepDir(filepath.Join(jvmInstallDir, "bin"), "bin"); err != nil { return err diff --git a/src/ruby/supply/supply_test.go b/src/ruby/supply/supply_test.go index 5b9168435..189bd65fe 100644 --- a/src/ruby/supply/supply_test.go +++ b/src/ruby/supply/supply_test.go @@ -605,6 +605,7 @@ var _ = Describe("Supply", func() { Context("app/.jdk does not exist", func() { BeforeEach(func() { + mockManifest.EXPECT().AllDependencyVersions("openjdk").Return([]string{}) mockInstaller.EXPECT().InstallOnlyVersion("openjdk1.8-latest", gomock.Any()).Do(func(_, path string) error { Expect(os.MkdirAll(filepath.Join(path, "bin"), 0755)).To(Succeed()) Expect(os.WriteFile(filepath.Join(path, "bin", "java"), []byte("java.exe"), 0755)).To(Succeed()) @@ -625,6 +626,24 @@ var _ = Describe("Supply", func() { Expect(string(body)).To(ContainSubstring(`export JAVA_MEM=${JAVA_MEM:--Xmx${JVM_MAX_HEAP:-384}m}`)) }) }) + + Context("app/.jdk does not exist and openjdk (new naming) is available", func() { + BeforeEach(func() { + // Override the global AllDependencyVersions("openjdk") mock for this context + mockManifest.EXPECT().AllDependencyVersions("openjdk").Return([]string{"17.0.13"}).AnyTimes() + mockInstaller.EXPECT().InstallOnlyVersionWithStrip("openjdk", gomock.Any(), 1).Do(func(_, path string, _ int) error { + Expect(os.MkdirAll(filepath.Join(path, "bin"), 0755)).To(Succeed()) + Expect(os.WriteFile(filepath.Join(path, "bin", "java"), []byte("java.exe"), 0755)).To(Succeed()) + return nil + }) + }) + + It("installs and links the JDK using new openjdk naming (cflinuxfs5)", func() { + Expect(supplier.InstallJVM()).To(Succeed()) + Expect(filepath.Join(depsDir, depsIdx, "jvm", "bin", "java")).To(BeAnExistingFile()) + Expect(filepath.Join(depsDir, depsIdx, "bin", "java")).To(BeAnExistingFile()) + }) + }) }) Describe("EnableLDLibraryPathEnv", func() {