You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* x86 Linux (but the few binary dependencies could easily be changed for aarch64)
24
-
* Docker installed and running. It should work fine with[podman](https://podman.io/) but it has not been tested.
25
-
*[GraalVM for JDK 21](https://www.graalvm.org/downloads/)
24
+
* Docker installed and running. It should work fine with
25
+
[podman](https://podman.io/) but it has not been tested.
26
26
27
-
> We recommend Oracle GraalVM for the best experience. It is licensed under the [GraalVM Free Terms and Conditions (GFTC)](https://www.oracle.com/downloads/licenses/graal-free-license.html) license, which permits use by any user including commercial and production use.
28
-
GraalVM Community Edition for JDK 21 works too, but Native Image generated executables sizes will differ.
29
-
30
-
> These instructions have only been tested on Linux x64.
27
+
> NOTE: These instructions have only been tested on Linux x64.
31
28
32
29
## Setup
33
30
34
-
You need the following zlib packages installed:
35
-
* zlib.x86_64
36
-
* zlib-devel.x86_64
37
-
* zlib-static.x86_64
38
-
39
-
On Oracle Linux, you can install with:
40
-
```sh
41
-
sudo yum install -y zlib.x86_64
42
-
sudo yum install -y zlib-devel.x86_64
43
-
sudo yum install -y zlib-static.x86_64
44
-
```
45
-
46
-
Clone this Git repo and in your Linux shell type the following to download and
47
-
configure the `musl` toolchain.
48
-
49
-
`./setup-musl.sh`
50
-
51
-
Download [upx](https://upx.github.io/):
52
-
53
-
`./setup-upx.sh`
31
+
Clone this Git repo. Everything runs in Docker so no need to install anything
32
+
on your machine.
54
33
55
34
## Hello World
56
35
57
-
With the `musl` toolchain installed, cd in to the `helloworld` folder.
36
+
Let's start with a simple Hello World example.
58
37
59
-
`cd helloworld`
38
+
Change the directory to `helloworld`.
60
39
61
-
Using the `build.sh` script, compile a simple single Java class Hello World
62
-
application with `javac`, compile the generated .class file into a fully
63
-
statically linked native Linux executable named `hello`, compress the executable
64
-
with [upx](https://upx.github.io/) to create the executable `hello.upx`, and
65
-
package the compressed static `hello.upx` executable into a `scratch`
66
-
Docker container image:
40
+
`cd helloworld`
67
41
68
-
`./build.sh`
42
+
Use the `build.sh` script to run a Docker build that:
43
+
1. compiles a simple single Java class Hello World application with `javac`
44
+
2. compiles the generated .class file with GraalVM Native Image into a fully
45
+
statically linked native Linux executable named `hello`
46
+
3. compresses the executable with [upx](https://upx.github.io/) to create the
47
+
executable `hello.upx`
48
+
4. packages the compressed static `hello.upx` executable into a `scratch` Docker
49
+
container image
69
50
70
-
You'll see two executables were built:
51
+
In a terminal, run:
71
52
72
-
`ls -lh hello*`
53
+
`./build.sh`
73
54
74
55
### Native Executables
75
56
76
-
Running either of the `hello` executables you can see they are functionally
77
-
equivalent. They just print "Hello World". But there are a few points worth
78
-
noting:
79
-
80
-
1. The executable generated by GraalVM Native Image using the
81
-
`--static --libc=musl` options is a fully self-contained executable which can be
82
-
confirmed by examining it with `ldd`:
83
-
84
-
`ldd hello`
85
-
86
-
should result in:
87
-
88
-
```shell
89
-
not a dynamic executable
90
-
```
91
-
92
-
This means that it does not rely on any libraries in the host operating system
93
-
environment making it easier to package in a variety of Docker container images.
94
-
95
-
Unfortunately `upx` compression renders `ldd` unable to list the shared
96
-
libraries of an executable, but since you compressed the statically linked
97
-
executable, you can be confident it is also statically linked.
98
-
99
-
2. Both executables are the result of compiling a Java bytecode application into
100
-
native machine code. The uncompressed executable is only ~6.3MB! There's no
101
-
JVM, no JARs, no JIT compiler and none of the overhead it imposes. Both
102
-
start extremely fast as there is minimal startup cost.
103
-
104
-
3. The `upx` compressed executable is over 70% smaller, 1.7MB vs. 6.3MB! With
105
-
`upx` the application self-extracts quickly but does incur a cost of about
106
-
100ms for decompression. See this blog for a deep dive on [GraalVM Native
107
-
Image and
57
+
1. The `hello` executable generated by GraalVM Native Image in the Dockerfile
58
+
using the `--static --libc=musl` options is a fully self-contained
59
+
executable. This means that it does not rely on any libraries in the host
60
+
operating system environment. This makes it easier to package in a variety of
61
+
container images.
62
+
63
+
2. You can see in the output of the Dockerfile build that `ls -lh` reports the
64
+
`hello` executable is ~4.9MB. There's no JVM, no JARs, no JIT compiler and
65
+
none of the overhead it imposes. It starts extremely fast as there is minimal
66
+
startup cost.
67
+
68
+
3. The `upx` compressed `hello.upx` executable is over 70% smaller, 1.3MB vs.
69
+
4.9MB! A `upx` compressed application self-extracts quickly but does incur a
70
+
cost of about 100ms for decompression. See this blog for a deep dive on
0 commit comments