A set of annotations and an annotation processor to help with GraalVM native image.
For a native image to be built, all reflection, proxies, JNI, classpath resource and other elements that would usually be discovered at runtime, must be declared at compile time.
Instead of using the GraalVM tracing agent, or hand crafting native image configuration files, you can annotate your classes, interfaces, methods and fields. These annotations are then turned into JSON files consumed by the native image compiler.
It is currently most useful for exposing certain elements to reflection, and the reason I created it was to help generate natively compiled DBus services using DBus Java on Linux.
The annotations are only source only, so the library is only needed during development and build time.
The library is available in Maven Central (and OSS Snapshots). You need to add it as a compile time dependency, and an annotation processor. Gradle also supports annotations processors, or you can use them with the standard Java compiler.
<dependency>
<groupId>uk.co.bithatch</groupId>
<artifactId>native-image-annotations</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
Not required if using a stable version.
<repository>
<id>oss-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots />
<releases>
<enabled>false</enabled>
</releases>
</repository>
You must add the annotation processor to your compiler.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>uk.co.bithatch</groupId>
<artifactId>native-image-annotations</artifactId>
<version>0.0.1-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
The module must be added, even though it won't be available at runtime.
requires static uk.co.bithatch.nativeimage.annotations
To use, simply annotation you source elements appropriately. In the example below, reflection configuration will be created, exposing MyNativeService
and all of its methods, as well as a single field and a method from MyObject
.
@Reflectable
@TypeReflect(methods = true, classes = true)
public class MyNativeService {
public List<String> getListOfSomething() {
return Arrays.asList("one", "two", "three");
}
public MyObject getAnObject(String name) {
return new MyObject(name, name + " private");
}
@Reflectable
@TypeReflect(constructors = true)
public static class MyObject {
@Reflectable
private String someValue;
private String somePrivateValue;
public MyObject(String someValue, String somePrivateValue) {
this.someValue = someValue;
this.somePrivateValue = somePrivateValue;
}
@Reflectable
public String getSomeValue() {
return someValue;
}
public String getSomePrivateValue() {
return somePrivateValue;
}
}
}
Marks either a TYPE
, CONSTRUCTOR
, FIELD
or METHOD
as a candidate for reflection. It has a single attribute, all()
that will signal that all child elements will also be reflectable.
Configuration will be added to reflect-config.json
.
Used in on a TYPE
in conjunction with a @Reflectable
, this annotation provides 4 attributes allowing control of whether all child elements of a certain type should be reflectable.
It supports, constructors()
, fields()
, methods()
or classes()
.
Configuration will be added to reflect-config.json
.
Marks a TYPE
as a Proxy type.
Configuration will be added to proxy-config.json
.
Marks a TYPE
for serialization.
Configuration will be added to serialization-config.json
.
Adds an i18n resource bundle for a TYPE
. A single attribute is supported, locales()
which is an optional list of locales to include.
For example, if the class com.acme.MyObject
was annotated with @Bundle
, then the default resource path of com/acme/MyObject.properties
must exist. There can be optional resources such as com/acme/MyObject_fr.properties
etc.
Introduces classpath resources. Exact behaviour will depend on attributes used.
- If the annotation has no attributes, then all resources in the same package, and prefixed with the same class name will be included. For example, if the annotated class's full qualified name is
com.acme.MyObject
, then/com/acme/MyObject.properties
,/com/acme/MyObject.css
and so on will be included. - If the annotation sets the
siblings()
attribute to true, then all resources in the same project will be incluided. - Otherwise, the annotation
value()
is an array of absolute resource paths.
Configuration will be added to resources-config.json
.