avelino / avelino/jbundle

Embedded packaging configuration in JAR (META-INF)

Open
#19 0 comments 1 reaction 0 assignees View on GitHub
area/config area/pack
Dominant language
Rust
Stars
181
Forks
11
PR merge metrics
No merged PRs in 30d

Description

## Problem

Libraries that require specific Java modules at runtime have no way to declare this requirement. When a user packages an application that depends on such a library, jdeps may fail to detect the needed modules (due to reflection/dynamic loading), causing runtime failures. The burden falls entirely on the end user to discover and configure the correct modules.

## Inspiration

GraalVM's native-image supports [build configuration embedded in JAR files](https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildConfiguration/) via `META-INF/native-image/`. Libraries ship their reflection/resource/JNI configuration inside the JAR, and the native-image builder automatically discovers and merges all configurations from the classpath.

This means library authors solve the configuration problem once, and all users benefit automatically. Example:
```
my-library.jar
└── META-INF/
└── native-image/
└── com.example/my-library/
├── native-image.properties
├── reflect-config.json
└── resource-config.json
```

## Expected Outcome

jbundle should support a `META-INF/jbundle/` directory convention inside JARs:

### Library-Side Configuration

A library author adds to their JAR:
```
META-INF/jbundle/{group-id}/{artifact-id}/jbundle.edn
```

Example content:
```edn
{:required-modules ["java.sql" "java.naming"]
:min-java-version 17
:resources-needed ["db/migrations/*.sql"]
:shrink-exclude ["com/example/generated/**"]}
```

### jbundle Behavior

1. During the build, scan all JARs on the classpath (inside the uberjar) for `META-INF/jbundle/` entries
2. Merge all discovered configurations:
- Union of `:required-modules` → feeds into jlink
- Maximum of `:min-java-version` → validates JDK selection
- Union of `:resources-needed` → protects from shrink removal
- Union of `:shrink-exclude` → protects from aggressive shrink
3. User's `.jbundle.edn` and CLI flags override/extend merged config

### Precedence (lowest to highest)

1. `META-INF/jbundle/` from dependencies (auto-discovered)
2. `.jbundle.edn` in project root (#9)
3. CLI flags

### Benefits

- **Library authors** declare requirements once, saving every user from debugging
- **Application developers** get correct module detection without manual configuration
- **Ecosystem**: as adoption grows, the "jdeps misses reflection" problem diminishes
- **Backwards compatible**: JARs with `META-INF/jbundle/` work fine with other tools (extra files are ignored)

## Real-World Examples

Libraries that would benefit from declaring their requirements:
- **next.jdbc / clojure.java.jdbc**: needs `java.sql`, `java.naming`
- **ring-jetty / http-kit**: needs `jdk.crypto.ec` for HTTPS
- **clojure.data.xml**: needs `java.xml`
- **buddy-sign (JWT)**: needs `java.security.jgss`, `jdk.crypto.ec`
- **amazonica / cognitect.aws**: needs `java.xml`, `java.naming`, `java.management`

## Ecosystem Adoption Path

1. jbundle documents the `META-INF/jbundle/` convention
2. jbundle ships a built-in "known modules" database for popular libraries (temporary bridge)
3. Library maintainers add the metadata to their JARs over time
4. Built-in database becomes less necessary as ecosystem adopts the convention

Contributor guide

Open the contributing guide

Research direction

Start by reading the proposed META-INF/jbundle/{group-id}/{artifact-id}/jbundle.edn format alongside the project-root .jbundle.edn and CLI precedence described here. Trace the build step that feeds jlink, then define how dependency JAR entries are discovered and merged. Done means all four configuration categories are merged with the stated precedence and the JDK version is validated.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, rust
Domain
build-system, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.