Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Produce a native image using GraalVM #1344

Open
ggrossetie opened this issue Mar 19, 2023 · 6 comments
Open

Produce a native image using GraalVM #1344

ggrossetie opened this issue Mar 19, 2023 · 6 comments
Assignees
Labels
enhancement New feature or request t:discussion Can be converted to a discussion t:docker issue to move to docker repository

Comments

@ggrossetie
Copy link
Contributor

Is your feature request related to a problem? Please describe.
I would like to use PlantUML CLI as a native image:

$ echo 'Alice->Bob: Hello' | ./plantuml -tpng -pipe > diagram.png

Describe the solution you'd like
I was able to produce a native image using GraalVM on Ubuntu:

$ /path/to/graalvm-ce-java17-22.3.1/bin/native-image -H:ConfigurationFileDirectories=./native-image-config-dir --no-fallback --report-unsupported-elements-at-runtime -jar plantuml-1.2023.4.jar
========================================================================================================================
GraalVM Native Image: Generating 'plantuml-1.2023.4' (executable)...
========================================================================================================================
[1/7] Initializing...                                                                                    (2,5s @ 0,22GB)
 Version info: 'GraalVM 22.3.1 Java 17 CE'
 Java version info: '17.0.6+10-jvmci-22.3-b13'
 C compiler: gcc (linux, x86_64, 11.3.0)
 Garbage collector: Serial GC
[2/7] Performing analysis...  [******]                                                                  (12,1s @ 3,33GB)
  11 171 (88,31%) of 12 650 classes reachable
  21 887 (67,71%) of 32 323 fields reachable
  58 772 (61,05%) of 96 267 methods reachable
     200 classes,    96 fields, and 1 098 methods registered for reflection
     129 classes,   200 fields, and   115 methods registered for JNI access
       7 native libraries: dl, freetype, m, pthread, rt, stdc++, z
[3/7] Building universe...                                                                               (1,3s @ 3,25GB)
[4/7] Parsing methods...      [*]                                                                        (1,0s @ 2,32GB)
[5/7] Inlining methods...     [***]                                                                      (0,7s @ 2,75GB)
[6/7] Compiling methods...    [***]                                                                     (10,5s @ 3,33GB)
[7/7] Creating image...                                                                                  (1,8s @ 1,87GB)
  31,77MB (50,30%) for code area:    37 017 compilation units
  26,68MB (42,24%) for image heap:  292 532 objects and 109 resources
   4,72MB ( 7,47%) for other data
  63,17MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 packages in code area:                               Top 10 object types in image heap:
 953,14KB java.util                                            6,70MB byte[] for code metadata
 796,22KB sun.font                                             3,09MB java.lang.String
 778,06KB gen.lib.dotgen                                       2,68MB java.lang.Class
 683,21KB java.awt                                             2,39MB byte[] for general heap data
 561,52KB gen.lib.common                                       2,17MB byte[] for java.lang.String
 526,17KB java.lang.invoke                                     1,03MB byte[] for embedded resources
 495,03KB javax.swing                                       1017,65KB int[]
 466,31KB c.s.org.apache.xerces.internal.impl.xs.traversers  960,01KB com.oracle.svm.core.hub.DynamicHubCompanion
 464,52KB sun.awt.X11                                        632,55KB java.lang.String[]
 464,49KB java.lang                                          552,14KB java.util.HashMap$Node
  25,46MB for 467 more packages                                5,20MB for 1788 more object types
------------------------------------------------------------------------------------------------------------------------
                        2,1s (6,5% of total time) in 37 GCs | Peak RSS: 7,68GB | CPU load: 11,03
------------------------------------------------------------------------------------------------------------------------
Produced artifacts:
 /path/to/plantuml-1.2023.4 (executable)
 /path/to/plantuml-1.2023.4.build_artifacts.txt (txt)
========================================================================================================================
Finished generating 'plantuml-1.2023.4' in 32,4s.

We need to specify a configure directory since PlantUML relies on java.awt.image/JNI.
The configuration can be generated using the following command:

$ mkdir native-image-config-dir
$ echo 'Bob->Alice: Hello' | /path/to/graalvm-ce-java17-22.3.1/bin/java -agentlib:native-image-agent=config-output-dir=./native-image-config-dir -jar plantuml-1.2023.4.jar -tpng -pipe > out.png

It will run PlantUML with an agent which will record every calls and produce several configuration files in the native-image-config-dir directory.

I can build the native image on my side but I think it would be great to publish it as part of the release process.

Keep in mind that (currently) it only works for CLI (i.e., the GUI won't show):

$ ./plantuml-1.2023.4
There is an issue with your server. You will find some tips here:
https://forum.plantuml.net/3399/problem-with-x11-and-headless-exception
https://plantuml.com/en/faq#239d64f675c3e515
Exception in thread "main" java.awt.HeadlessException
	at java.desktop@17.0.6/java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:166)
	at java.desktop@17.0.6/java.awt.Window.<init>(Window.java:553)
	at java.desktop@17.0.6/java.awt.Frame.<init>(Frame.java:428)
	at java.desktop@17.0.6/javax.swing.JFrame.<init>(JFrame.java:224)
	at net.sourceforge.plantuml.swing.MainWindow.<init>(MainWindow.java:159)
	at net.sourceforge.plantuml.Run.main(Run.java:178)

It might be possible to make it work but since I'm only interested in the CLI... 😄

Additional context
I can prepare a GitHub Action to demonstrate how to build the native image from a jar file.

@ggrossetie
Copy link
Contributor Author

java

$ time echo "Alice->Bob: Hello" | java -jar plantuml-1.2023.4.jar -tpng -pipe > native.png && open native.png

real  0m0,388s
user  0m1,073s
sys   0m0,076s

java

native

$ time echo "Alice->Bob: Hello" | ./plantuml-1.2023.4 -tpng -pipe > native.png && open native.png

real  0m0,060s
user  0m0,034s
sys   0m0,029s

native

@arnaudroques arnaudroques added the t:discussion Can be converted to a discussion label Mar 19, 2023
@evantill
Copy link
Collaborator

Nice work thank you.

I was thinking of it.
Maybe we can create a docker image and use it in a github workflow ?

@evantill evantill added enhancement New feature or request t:docker issue to move to docker repository and removed triage labels Mar 19, 2023
@ggrossetie
Copy link
Contributor Author

Maybe we can create a docker image and use it in a github workflow ?

I don't think we need a Docker image but I can open a pull request with a GitHub Action running on ubuntu-latest.

@arnaudroques
Copy link
Contributor

Additional context
I can prepare a GitHub Action to demonstrate how to build the native image from a jar file.

Yes, that would be great.
And we could also integrate this in our main CI/CD so that we also release this native image.

@evantill
Copy link
Collaborator

evantill commented Mar 19, 2023

The docker image would help us during development on our computers. Some of us are on Windows, other on macos...
And this image could be reused in the github workflow.

We have just started a new repository for every thing related to docker image creation https://github.com/plantuml/docker

@evantill
Copy link
Collaborator

@ggrossetie you can go on the PR for the github workflow and we will see later on the docker image stuff
I will create an other issue for the docker related stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request t:discussion Can be converted to a discussion t:docker issue to move to docker repository
Projects
None yet
Development

No branches or pull requests

3 participants