Skip to content

Commit

Permalink
Change default OpenJDK version (#681)
Browse files Browse the repository at this point in the history
  • Loading branch information
Malax authored May 28, 2024
1 parent 022828c commit 27c6522
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 17 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions buildpacks/jvm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Checksum validation of downloaded OpenJDK distribution files. ([#680](https://github.com/heroku/buildpacks-jvm/pull/680))
- A warning will now be shown when the OpenJDK version is not explicitly configured for an application. ([#681](https://github.com/heroku/buildpacks-jvm/pull/681))

### Changed

- This buildpack now installs the latest long-term support release (currently 21) of OpenJDK if no version is explicitly configured. Previously, OpenJDK 8 was installed as the default. ([#681](https://github.com/heroku/buildpacks-jvm/pull/681))
- Some error messages have changed so they longer suggest to open a Heroku support ticket. Instead, users are now provided with a link to create an issue on GitHub. ([#674](https://github.com/heroku/buildpacks-jvm/pull/674))

### Removed
Expand Down
1 change: 1 addition & 0 deletions buildpacks/jvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ inventory = { git = "https://github.com/Malax/inventory", features = ["sha2"] }
thiserror = "1"
sha2 = "0.10"
hex = "0.4"
toml = "0.8"

[dev-dependencies]
buildpacks-jvm-shared-test.workspace = true
Expand Down
1 change: 1 addition & 0 deletions buildpacks/jvm/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub(crate) const JAVA_TOOL_OPTIONS_ENV_VAR_DELIMITER: &str = " ";
pub(crate) const JAVA_TOOL_OPTIONS_ENV_VAR_NAME: &str = "JAVA_TOOL_OPTIONS";
pub(crate) const JDK_OVERLAY_DIR_NAME: &str = ".jdk_overlay";
pub(crate) const OPENJDK_LATEST_LTS_VERSION: u32 = 21;
71 changes: 55 additions & 16 deletions buildpacks/jvm/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@ mod errors;
mod layers;
mod openjdk_artifact;
mod openjdk_version;
mod salesforce_functions;
mod util;

use crate::constants::OPENJDK_LATEST_LTS_VERSION;
use crate::errors::on_error_jvm_buildpack;
use crate::layers::openjdk::OpenJdkLayer;
use crate::layers::runtime::RuntimeLayer;
use crate::openjdk_artifact::{
OpenJdkArtifactMetadata, OpenJdkArtifactRequirement, OpenJdkArtifactRequirementParseError,
HerokuOpenJdkVersionRequirement, OpenJdkArtifactMetadata, OpenJdkArtifactRequirement,
OpenJdkArtifactRequirementParseError, OpenJdkDistribution,
};
use crate::openjdk_version::OpenJdkVersion;
use crate::salesforce_functions::is_salesforce_function_app;
use buildpacks_jvm_shared::system_properties::{read_system_properties, ReadSystemPropertiesError};
#[cfg(test)]
use buildpacks_jvm_shared_test as _;
pub(crate) use constants::{
JAVA_TOOL_OPTIONS_ENV_VAR_DELIMITER, JAVA_TOOL_OPTIONS_ENV_VAR_NAME, JDK_OVERLAY_DIR_NAME,
};
use indoc::formatdoc;
use inventory::artifact::{Arch, Os};
use inventory::inventory::{Inventory, ParseInventoryError};
use libcnb::build::{BuildContext, BuildResult, BuildResultBuilder};
Expand All @@ -24,16 +32,13 @@ use libcnb::data::layer_name;
use libcnb::detect::{DetectContext, DetectResult, DetectResultBuilder};
use libcnb::generic::{GenericMetadata, GenericPlatform};
use libcnb::Buildpack;
use libherokubuildpack::download::DownloadError;
use std::env::consts;
use url as _; // Used by exec.d binary

use crate::openjdk_version::OpenJdkVersion;
#[cfg(test)]
use buildpacks_jvm_shared_test as _;
#[cfg(test)]
use libcnb_test as _;
use libherokubuildpack::download::DownloadError;
use libherokubuildpack::log::log_warning;
use sha2::Sha256;
use std::env::consts;
use url as _; // Used by exec.d binary

struct OpenJdkBuildpack;

Expand Down Expand Up @@ -86,19 +91,53 @@ impl Buildpack for OpenJdkBuildpack {

fn build(&self, context: BuildContext<Self>) -> libcnb::Result<BuildResult, Self::Error> {
let openjdk_artifact_requirement = read_system_properties(&context.app_dir)
.map(|properties| {
properties
.get("java.runtime.version")
.cloned()
.unwrap_or(String::from("8"))
})
.map_err(OpenJdkBuildpackError::ReadSystemPropertiesError)
.map(|properties| properties.get("java.runtime.version").cloned())
.and_then(|string| {
string
.parse::<OpenJdkArtifactRequirement>()
.map_err(OpenJdkBuildpackError::OpenJdkArtifactRequirementParseError)
.map(|string| {
string
.parse::<OpenJdkArtifactRequirement>()
.map_err(OpenJdkBuildpackError::OpenJdkArtifactRequirementParseError)
})
.transpose()
})?;

let openjdk_artifact_requirement = if let Some(openjdk_artifact_requirement) =
openjdk_artifact_requirement
{
openjdk_artifact_requirement
// The default version for Salesforce functions is always OpenJDK 8. Keep this conditional
// around until Salesforce functions is EOL and then remove it.
} else if is_salesforce_function_app(&context.app_dir) {
OpenJdkArtifactRequirement {
version: HerokuOpenJdkVersionRequirement::Major(8),
distribution: OpenJdkDistribution::default(),
}
} else {
log_warning(
"No OpenJDK version specified",
formatdoc! {"
Your application does not explicitly specify an OpenJDK version. The latest
long-term support (LTS) version will be installed. This currently is OpenJDK {OPENJDK_LATEST_LTS_VERSION}.
This default version will change when a new LTS version is released. Your
application might fail to build with the new version. We recommend explicitly
setting the required OpenJDK version for your application.
To set the OpenJDK version, add or edit the system.properties file in the root
directory of your application to contain:
java.runtime.version = {OPENJDK_LATEST_LTS_VERSION}
"},
);

OpenJdkArtifactRequirement {
version: HerokuOpenJdkVersionRequirement::Major(OPENJDK_LATEST_LTS_VERSION),
distribution: OpenJdkDistribution::default(),
}
};

let openjdk_inventory = include_str!("../openjdk_inventory.toml")
.parse::<Inventory<OpenJdkVersion, Sha256, OpenJdkArtifactMetadata>>()
.map_err(OpenJdkBuildpackError::ParseInventoryError)?;
Expand Down
22 changes: 22 additions & 0 deletions buildpacks/jvm/src/salesforce_functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use libcnb::read_toml_file;
use std::path::Path;

pub(crate) fn is_salesforce_function_app(app_dir: &Path) -> bool {
read_toml_file::<toml::value::Value>(app_dir.join("project.toml"))
.is_ok_and(|project_toml_table| matches!(value_at_path(&project_toml_table, &["com", "salesforce", "type"]), Some(toml::Value::String(salesforce_type)) if salesforce_type == "function"))
}

fn value_at_path<'a>(table: &'a toml::value::Value, path: &[&str]) -> Option<&'a toml::Value> {
let mut value = table;

for path_segment in path {
if let toml::Value::Table(table) = value {
match table.get(*path_segment) {
Some(next_value) => value = next_value,
None => return None,
}
}
}

Some(value)
}
6 changes: 6 additions & 0 deletions buildpacks/jvm/test-apps/java-default-app/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>bogus</groupId>
<artifactId>bogus</artifactId>
<version>1.0.0</version>
</project>
6 changes: 6 additions & 0 deletions buildpacks/jvm/test-apps/salesforce-functions-app/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>bogus</groupId>
<artifactId>bogus</artifactId>
<version>1.0.0</version>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[com.salesforce]
type = "function"
67 changes: 66 additions & 1 deletion buildpacks/jvm/tests/integration/versions.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
use crate::default_build_config;
use libcnb_test::{assert_contains, TestRunner};
use indoc::formatdoc;
use libcnb::data::buildpack_id;
use libcnb_test::{assert_contains, assert_not_contains, BuildpackReference, TestRunner};

#[test]
#[ignore = "integration test"]
fn openjdk_default() {
TestRunner::default().build(
default_build_config("test-apps/java-default-app").buildpacks([
BuildpackReference::CurrentCrate,
// We need another buildpack to require 'jvm' in the build plan to be able to use a
// default OpenJDK version. It could be any other buildpack, heroku/maven is just
// convenient to use here.
BuildpackReference::WorkspaceBuildpack(buildpack_id!("heroku/maven")),
]),
|context| {
assert_contains!(
context.pack_stderr,
&formatdoc! {"
[Warning: No OpenJDK version specified]
Your application does not explicitly specify an OpenJDK version. The latest
long-term support (LTS) version will be installed. This currently is OpenJDK 21.
This default version will change when a new LTS version is released. Your
application might fail to build with the new version. We recommend explicitly
setting the required OpenJDK version for your application.
To set the OpenJDK version, add or edit the system.properties file in the root
directory of your application to contain:
java.runtime.version = 21
"}
);

assert_contains!(
context.run_shell_command("java -version").stderr,
"openjdk version \"21.0.3\""
);
},
);
}

#[test]
#[ignore = "integration test"]
fn openjdk_functions_default() {
TestRunner::default().build(
default_build_config("test-apps/salesforce-functions-app").buildpacks([
BuildpackReference::CurrentCrate,
// We need another buildpack to require 'jvm' in the build plan to be able to use a
// default OpenJDK version. It could be any other buildpack, heroku/maven is just
// convenient to use here.
BuildpackReference::WorkspaceBuildpack(buildpack_id!("heroku/maven")),
]),
|context| {
assert_not_contains!(
context.pack_stderr,
"[Warning: No OpenJDK version specified]"
);

assert_contains!(
context.run_shell_command("java -version").stderr,
"openjdk version \"1.8.0_412\""
);
},
);
}

#[test]
#[ignore = "integration test"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
java.runtime.version = 8

0 comments on commit 27c6522

Please sign in to comment.