A Leiningen plugin for generating GraalVM native images from your project.
The lein native-image command compiles your project then uses GraalVM's native-image to build a native image.
:main namespace w/entrypoint and support AOT compilation.
Here's an example:
(defproject my-app "0.1.0"
:dependencies [[org.clojure/clojure "1.9.0"]]
:plugins [[io.taylorwood/lein-native-image "0.2.0"]]
:native-image {:graal-bin "/path/to/graalvm-1.0.0-rc1/Contents/Home/bin"
:name "my-app"}
:main ^:skip-aot my-app.core
:profiles {:dev {:dependencies [[org.clojure/test.check "0.9.0"]]}
:test ;; e.g. lein with-profile +test native-image
{:native-image {:opts ["-H:+ReportUnsupportedElementsAtRuntime"
"--verbose"]}}
:uberjar {:aot :all
:native-image {:opts ["-Dclojure.compiler.direct-linking=true"]}}})
See the examples directory for apps that can be compiled to native images with GraalVM.
Put [io.taylorwood/lein-native-image "0.2.0"] into the :plugins vector of your project.clj, or in your Leiningen user profile.
Optionally specify a custom image name, path to GraalVM's bin directory or native-image path, or native-image CLI options in your project.clj:
(defproject my-app "0.1.0"
:native-image {:name "my-app"
:graal-bin "/path/to/graalvm-1.0.0-rc1/bin"
:opts ["--verbose"]})
:name is an optional name for the generated native image.:graal-bin path can be specified as a string or resolved from an environment variable using a keyword e.g. :env/GRAALVM_HOME.
If :graal-bin is unspecified, the GRAALVM_HOME environment variable will be used by default.:opts is an optional vector of arguments to native-image; see its documentation for more.The plugin will merge the task-specific profile :native-image, or :uberjar if that doesn't exist.
You can also specify these in your Leiningen user profile ~/.lein/profiles.clj:
{:user {:plugins [[io.taylorwood/lein-native-image "0.2.0"]]
:native-image {:graal-bin "/path/to/graalvm-1.0.0-rc1/Contents/Home/bin"}}}
Build a native image from your project:
➜ lein native-image
Compiling my-app.core
Build on Server(pid: 36212, port: 26681)
classlist: 332.89 ms
(cap): 1,289.90 ms
8<----------------------
write: 932.61 ms
[total]: 11,789.08 ms
Created native image /Users/Taylor/Projects/my-app/target/my-app
Execute the native image:
➜ ./target/my-app with optional args
Hello, World!
GraalVM and Substrate VM's support for AOT compilation and native images is evolving. There are limitations and unsupported features you will likely encounter. This release was tested with GraalVM 1.0.0-RC1 EE; some of these notes may not apply to future releases. At least one AOT issue has been fixed since 1.0.0-RC1, but you must build Substrate VM locally to get unreleased fixes.
When the :opts ["-H:+ReportUnsupportedElementsAtRuntime"] flag is set, some native-image build issues will be deferred as runtime exceptions.
To avoid spurious runtime errors, don't use this flag for "production" builds.
You may need to specify :opts ["-H:EnableURLProtocols=http"] to use HTTP libraries.
HTTPS is currently in development and unsupported!
Specifying :jvm-opts ["-Dclojure.compiler.direct-linking=true"] might allow for better optimizations by GraalVM.
This plugin doesn't shutdown GraalVM native-image build servers after builds, so that subsequent builds are slightly faster.
You can specify :opts ["--no-server"] to not spawn a build server at all, or use other native-image commands to manage build server(s).
GraalVM Native Image AOT Compilation
Instant Netty Startup using GraalVM (and source)
You'll need Leiningen and GraalVM installed to build and test the plugin.
Issues, PRs, and suggestions are welcome!
Copyright © 2018 Taylor Wood.
Distributed under the MIT License.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |