Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ shrink = true
appcds = true
crac = false
compact_banner = false
one_time_banner = false

# Gradle multi-project options
gradle_project = "app"
Expand All @@ -39,6 +40,7 @@ All fields are optional.
| `gradle_project` | string | — | Gradle subproject to build (for multi-project) |
| `modules` | array | — | Manual module list (bypasses jdeps detection) |
| `jlink_runtime` | string | — | Path to existing jlink runtime to reuse |
| `one_time_banner` | boolean | `false` | Show the banner only on the first run |

## Precedence

Expand Down
3 changes: 2 additions & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ jbundle build [OPTIONS] --input <PATH> --output <PATH>
| `--shrink [true\|false]` | `false` | Shrink uberjar by removing non-essential files |
| `--no-appcds` | — | Disable AppCDS generation |
| `--crac` | — | Enable CRaC checkpoint (Linux only) |
| `--compact-banner` | — | Use a compact banner in the wrapper |
| `--compact-banner` | `false` | Use a compact banner in the wrapper |
| `--one-time-banner` | `false` | Show the banner only on the first run |
| `--gradle-project <NAME>` | — | Gradle subproject to build (multi-project) |
| `--all` | — | Build all application subprojects (Gradle) |
| `--modules <LIST>` | — | Manual module list, comma-separated |
Expand Down
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ pub enum Command {
/// Use a compact banner in the wrapper
#[arg(long)]
compact_banner: bool,

/// Show the banner only on the first run
#[arg(long)]
one_time_banner: bool,
},

/// Analyze a JAR or project and report size breakdown
Expand Down
1 change: 1 addition & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ pub struct BuildConfig {
pub appcds: bool,
pub crac: bool,
pub compact_banner: bool,
pub one_time_banner: bool,
/// Gradle subproject to build (for multi-project builds)
pub gradle_project: Option<String>,
/// Build all application subprojects (Gradle multi-project)
Expand Down
11 changes: 11 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ async fn main() -> Result<()> {
jlink_runtime,
verbose: _,
compact_banner,
one_time_banner,
} => {
let input_path =
std::fs::canonicalize(&input).unwrap_or_else(|_| PathBuf::from(&input));
Expand Down Expand Up @@ -141,6 +142,12 @@ async fn main() -> Result<()> {
.and_then(|c| c.compact_banner)
.unwrap_or(false);

let one_time_banner = one_time_banner
|| project_config
.as_ref()
.and_then(|c| c.one_time_banner)
.unwrap_or(false);

// Gradle subproject selection (CLI > config file)
let gradle_project = gradle_project.or_else(|| {
project_config
Expand Down Expand Up @@ -186,6 +193,7 @@ async fn main() -> Result<()> {
appcds,
crac,
compact_banner,
one_time_banner,
gradle_project,
build_all: all,
modules_override,
Expand Down Expand Up @@ -523,6 +531,8 @@ async fn run_build(config: BuildConfig) -> Result<()> {

let compact_banner = config.compact_banner;

let one_time_banner = config.one_time_banner;

// Step: Pack binary
let step = pipeline.start_step("Packing binary");
pack::create_binary(&pack::PackOptions {
Expand All @@ -535,6 +545,7 @@ async fn run_build(config: BuildConfig) -> Result<()> {
appcds: config.appcds,
java_version,
compact_banner,
one_time_banner,
})?;
let size = std::fs::metadata(&config.output)?.len();
Pipeline::finish_step(
Expand Down
2 changes: 2 additions & 0 deletions src/pack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct PackOptions<'a> {
pub appcds: bool,
pub java_version: u8,
pub compact_banner: bool,
pub one_time_banner: bool,
}

pub fn create_binary(opts: &PackOptions) -> Result<(), PackError> {
Expand Down Expand Up @@ -66,6 +67,7 @@ pub fn create_binary(opts: &PackOptions) -> Result<(), PackError> {
appcds: opts.appcds,
java_version: opts.java_version,
compact_banner: opts.compact_banner,
one_time_banner: opts.one_time_banner,
});
let stub_script = stub::finalize_stub(&stub_script);

Expand Down
17 changes: 16 additions & 1 deletion src/pack/stub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct StubParams<'a> {
pub appcds: bool,
pub java_version: u8,
pub compact_banner: bool,
pub one_time_banner: bool,
}

pub fn generate(params: &StubParams) -> String {
Expand Down Expand Up @@ -50,6 +51,18 @@ pub fn generate(params: &StubParams) -> String {
BANNER"#
};

let banner_display = if params.one_time_banner {
format!(
r#"mkdir -p "$JBUNDLE_RUNS"
if [ ! -e "$JBUNDLE_RUNS/$APP_HASH" ]; then
touch "$JBUNDLE_RUNS/$APP_HASH"
{jbundle_banner}
fi"#
)
} else {
jbundle_banner.to_string()
};

// AppCDS via AutoCreateSharedArchive (JDK 19+)
let cds_flags = if params.appcds && params.java_version >= 19 {
r#"
Expand All @@ -64,11 +77,12 @@ CDS_FLAG="-XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=$CDS_FILE""#
r#"#!/bin/sh
set -e
CACHE="${{HOME}}/.jbundle/cache"
JBUNDLE_RUNS="${{HOME}}/.jbundle/runs"
RT_HASH="{runtime_hash}" RT_SIZE={runtime_size}
APP_HASH="{app_hash}" APP_SIZE={app_size}
CRAC_SIZE={crac_size} CRAC_HASH="{crac_hash_val}"

{jbundle_banner}
{banner_display}

STUB_SIZE=__STUB_SIZE__

Expand Down Expand Up @@ -144,6 +158,7 @@ mod tests {
appcds: true,
java_version: 21,
compact_banner: false,
one_time_banner: false,
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/project_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct ProjectConfig {
pub appcds: Option<bool>,
pub crac: Option<bool>,
pub compact_banner: Option<bool>,
pub one_time_banner: Option<bool>,
/// Gradle subproject to build (for multi-project builds)
pub gradle_project: Option<String>,
/// Manual module override (bypasses jdeps detection)
Expand Down Expand Up @@ -57,6 +58,7 @@ profile = "cli"
appcds = false
crac = true
compact_banner = false
one_time_banner = false
gradle_project = "jabkit"
modules = ["java.base", "java.sql"]
jlink_runtime = "./build/jlink"
Expand All @@ -76,6 +78,7 @@ jlink_runtime = "./build/jlink"
assert_eq!(config.appcds, Some(false));
assert_eq!(config.crac, Some(true));
assert_eq!(config.compact_banner, Some(false));
assert_eq!(config.one_time_banner, Some(false));
assert_eq!(config.gradle_project.as_deref(), Some("jabkit"));
assert_eq!(
config.modules,
Expand Down
Loading