Skip to content

Commit 0b5aaca

Browse files
4.2.7 packaging example (#207)
* Add packaging example (#195) --------- Co-authored-by: Romain Grecourt <[email protected]> * Fix typo * Fix version in pom.xml * Force upgrade Hibernate to work with Java 26 --------- Co-authored-by: Romain Grecourt <[email protected]>
1 parent 84db11b commit 0b5aaca

File tree

16 files changed

+819
-0
lines changed

16 files changed

+819
-0
lines changed

examples/integrations/cdi/pokemons/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
<version>1.0.0-SNAPSHOT</version>
3333
<name>Helidon Examples CDI Extensions Pokemons JPA</name>
3434

35+
<properties>
36+
<version.lib.hibernate>6.6.23.Final</version.lib.hibernate>
37+
</properties>
38+
3539
<dependencies>
3640
<!-- Compile-scoped dependencies. -->
3741
<dependency>

examples/packaging/README.md

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
2+
# Helidon Application Packaging Example
3+
4+
Helidon supports three packaging options for your application:
5+
6+
1. Thin Jar (the default)
7+
2. JLink Custom Image
8+
3. Native Image
9+
10+
It is also possible to package your Helidon application as a fat jar (although this is not recommended).
11+
12+
This examples shows how to build and run a Helidon application using these packaging options.
13+
It also shows how to build a file distribution for each of the formats.
14+
15+
## Build and Run
16+
17+
```shell
18+
mvn package
19+
java -jar target/helidon-examples-packaging.jar
20+
```
21+
## Exercise the application
22+
23+
```shell
24+
curl -X GET http://localhost:8080/simple-greet
25+
Hello World!
26+
```
27+
28+
## Thin Jar
29+
30+
The default packaging for a Helidon application is the thin jar. In the above Build and Run
31+
step you used a thin jar. In this packaging:
32+
33+
1. Your application code, and only your application code, is in the application jar (`target/helidon-examples-packaging.jar`).
34+
2. The application's runtime dependencies are in the `target/libs` directory.
35+
3. The application jar has entries in `META-INF/MANIFEST.MF` that specify:
36+
- The application's Main-Class
37+
- The Class-Path to use when running the application
38+
39+
To see how this looks in the `MANIFEST.MF` file, run:
40+
41+
```shell
42+
unzip -p target/helidon-examples-packaging.jar META-INF/MANIFEST.MF
43+
```
44+
45+
You'll see the `Class-Path` entry contains all jar files that are in the `libs` directory.
46+
47+
#### Thin Zip Distribution
48+
49+
To create a zip file of your thin jar application you can use zip:
50+
51+
```shell
52+
(cd target; zip -r helidon-examples-packaging-thin.zip helidon-examples-packaging.jar libs/)
53+
```
54+
55+
You can now copy this zip elsewhere and "install" and run it:
56+
57+
```shell
58+
unzip helidon-examples-packaging.zip
59+
java -jar helidon-examples-packaging.jar
60+
```
61+
62+
As an alternative to the `zip` command this example also demonstrates how to use the
63+
`maven-assembly-plugin` to create the distribution zip. This uses:
64+
65+
1. The `thin-zip` profile in the [pom.xml](./pom.xml) to configure the plugin.
66+
2. The assembly descriptor in [thin-assembly.xml](./src/main/assembly/thin-assembly.xml)
67+
68+
To generate the zip using the `maven-assembly-plugin`:
69+
70+
```shell
71+
mvn package -Pthin-zip
72+
```
73+
This will create `target/appplication-se-thin.zip` just like we did with the `zip` command.
74+
75+
## Jlink Image
76+
77+
The Jlink image creates a custom Java runtime image that is bundled with your application.
78+
This custom runtime image contains only the JDK modules your application requires. It also
79+
(by default) creates a CDS archive to speed up application launching.
80+
81+
To build and run:
82+
83+
```shell
84+
mvn package -Pjlink-image
85+
target/helidon-examples-packaging-jri/bin/start
86+
```
87+
88+
If you look in `target/helidon-examples-packaging-jri` you will see:
89+
90+
1. `app`: this contains your application jar and dependencies, just like the thin jar case.
91+
2. `bin`: this contains the start script for your application plus some JDK commands.
92+
3. `lib/start.jsa`: this is a CDS archive for your application. It makes starting it a bit faster.
93+
4. The rest of the files are the JDK files needed to run your application.
94+
95+
### JLink Zip Distribution
96+
97+
To create a zip file of your jlink application you can use zip:
98+
99+
```shell
100+
(cd target; zip -r helidon-examples-packaging-jlink.zip helidon-examples-packaging-jri )
101+
```
102+
103+
You can now copy this zip elsewhere and "install" and run it:
104+
105+
```shell
106+
unzip helidon-examples-packaging-jlink.zip
107+
helidon-examples-packaging-jri/bin/start
108+
```
109+
110+
As an alternative to the `zip` command this example demonstrates how to use the
111+
`maven-assembly-plugin` to create the distribution zip. This uses:
112+
113+
1. The `jlink-zip` profile in the [pom.xml](./pom.xml) to configure the plugin.
114+
2. The assembly descriptor in [jlink-assembly.xml](./src/main/assembly/jlink-assembly.xml)
115+
116+
To generate the zip using the `maven-assembly-plugin`:
117+
118+
```shell
119+
# This assume you previously built the image with -Pjlink-image
120+
mvn package -Pjlink-zip
121+
```
122+
This will create `target/appplication-se-jlink.zip` just like we did with the `zip` command.
123+
124+
## Native Image
125+
126+
Native image creates a native executable of your Java application. You will need
127+
Oracle GraalVM 21 installed on your system and set `GRAALVM_HOME` to point to your
128+
installation. You can verify it by doing `${GRAALVM_HOME}/bin/native-image --version`.
129+
130+
To build and run:
131+
132+
```shell
133+
mvn package -Pnative-image
134+
target/helidon-examples-packaging
135+
```
136+
137+
Your application is a native executable. You can see that by running:
138+
139+
```shell
140+
file target/helidon-examples-packaging
141+
```
142+
143+
### Native image Distribution
144+
145+
Your application is a single executable file so no distribution archive is required.
146+
147+
## Fat Jar
148+
149+
Fat jars are application jars that contain your application code plus all of its runtime dependencies.
150+
Fat jars are not recommended because they require either merging of jar files (the basic
151+
form of a fat jar) or a special class loader to handle the uber jar variant (which is a jar of jars).
152+
Both of these add complexity.
153+
154+
Flattening of jars is also problematic because it can significantly alter the behavior
155+
of your program in non-obvious ways. For example in an MP application if
156+
bean-discovery-mode="all" is used, all classes from all jars would be
157+
discovered as beans.
158+
159+
That said, it is possible to create a fat Jar for your Helidon application.
160+
161+
#### Fat Jar Distribution
162+
163+
This example uses the `maven-assembly-plugin` with the `helidon-assembly-extension` to create a fat jar.
164+
Specifically see:
165+
166+
1. The `fat-jar` profile in the [pom.xml](./pom.xml) to configure the plugin.
167+
2. The assembly descriptor in [fat-assembly.xml](./src/main/assembly/fat-assembly.xml).
168+
169+
Note that the plugin and descriptor use the `helidon-assembly-extension` which handles merging
170+
of Helidon json metadata that resides in Helidon jar files.
171+
172+
To generate the fat jar:
173+
174+
```shell
175+
mvn package -Pfat-jar
176+
```
177+
178+
This will create `target/helidon-examples-packaging-fat.jar` which can be run with:
179+
180+
```shell
181+
java -jar target/helidon-examples-packaging-fat.jar
182+
```

examples/packaging/pom.xml

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright (c) 2025 Oracle and/or its affiliates.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<project xmlns="http://maven.apache.org/POM/4.0.0"
18+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>io.helidon.applications</groupId>
23+
<artifactId>helidon-se</artifactId>
24+
<version>4.2.6-SNAPSHOT</version>
25+
<relativePath/>
26+
</parent>
27+
<groupId>io.helidon.examples.packaging</groupId>
28+
<artifactId>helidon-examples-packaging</artifactId>
29+
<version>1.0-SNAPSHOT</version>
30+
31+
<properties>
32+
<mainClass>io.helidon.examples.packaging.Main</mainClass>
33+
<helidon.build-tools.version>4.0.20</helidon.build-tools.version>
34+
</properties>
35+
36+
<dependencies>
37+
<dependency>
38+
<groupId>io.helidon.webserver</groupId>
39+
<artifactId>helidon-webserver</artifactId>
40+
</dependency>
41+
<dependency>
42+
<groupId>io.helidon.config</groupId>
43+
<artifactId>helidon-config-yaml</artifactId>
44+
</dependency>
45+
<dependency>
46+
<groupId>io.helidon.logging</groupId>
47+
<artifactId>helidon-logging-jul</artifactId>
48+
<scope>runtime</scope>
49+
</dependency>
50+
<dependency>
51+
<groupId>io.helidon.webclient</groupId>
52+
<artifactId>helidon-webclient</artifactId>
53+
<scope>test</scope>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.junit.jupiter</groupId>
57+
<artifactId>junit-jupiter-api</artifactId>
58+
<scope>test</scope>
59+
</dependency>
60+
<dependency>
61+
<groupId>org.hamcrest</groupId>
62+
<artifactId>hamcrest-all</artifactId>
63+
<scope>test</scope>
64+
</dependency>
65+
<dependency>
66+
<groupId>io.helidon.webserver.testing.junit5</groupId>
67+
<artifactId>helidon-webserver-testing-junit5</artifactId>
68+
<scope>test</scope>
69+
</dependency>
70+
</dependencies>
71+
72+
<build>
73+
<plugins>
74+
<plugin>
75+
<groupId>org.apache.maven.plugins</groupId>
76+
<artifactId>maven-dependency-plugin</artifactId>
77+
<executions>
78+
<execution>
79+
<id>copy-libs</id>
80+
</execution>
81+
</executions>
82+
</plugin>
83+
</plugins>
84+
</build>
85+
86+
<profiles>
87+
<profile>
88+
<id>fat-jar</id>
89+
<build>
90+
<plugins>
91+
<plugin>
92+
<groupId>org.apache.maven.plugins</groupId>
93+
<artifactId>maven-assembly-plugin</artifactId>
94+
<configuration>
95+
<descriptors>
96+
<descriptor>src/main/assembly/fat-assembly.xml</descriptor>
97+
</descriptors>
98+
<archive>
99+
<manifest>
100+
<mainClass>${mainClass}</mainClass>
101+
</manifest>
102+
</archive>
103+
</configuration>
104+
<executions>
105+
<execution>
106+
<phase>package</phase>
107+
<goals>
108+
<goal>single</goal>
109+
</goals>
110+
</execution>
111+
</executions>
112+
<dependencies>
113+
<dependency>
114+
<groupId>io.helidon.build-tools</groupId>
115+
<artifactId>helidon-assembly-extension</artifactId>
116+
<version>${helidon.build-tools.version}</version>
117+
</dependency>
118+
</dependencies>
119+
</plugin>
120+
</plugins>
121+
</build>
122+
</profile>
123+
124+
<profile>
125+
<id>thin-zip</id>
126+
<build>
127+
<plugins>
128+
<plugin>
129+
<groupId>org.apache.maven.plugins</groupId>
130+
<artifactId>maven-assembly-plugin</artifactId>
131+
<configuration>
132+
<descriptors>
133+
<descriptor>src/main/assembly/thin-assembly.xml</descriptor>
134+
</descriptors>
135+
</configuration>
136+
<executions>
137+
<execution>
138+
<phase>package</phase>
139+
<goals>
140+
<goal>single</goal>
141+
</goals>
142+
</execution>
143+
</executions>
144+
</plugin>
145+
</plugins>
146+
</build>
147+
</profile>
148+
149+
<profile>
150+
<id>jlink-zip</id>
151+
<build>
152+
<plugins>
153+
<plugin>
154+
<groupId>org.apache.maven.plugins</groupId>
155+
<artifactId>maven-assembly-plugin</artifactId>
156+
<configuration>
157+
<descriptors>
158+
<descriptor>src/main/assembly/jlink-assembly.xml</descriptor>
159+
</descriptors>
160+
</configuration>
161+
<executions>
162+
<execution>
163+
<phase>package</phase>
164+
<goals>
165+
<goal>single</goal>
166+
</goals>
167+
</execution>
168+
</executions>
169+
</plugin>
170+
</plugins>
171+
</build>
172+
</profile>
173+
174+
</profiles>
175+
</project>

0 commit comments

Comments
 (0)