Skip to content

Commit ad53ac5

Browse files
committed
First release
1 parent b2c099d commit ad53ac5

File tree

13 files changed

+853
-1
lines changed

13 files changed

+853
-1
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
.idea
3+
*.log
4+
tmp/
5+
pom.xml.asc
6+
target
7+
.cpcache
8+
*.jar

README.md

+65-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,66 @@
11
# clojure-graalvm-agent-helper
2-
Ease native configuration generation for GraalVM NativeImage
2+
Ease native configuration generation for GraalVM NativeImage. You don't have to write configurations for native image by hand, since there is [Agent](https://medium.com/graalvm/introducing-the-tracing-agent-simplifying-graalvm-native-image-configuration-c3b56c486271) which might trace all the calls you make.
3+
4+
This tool helps you automate the process. You can leave in-context calls and production version of the jar will not contain any code which in-context wraps.
5+
6+
Extracted from `holy-lambda` micro-framework.
7+
8+
## How to use it?
9+
1. Add following dependency:
10+
11+
``` clojure
12+
io.github.FieryCod/clojure-graalvm-agent-helper {:mvn/version "0.0.1"}
13+
```
14+
15+
2. Use `agent/in-context` in your code:
16+
17+
```clojure
18+
(ns example.core
19+
(:gen-class)
20+
(:require
21+
[fierycod.graalvm-agent-helper.core :as agent]))
22+
23+
(agent/in-context
24+
(println "I can run arbitrary code in agent context. Agent will catch all the calls in context and generate native configuration out of it :)"))
25+
26+
(agent/in-context
27+
(println "In case of error agent will catch it :)")
28+
(throw (ex-info "Ups.." {})))
29+
30+
(defn -main
31+
[]
32+
(agent/in-context (println "Since main is called I will print as well :)")))
33+
```
34+
35+
3. Compile with `USE_AGENT_CONTEXT` environment set to `true`, so that `in-context` will not be removed
36+
37+
```
38+
USE_AGENT_CONTEXT=true clojure -X:uberjar :aot true :jvm-opts '["-Dclojure.compiler.direct-linking=true", "-Dclojure.spec.skip-macros=true"]' :jar agent-output.jar :main-class example.core
39+
```
40+
41+
4. Run in native agent context
42+
```
43+
java -agentlib:native-image-agent=config-output-dir=resources/native-configuration \
44+
-Dexecutor=native-agent \
45+
-jar agent-output.jar
46+
```
47+
48+
5. Compile a project without `USE_IN_AGENT_CONTEXT`
49+
```
50+
clojure -X:uberjar :aot true :jvm-opts '["-Dclojure.compiler.direct-linking=true", "-Dclojure.spec.skip-macros=true"]' :jar output.jar :main-class example.core
51+
```
52+
53+
5. Feed `native-image` with configuration and compile
54+
```
55+
native-image -jar output.jar \
56+
-H:ConfigurationFileDirectories=resources/native-configuration \
57+
-H:+AllowIncompleteClasspath \
58+
--report-unsupported-elements-at-runtime \
59+
--no-fallback \
60+
--verbose \
61+
--enable-url-protocols=http,https \
62+
--no-server \
63+
--initialize-at-build-time
64+
```
65+
66+
Check example folder if you still have trouble setting it up.

example/Makefile

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
IMAGE_CORD_PART:=fierycod/graalvm-native-image
2+
USE_EE:=false
3+
PWD=$$(pwd)
4+
USER_GID=$$(id -u):$$(id -g)
5+
6+
ifeq ($(USE_EE), false)
7+
IMAGE_CORD=$(IMAGE_CORD_PART):ce
8+
else
9+
IMAGE_CORD=$(IMAGE_CORD_PART):ee
10+
endif
11+
12+
compile-agent:
13+
USE_AGENT_CONTEXT=true clojure -X:uberjar :aot true :jvm-opts '["-Dclojure.compiler.direct-linking=true", "-Dclojure.spec.skip-macros=true"]' :jar agent-output.jar :main-class example.core
14+
15+
native-gen-conf: compile-agent
16+
@docker run --user $(USER_GID) \
17+
-v $(PWD):/project \
18+
-it $(IMAGE_CORD) \
19+
bash -c "java -agentlib:native-image-agent=config-output-dir=resources/native-configuration \
20+
-Dexecutor=native-agent \
21+
-jar agent-output.jar"
22+
compile:
23+
clojure -X:uberjar :aot true :jvm-opts '["-Dclojure.compiler.direct-linking=true", "-Dclojure.spec.skip-macros=true"]' :jar output.jar :main-class example.core
24+
25+
native-image: native-gen-conf compile
26+
@docker run --user $(USER_GID) \
27+
-v $(PWD):/project \
28+
-it $(IMAGE_CORD) \
29+
bash -c "native-image -jar output.jar \
30+
-H:ConfigurationFileDirectories=resources/native-configuration \
31+
-H:+AllowIncompleteClasspath \
32+
--report-unsupported-elements-at-runtime \
33+
--no-fallback \
34+
--verbose \
35+
--enable-url-protocols=http,https \
36+
--no-server \
37+
--initialize-at-build-time"

example/deps.edn

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{:paths ["src"]
2+
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
3+
io.github.FieryCod/clojure-graalvm-agent-helper {:mvn/version "0.0.1"}}
4+
:aliases {:deps {:replace-deps {org.clojure/tools.deps.alpha {:mvn/version "0.11.910"}
5+
org.slf4j/slf4j-nop {:mvn/version "1.7.25"}}
6+
:ns-default clojure.tools.cli.api}
7+
:test {:extra-paths ["test"]}
8+
9+
:uberjar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.216"}}
10+
:exec-fn hf.depstar/uberjar
11+
:exec-args {:aot true}}
12+
13+
;; build a jar (library):
14+
:jar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.216"}}
15+
:exec-fn hf.depstar/jar
16+
:exec-args {}}
17+
;; generic depstar alias, use with jar or uberjar function name:
18+
:depstar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.216"}}
19+
:ns-default hf.depstar
20+
:exec-args {}}}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[
2+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[
2+
]

0 commit comments

Comments
 (0)