Skip to content

Commit

Permalink
Java provider default jdk17 and custom versions (#725)
Browse files Browse the repository at this point in the history
* better jdk version detection

* update snapshot tests

* update java docs
  • Loading branch information
coffee-cup authored Dec 17, 2022
1 parent a7e2477 commit 8ad1ec5
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 53 deletions.
41 changes: 31 additions & 10 deletions docs/pages/docs/providers/java.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,51 +6,72 @@ title: Java

Java is detected if a `pom.[xml|atom|clj|groovy|rb|scala|yaml|yml]` or `gradlew` file is found.

## Install
## Setup

```
Skipped
```
### JDK

The following major JDK versions are available

- `19`
- `17` (Default)
- `11`
- `8`

The version can be overriden by setting the `NIXPACKS_JDK_VERSION` environment variable.

### Gradle

The following major Gradle verions are available

- `7` (Default)
- `6`
- `5`
- `4`

The version can be overriden by setting the `NIXPACKS_GRADLE_VERSION` environment variable.

## Build

If Maven is found:
If Maven is found:

```
/bin/maven -DoutputFile=target/mvn-dependency-list.log -B -DskipTests clean dependency:list install
```

If Gradle is found:

```
./gradlew build
```

## Start

If Maven is found:
If Maven is found:

```
java $JAVA_OPTS -jar target/*jar
```

If Maven and Wildfly Swarm is found:

If Maven and Wildfly Swarm is found:
```
java -Dswarm.http.port=$PORT $JAVA_OPTS -jar target/*jar
```

If Maven and Spring Boot is found:

If Maven and Spring Boot is found:
```
java -Dserver.port=$PORT $JAVA_OPTS -jar target/*jar
```


If Gradle is found:

```
java $JAVA_OPTS -jar build/libs/*.jar
```


If Gradle and Spring Boot is found:

```
java $JAVA_OPTS -jar -Dserver.port=$PORT build/libs/*.jar
```
202 changes: 162 additions & 40 deletions src/providers/java.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ use crate::nixpacks::{
BuildPlan,
},
};
use anyhow::Result;
use regex::{Match, Regex};
use anyhow::{bail, Result};
use regex::Regex;

pub struct JavaProvider {}

const DEFAULT_JDK_VERSION: u32 = 17;
const DEFAULT_GRADLE_VERSION: u32 = 7;

impl Provider for JavaProvider {
fn name(&self) -> &str {
"java"
Expand All @@ -30,11 +33,10 @@ impl Provider for JavaProvider {
|| app.includes_file("gradlew"))
}

fn get_build_plan(&self, app: &App, _env: &Environment) -> Result<Option<BuildPlan>> {
let mut setup: Phase;
let mut build = if self.is_using_gradle(app) {
let pkgs = self.get_jdk_and_gradle_pkgs(app)?;
setup = Phase::setup(Some(pkgs));
fn get_build_plan(&self, app: &App, env: &Environment) -> Result<Option<BuildPlan>> {
let (setup, build) = if self.is_using_gradle(app) {
let pkgs = self.get_jdk_and_gradle_pkgs(app, env)?;
let setup = Phase::setup(Some(pkgs));

let mut build = Phase::build(None);
let gradle_exe = self.get_gradle_exe(app);
Expand All @@ -46,19 +48,26 @@ impl Provider for JavaProvider {

build.add_cmd(format!("{gradle_exe} build -x check"));
build.add_cache_directory("/root/.gradle");
build
build.depends_on_phase("setup");

(setup, build)
} else {
setup = Phase::setup(Some(vec![Pkg::new("jdk")]));
setup.add_nix_pkgs(&[Pkg::new("maven")]);
let jdk_version = self.get_jdk_version(app, env)?;
let jdk_pkg = self.get_jdk_pkg(jdk_version)?;

let setup = Phase::setup(Some(vec![jdk_pkg, Pkg::new("maven")]));

let mvn_exe = self.get_maven_exe(app);
let mut build = Phase::build(Some(format!("{mvn_exe} -DoutputFile=target/mvn-dependency-list.log -B -DskipTests clean dependency:list install",
mvn_exe=mvn_exe
)));
build.add_cache_directory(".m2/repository");
build
build.depends_on_phase("setup");

(setup, build)
};

let start = StartPhase::new(self.get_start_cmd(app)?);
build.depends_on = Some(vec!["setup".to_string()]);

let plan = BuildPlan::new(&vec![setup, build], Some(start));
Ok(Some(plan))
Expand Down Expand Up @@ -143,18 +152,69 @@ impl JavaProvider {
}
}

pub fn get_jdk_and_gradle_pkgs(&self, app: &App) -> Result<Vec<Pkg>> {
fn as_default(v: Option<Match>) -> &str {
match v {
Some(m) => m.as_str(),
None => "_",
pub fn get_jdk_and_gradle_pkgs(&self, app: &App, env: &Environment) -> Result<Vec<Pkg>> {
let gradle_version = self.get_gradle_version(app, env)?;
let jdk_version = self.get_jdk_version(app, env)?;

let pkgs = vec![
self.get_jdk_pkg(jdk_version)?,
self.get_gradle_pkg(gradle_version)?,
];
Ok(pkgs)
}

fn get_jdk_pkg(&self, jdk_version: u32) -> Result<Pkg> {
let pkg = match jdk_version {
19 => Pkg::new("jdk"),
17 => Pkg::new("jdk17"),
11 => Pkg::new("jdk11"),
8 => Pkg::new("jdk8"),
_ => bail!("Unsupported JDK version: {}", jdk_version),
};

Ok(pkg)
}

fn get_gradle_pkg(&self, gradle_version: u32) -> Result<Pkg> {
let pkg = match gradle_version {
7 => Pkg::new("gradle"),
6 => Pkg::new("gradle_6"),
5 => Pkg::new("gradle_5"),
4 => Pkg::new("gradle_4"),
_ => bail!("Unsupported Gradle version: {}", gradle_version),
};

Ok(pkg)
}

fn get_jdk_version(&self, app: &App, env: &Environment) -> Result<u32> {
// If the JDK version is manually specified, use that
if let Some(jdk_version) = env.get_config_variable("JDK_VERSION") {
return Ok(jdk_version.parse::<u32>()?);
}

if self.is_using_gradle(app) {
let gradle_version = self.get_gradle_version(app, env)?;

// Return a JDK version based on the gradle version
if gradle_version == 6 {
return Ok(11);
} else if gradle_version <= 5 {
return Ok(8);
}
}

let default_pkgs = vec![Pkg::new("jdk"), Pkg::new("gradle")];
Ok(DEFAULT_JDK_VERSION)
}

fn get_gradle_version(&self, app: &App, env: &Environment) -> Result<u32> {
// If the Gradle version is manually specified, use that
if let Some(gradle_version) = env.get_config_variable("GRADLE_VERSION") {
return Ok(gradle_version.parse::<u32>()?);
}

if !app.includes_file("gradle/wrapper/gradle-wrapper.properties") {
return Ok(default_pkgs);
return Ok(DEFAULT_GRADLE_VERSION);
}

let file_content = app.read_file("gradle/wrapper/gradle-wrapper.properties")?;
Expand All @@ -164,35 +224,97 @@ impl JavaProvider {

// If it's still none, return default
if custom_version.is_none() {
return Ok(default_pkgs);
return Ok(DEFAULT_GRADLE_VERSION);
}

let custom_version = custom_version.unwrap();
let matches = Regex::new(r#"^(?:[\sa-zA-Z-"']*)(\d*)(?:\.*)(\d*)(?:\.*\d*)(?:["']?)$"#)?
.captures(custom_version.as_str().trim());

// If no matches, just use default
if matches.is_none() {
return Ok(default_pkgs);
}
let matches = matches.unwrap();
let parsed_version = as_default(matches.get(1));
let parsed_version = match matches {
Some(m) => match m.get(1) {
Some(v) => v.as_str(),
None => return Ok(DEFAULT_GRADLE_VERSION),
},
None => return Ok(DEFAULT_GRADLE_VERSION),
};

if parsed_version == "_" {
return Ok(default_pkgs);
}
let int_version = parsed_version.parse::<u32>().unwrap_or_default();
Ok(int_version)
}
}

let int_version = parsed_version.parse::<i32>().unwrap_or_default();
let pkgs = if int_version == 6 {
vec![Pkg::new("jdk11"), Pkg::new("gradle_6")]
} else if int_version == 5 {
vec![Pkg::new("jdk8"), Pkg::new("gradle_5")]
} else if int_version < 5 {
vec![Pkg::new("jdk8"), Pkg::new("gradle_4")]
} else {
default_pkgs
};
#[cfg(test)]
mod tests {
use super::*;

Ok(pkgs)
#[test]
fn test_get_jdk_pkg() {
let java = JavaProvider {};

assert_eq!(
Pkg::new("jdk17"),
java.get_jdk_pkg(
java.get_jdk_version(
&App::new("examples/java-gradle-hello-world").unwrap(),
&Environment::from_envs(vec![]).unwrap(),
)
.unwrap()
)
.unwrap()
);

assert_eq!(
Pkg::new("jdk8"),
java.get_jdk_pkg(
java.get_jdk_version(
&App::new("examples/java-gradle-hello-world").unwrap(),
&Environment::from_envs(vec!["NIXPACKS_JDK_VERSION=8"]).unwrap(),
)
.unwrap()
)
.unwrap()
);

assert_eq!(
Pkg::new("jdk11"),
java.get_jdk_pkg(
java.get_jdk_version(
&App::new("examples/java-gradle-hello-world").unwrap(),
&Environment::from_envs(vec!["NIXPACKS_GRADLE_VERSION=6"]).unwrap(),
)
.unwrap()
)
.unwrap()
);
}

#[test]
fn test_get_gradle_pkg() {
let java = JavaProvider {};

assert_eq!(
Pkg::new("gradle"),
java.get_gradle_pkg(
java.get_gradle_version(
&App::new("examples/java-gradle-hello-world").unwrap(),
&Environment::from_envs(vec![]).unwrap(),
)
.unwrap()
)
.unwrap()
);

assert_eq!(
Pkg::new("gradle_5"),
java.get_gradle_pkg(
java.get_gradle_version(
&App::new("examples/java-gradle-hello-world").unwrap(),
&Environment::from_envs(vec!["NIXPACKS_GRADLE_VERSION=5"]).unwrap(),
)
.unwrap()
)
.unwrap()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ expression: plan
"build": {
"name": "build",
"dependsOn": [
"install",
"setup"
],
"cmds": [
Expand All @@ -24,7 +25,7 @@ expression: plan
"setup": {
"name": "setup",
"nixPkgs": [
"jdk",
"jdk17",
"gradle"
],
"nixOverlays": [],
Expand Down
3 changes: 2 additions & 1 deletion tests/snapshots/generate_plan_tests__java_maven.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ expression: plan
"build": {
"name": "build",
"dependsOn": [
"install",
"setup"
],
"cmds": [
Expand All @@ -24,7 +25,7 @@ expression: plan
"setup": {
"name": "setup",
"nixPkgs": [
"jdk",
"jdk17",
"maven"
],
"nixOverlays": [],
Expand Down
3 changes: 2 additions & 1 deletion tests/snapshots/generate_plan_tests__java_maven_wrapper.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ expression: plan
"build": {
"name": "build",
"dependsOn": [
"install",
"setup"
],
"cmds": [
Expand All @@ -24,7 +25,7 @@ expression: plan
"setup": {
"name": "setup",
"nixPkgs": [
"jdk",
"jdk17",
"maven"
],
"nixOverlays": [],
Expand Down
Loading

0 comments on commit 8ad1ec5

Please sign in to comment.