micronaut-maven-plugin
micronaut-maven-plugin copied to clipboard
POC - JAR of JARs
This PR contains a POC that fixes #104:
- Converts the project into a multi-module Maven build.
- Provides a new
io.micronaut.build:micronaut-entrypoint
artifact with a single class (io.micronaut.build.entrypoint.Entrypoint
) that is meant to be theMain-Class
of the runnable jars.- The class loader used is a
URLClassLoader
that loads dependencies (included in the JAR'slibs/
folder) by copying them to the local file system first, since nested JAR URLs aren't supported byURLClassLoader
. Ideally, this should be replaced by a custom class loader that is able to read nested JAR URLs.
- The class loader used is a
- Includes a
micronaut-entrypoint-test
test application, coming from a vanillamn create-cli-app
, with the following changes to its POM:- Copies dependencies to
classes/libs
so that they end up being inside the JAR. - Unpacks
micronaut-entrypoint
in theclasses
directory, since it needs to be exploded to be the JAR's main class. - Configure the generated JAR's manifest:
-
Class-Path
entry contains all the dependencies in the formatlibs/foo-1.2.3.jar
. -
Main-Class
is fixed toio.micronaut.build.entrypoint.Entrypoint
. -
Micronaut-Entrypoint
points to the actual main class (io.micronaut.build.entrypoint.test.MainCommand
in this case).
-
- Ideally, a MOJO should be provided to perform these tasks, so that the user POMs are cleaner.
- Copies dependencies to
The generated JAR looks like:
.
├── META-INF
│ ├── MANIFEST.MF
│ ├── maven
│ │ └── ...
│ └── native-image
│ └── ...
├── application.yml
├── io
│ └── micronaut
│ └── build
│ └── entrypoint
│ ├── Entrypoint.class // Unpacked
│ └── test
│ └── MainCommand.class. // The actual main class
├── libs
│ ├── apiguardian-api-1.1.0.jar
│ ├── jackson-annotations-2.11.2.jar
│ ├── jackson-core-2.11.2.jar
│ ├── jackson-databind-2.11.2.jar
│ ├── jackson-datatype-jdk8-2.11.2.jar
│ ├── jackson-datatype-jsr310-2.11.2.jar
│ ├── javax.annotation-api-1.3.2.jar
│ ├── javax.inject-1.jar
│ ├── jsr305-3.0.2.jar
│ ├── junit-jupiter-api-5.7.0.jar
│ ├── junit-jupiter-engine-5.7.0.jar
│ ├── junit-platform-commons-1.7.0.jar
│ ├── junit-platform-engine-1.7.0.jar
│ ├── logback-classic-1.2.3.jar
│ ├── logback-core-1.2.3.jar
│ ├── micronaut-aop-2.3.3.jar
│ ├── micronaut-buffer-netty-2.3.3.jar
│ ├── micronaut-core-2.3.3.jar
│ ├── micronaut-http-2.3.3.jar
│ ├── micronaut-http-client-2.3.3.jar
│ ├── micronaut-http-client-core-2.3.3.jar
│ ├── micronaut-http-netty-2.3.3.jar
│ ├── micronaut-inject-2.3.3.jar
│ ├── micronaut-picocli-3.2.0.jar
│ ├── micronaut-runtime-2.3.3.jar
│ ├── micronaut-test-core-2.3.2.jar
│ ├── micronaut-test-junit5-2.3.2.jar
│ ├── micronaut-validation-2.3.3.jar
│ ├── micronaut-websocket-2.3.3.jar
│ ├── netty-buffer-4.1.59.Final.jar
│ ├── netty-codec-4.1.59.Final.jar
│ ├── netty-codec-http-4.1.59.Final.jar
│ ├── netty-codec-http2-4.1.59.Final.jar
│ ├── netty-codec-socks-4.1.59.Final.jar
│ ├── netty-common-4.1.59.Final.jar
│ ├── netty-handler-4.1.59.Final.jar
│ ├── netty-handler-proxy-4.1.59.Final.jar
│ ├── netty-resolver-4.1.59.Final.jar
│ ├── netty-transport-4.1.59.Final.jar
│ ├── opentest4j-1.2.0.jar
│ ├── picocli-4.6.1.jar
│ ├── reactive-streams-1.0.3.jar
│ ├── rxjava-2.2.10.jar
│ ├── slf4j-api-1.7.26.jar
│ ├── snakeyaml-1.26.jar
│ ├── spotbugs-annotations-4.0.3.jar
│ └── validation-api-2.0.1.Final.jar
└── logback.xml
Spring's "repackage" goal (in the Spring Boot Maven Plugin), does something similar to this, but as you mentioned above, removes the need for unpack the jar first. https://github.com/spring-projects/spring-boot/tree/v2.5.2/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader
The actual "spring" dependencies on that project are minimal (if any at all, the last I looked)
The resulting package ends up looking like this:
.
├── META-INF
│ ├── MANIFEST.MF
│ ├── ...
│
├── BOOT-INF
│ ├── classes
│ │ ├── META-INF
│ │ │ └── rest-dice-parser.kotlin_module
│ │ ├── application.properties
│ │ └── com
│ │ └── example
│ │ └── app
│ │ ├── MyCode.class
│ │ ├── ...
│ └── lib
│ ├── my-deps-1.2.3.jar
│ ├── ...
|
└── org
└── springframework
└── boot
└── loader
├── ClassloaderRelatedBits.class
├── ...
I've been using this even on non-Spring projects just to avoid using the Shade plugin.
@bdemers thanks, this was just a POC I did right before leaving the Micronaut team.
Going forward, @melix and @graemerocher should be able to decide in which direction they want to move.
Can we take inspiration or borrow something from One Jar? The project seems to be dead but works in general. Will be very useful in this case.
FYI, we don't have plans to spend time on this in the short term, the interest by the community seems low.
SonarCloud Quality Gate failed.
3 Bugs
0 Vulnerabilities
2 Security Hotspots
86 Code Smells
No Coverage information
0.0% Duplication