{"id":16284987,"url":"https://github.com/goodforgod/graalvm-hint","last_synced_at":"2025-07-30T03:04:35.679Z","repository":{"id":40361548,"uuid":"409377443","full_name":"GoodforGod/graalvm-hint","owner":"GoodforGod","description":"🧰 Generates GraalVM configuration hints for native-image applications.","archived":false,"fork":false,"pushed_at":"2024-02-25T21:38:26.000Z","size":425,"stargazers_count":38,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T07:01:48.465Z","etag":null,"topics":["annotation-processor","graalvm","graalvm-native-image","hint","native-image"],"latest_commit_sha":null,"homepage":"http://goodforgod.dev/graalvm-hint/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoodforGod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-22T22:47:05.000Z","updated_at":"2025-01-25T10:52:36.000Z","dependencies_parsed_at":"2022-07-17T00:46:15.710Z","dependency_job_id":"8811045b-e62d-4dd6-94d8-c8026e6abfb5","html_url":"https://github.com/GoodforGod/graalvm-hint","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":"GoodforGod/java-library-template","purl":"pkg:github/GoodforGod/graalvm-hint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fgraalvm-hint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fgraalvm-hint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fgraalvm-hint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fgraalvm-hint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoodforGod","download_url":"https://codeload.github.com/GoodforGod/graalvm-hint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fgraalvm-hint/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267802568,"owners_count":24146501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation-processor","graalvm","graalvm-native-image","hint","native-image"],"created_at":"2024-10-10T19:21:49.255Z","updated_at":"2025-07-30T03:04:35.457Z","avatar_url":"https://github.com/GoodforGod.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GraalVM Hint Processor\n\n[![Minimum required Java version](https://img.shields.io/badge/Java-11%2B-blue?logo=openjdk)](https://openjdk.org/projects/jdk/11/)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.goodforgod/graalvm-hint-processor/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.goodforgod/graalvm-hint-processor)\n[![GitHub Action](https://github.com/goodforgod/graalvm-hint/workflows/Release/badge.svg)](https://github.com/GoodforGod/graalvm-hint/actions?query=workflow%3A%22Release%22)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_graalvm-hint\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=GoodforGod_graalvm-hint)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_graalvm-hint\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=GoodforGod_graalvm-hint)\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_graalvm-hint\u0026metric=ncloc)](https://sonarcloud.io/dashboard?id=GoodforGod_graalvm-hint)\n\nGraalVM Hint Processor helps generate GraalVM hints for building [native-image](https://www.graalvm.org/reference-manual/native-image/) applications.\n\nFully AOT processing library, no dependencies, no runtime side-affects.\n\nFeatures:\n- Generate Reflection Hints ([reflect-config.json](#reflectionhint))\n- Generate Resource Hints ([resource-config.json](#resourcehint))\n- Generate Options Hints ([native-image.properties](#nativeimagehint))\n- Generate Initialization Hints ([native-image.properties](#initializationhint))\n- Generate Dynamic Proxy Hints ([dynamic-proxy-hint.json](#dynamicproxyhint))\n- Generate JNI Hints ([jni-config.json](#jnihint))\n- Generate Link Build Hints ([native-image.properties](#linkhint))\n\n## Dependency :rocket:\n\n[**Gradle**](https://mvnrepository.com/artifact/io.goodforgod/graalvm-hint-processor)\n```groovy\nannotationProcessor \"io.goodforgod:graalvm-hint-processor:1.2.0\"\ncompileOnly \"io.goodforgod:graalvm-hint-annotations:1.2.0\"\n```\n\n[**Maven**](https://mvnrepository.com/artifact/io.goodforgod/graalvm-hint-processor)\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.goodforgod\u003c/groupId\u003e\n        \u003cartifactId\u003egraalvm-hint-annotations\u003c/artifactId\u003e\n        \u003cversion\u003e1.2.0\u003c/version\u003e\n        \u003cscope\u003ecompile\u003c/scope\u003e\n        \u003coptional\u003etrue\u003c/optional\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.goodforgod\u003c/groupId\u003e\n        \u003cartifactId\u003egraalvm-hint-processor\u003c/artifactId\u003e\n        \u003cversion\u003e1.2.0\u003c/version\u003e\n        \u003cscope\u003eprovided\u003c/scope\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n```xml\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e3.10.1\u003c/version\u003e\n            \u003cconfiguration\u003e\n                \u003cannotationProcessorPaths\u003e\n                    \u003cpath\u003e\n                        \u003cgroupId\u003eio.goodforgod\u003c/groupId\u003e\n                        \u003cartifactId\u003egraalvm-hint-processor\u003c/artifactId\u003e\n                        \u003cversion\u003e1.2.0\u003c/version\u003e\n                    \u003c/path\u003e\n                \u003c/annotationProcessorPaths\u003e\n            \u003c/configuration\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n## Content\n\n* [@ReflectionHint](#reflectionhint)\n    + [Self Config](#reflection-self-config)\n    + [Multi Config](#reflection-multi-config)\n* [@ResourceHint](#resourcehint)\n    + [Include Patterns](#include-patterns)\n    + [Exclude Patterns](#exclude-patterns)\n    + [Include Bundles](#include-bundles)\n* [@NativeImageHint](#nativeimagehint)\n    + [Entrypoint](#entrypoint)\n    + [Entrypoint \u0026 Options](#entrypoint-and-options)\n* [@InitializationHint](#initializationhint)\n    + [Runtime \u0026 Compile Time](#runtime-and-compile-time-config)\n    + [Self Config](#initialization-self-config)\n* [@DynamicProxyHint](#dynamicproxyhint)\n    + [Resources \u0026 Files](#resources-and-files-config)\n    + [Interfaces Multi Config](#interfaces-multi-config)\n    + [Interfaces Self Config](#interfaces-self-config)\n* [@JniHint](#jnihint)\n    + [JNI Self Config](#jni-self-config)\n    + [JNI Multi Config](#jni-multi-config)\n* [@LinkHint](#linkhint)\n  + [Link Self Config](#link-self-config)\n  + [Link Multi Config](#link-multi-config)\n  + [Link All Classes Config](#link-all-classes-config)\n* [Group \u0026 Artifact name](#group-and-artifact-name)\n\n## @ReflectionHint\n\nYou can read more about GraalVM reflection configuration [in official documentation here](https://www.graalvm.org/reference-manual/native-image/Reflection/).\n\nThere are available access hints:\n- allPublicFields\n- allPublicMethods\n- allPublicConstructors\n- allDeclaredFields\n- allDeclaredMethods\n- allDeclaredConstructors\n\nGenerating reflection access, most used cases is DTOs that are used for serialization/deserialization in any format (JSON for example).\n\n### Reflection Self Config\n\nSimple case for single Java class:\n```java\n@ReflectionHint\npublic class RequestOnly {\n\n    private String name;\n}\n```\n\nGenerated *reflection-config.json*:\n```json\n[{\n  \"name\": \"io.goodforgod.graalvm.hint.processor.RequestOnly\",\n  \"allDeclaredConstructors\": true,\n  \"allDeclaredFields\": true,\n  \"allDeclaredMethods\": true\n}]\n```\n\n### Reflection Multi Config\n\nThere may be more different cases, like generating hints for classes that are package private or just private, also there hint can be used for whole package.\n\nComplex example generating reflection access:\n```java\n@ReflectionHint(types = { Response.class, Request.class }, value = ReflectionHint.AccessType.ALL_DECLARED_FIELDS)\n@ReflectionHint(typeNames = { \"io.goodforgod.graalvm.hint.processor\"})\npublic class ReflectionConfig {\n\n    private String name;\n}\n```\n\nGenerated *reflection-config.json*:\n```json\n[{\n  \"name\": \"io.goodforgod.graalvm.hint.processor\",\n  \"allDeclaredConstructors\": true,\n  \"allDeclaredFields\": true,\n  \"allDeclaredMethods\": true\n},\n{\n  \"name\": \"io.goodforgod.example.Response\",\n  \"allDeclaredFields\": true\n},\n{\n  \"name\": \"io.goodforgod.example.Request\",\n  \"allDeclaredFields\": true\n}]\n```\n\n## @ResourceHint\n\nYou can read more about GraalVM resource configuration [in official documentation here](https://www.graalvm.org/reference-manual/native-image/Resources/).\n\nHint allows generating config for resource files to be included/excluded when building native application.\nYou can also include bundles into native image using this Hint.\n\n### Include Patterns\n\nResource patterns specified with Java regexp to Include during native-image generation into the final application.\n\nInclude Hint:\n```java\n@ResourceHint(include = { \"simplelogger.properties\", \"application.yml\", \"*.xml\" })\npublic class ResourceNames {\n\n}\n```\n\nGenerated *resource-config.json*:\n```json\n{\n  \"resources\": {\n    \"includes\": [\n      { \"pattern\" : \"*.xml\" },\n      { \"pattern\": \"application.yml\" },\n      { \"pattern\": \"simplelogger.properties\" }\n    ]\n  }\n}\n```\n\n### Exclude Patterns\n\nResource patterns specified with Java regexp to Exclude during native-image generation into the final application.\n\nExclude Hint:\n```java\n@ResourceHint(exclude = { \"*.xml\" })\npublic class ResourceNames {\n\n}\n```\n\nGenerated *resource-config.json*:\n```json\n{\n  \"resources\": {\n    \"excludes\": [\n      { \"pattern\": \"*.xml\" }\n    ]\n  }\n}\n```\n\n### Include Bundles\n\nNative Image needs ahead-of-time knowledge of the resource bundles your application needs so that it can load and store the appropriate bundles for usage in the generated binary.\n\nBundle Hint:\n```java\n@ResourceHint(bundles = { \"your.pkg.Bundle\" })\npublic class ResourceNames {\n\n}\n```\n\nGenerated *resource-config.json*:\n```json\n{\n  \"bundles\": [\n    { \"name\": \"your.pkg.Bundle\" }\n  ]\n}\n```\n\n## @NativeImageHint\n\nYou can read more about GraalVM native-image options [in official documentation here](https://www.graalvm.org/reference-manual/native-image/Options/).\n\nHint allows generating config for native-image options and initial application entrypoint.\n\n### Entrypoint\n\nSimple hint configuration:\n```java\n@NativeImageHint(entrypoint = EntrypointOnly.class)\npublic class EntrypointOnly {\n\n    public static void main(String[] args) {}\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = -H:Class=io.goodforgod.graalvm.hint.processor.EntrypointOnly\n```\n\n### Entrypoint and Options\n\nComplex hint configuration with options:\n```java\n@NativeImageHint(entrypoint = Entrypoint.class, name = \"myapp\", options = { NativeImageOptions.PRINT_INITIALIZATION, NativeImageOptions.INLINE_BEFORE_ANALYSIS })\npublic class Entrypoint {\n\n    public static void main(String[] args) {}\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = -H:Class=io.goodforgod.graalvm.hint.processor.Entrypoint -H:Name=myapp \\\n       -H:+PrintClassInitialization \\\n       -H:+InlineBeforeAnalysis\n```\n\n## @InitializationHint\n\nYou can read more about GraalVM initialization configuration [in official documentation here](https://www.graalvm.org/reference-manual/native-image/ClassInitialization/).\n\nHint allows generating config for what classes to instantiate in runtime and what classes to instantiate in compile time.\n\n### Runtime and Compile Time Config\n\nInitialization hint configuration:\n```java\n@InitializationHint(value = InitializationHint.InitPhase.BUILD, types = HintOptions.class)\n@InitializationHint(value = InitializationHint.InitPhase.RUNTIME, typeNames = \"io.goodforgod.graalvm.hint.processor\")\npublic class EntrypointOnly {\n\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = --initialize-at-build-time=io.goodforgod.graalvm.hint.processor.HintOrigin.class \\\n       --initialize-at-run-time=io.goodforgod.graalvm.hint.processor\n```\n\n### Initialization Self Config\n\nSimple case for single Java class:\n```java\n@InitializationHint\npublic class Self {\n\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = --initialize-at-build-time=io.goodforgod.graalvm.hint.processor.Self\n```\n\n## @DynamicProxyHint\n\nYou can read more about GraalVM DynamicProxyHint configuration [in official documentation here](https://www.graalvm.org/reference-manual/native-image/DynamicProxy/).\n\n### Resources and Files Config\n\nUse can pass dynamic proxy resources (*-H:DynamicProxyConfigurationResources*) or files (*-H:DynamicProxyConfigurationFiles*) using corresponding options:\n```java\n@DynamicProxyHint(resources = {\"proxy-resource.json\"}, files = {\"proxy-file.json\"})\npublic class Resource {\n\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = -H:DynamicProxyConfigurationFiles=proxy-file.json \\\n       -H:DynamicProxyConfigurationResources=proxy-resource.json\n```\n\n### Interfaces Multi Config\n\nYou can fully configure proxy yourself using annotations only, without the need for manually creating JSON configurations.\n```java\n@DynamicProxyHint(value = {\n        @DynamicProxyHint.Configuration(interfaces = {OptionParser.class, HintOrigin.class}),\n        @DynamicProxyHint.Configuration(interfaces = {HintOrigin.class})\n})\npublic class Config {\n\n}\n```\n\nGenerated *dynamic-proxy-hint-config.json*:\n```json\n[\n  { \"interfaces\": [ \"io.goodforgod.graalvm.hint.processor.OptionParser\", \"io.goodforgod.graalvm.hint.processor.HintOrigin\" ] },\n  { \"interfaces\": [ \"io.goodforgod.graalvm.hint.processor.HintOrigin\" ] }\n]\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = -H:DynamicProxyConfigurationResources=META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/dynamic-proxy-config.json\n```\n\n### Interfaces Self Config\n\nIn case you need to add only one interface for DynamicProxy Hint configuration, you can annotate that interface directly:\n```java\n@DynamicProxyHint\npublic interface Self {\n\n}\n```\n\nGenerated *dynamic-proxy-hint-config.json*:\n```json\n[\n  { \"interfaces\": [ \"io.goodforgod.graalvm.hint.processor.Self\" ] }\n]\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = -H:DynamicProxyConfigurationResources=META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/dynamic-proxy-config.json\n```\n\n## @JniHint\n\nYou can read more about GraalVM JNI configuration [in official documentation here](https://www.graalvm.org/reference-manual/native-image/JNI/).\n\nThere are available JNI access hints:\n- allPublicFields\n- allPublicMethods\n- allPublicConstructors\n- allDeclaredFields\n- allDeclaredMethods\n- allDeclaredConstructors\n\n### JNI Self Config\n\nSimple case for single Java class:\n```java\n@JniHint\npublic class RequestOnly {\n\n    private String name;\n}\n```\n\nGenerated *jni-config.json*:\n```json\n[{\n  \"name\": \"io.goodforgod.graalvm.hint.processor.RequestOnly\",\n  \"allDeclaredConstructors\": true,\n  \"allDeclaredFields\": true,\n  \"allDeclaredMethods\": true\n}]\n```\n\n### JNI Multi Config\n\nThere may be more different cases, like generating hints for classes that are package private or just private, also there hint can be used for whole package.\n\nComplex example generating reflection access:\n```java\n@JniHint(types = { Response.class, Request.class }, value = JniHint.AccessType.ALL_DECLARED_FIELDS)\n@JniHint(typeNames = { \"io.goodforgod.graalvm.hint.processor\"})\npublic final class JniConfig {\n\n}\n```\n\nGenerated *jni-config.json*:\n```json\n[{\n  \"name\": \"io.goodforgod.graalvm.hint.processor\",\n  \"allDeclaredConstructors\": true,\n  \"allDeclaredFields\": true,\n  \"allDeclaredMethods\": true\n},\n{\n  \"name\": \"io.goodforgod.example.Response\",\n  \"allDeclaredFields\": true\n},\n{\n  \"name\": \"io.goodforgod.example.Request\",\n  \"allDeclaredFields\": true\n}]\n```\n\n## @LinkHint\n\nYou can read more about GraalVM Link Build configuration [in official documentation here](https://www.graalvm.org/22.1/reference-manual/native-image/Options/#options-to-native-image-builder).\n\nHint is only **available in GraalVM 22.1.0+**, check this [PR for more info](https://github.com/oracle/graal/pull/4305).\n\nSpecify types to be fully defined at image build-time.\n\n### Link Self Config\n\nSimple case for single Java class:\n```java\n@LinkHint\npublic class RequestOnly {\n\n    private String name;\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = --link-at-build-time=io.goodforgod.graalvm.hint.processor.RequestOnly\n```\n\n### Link Multi Config\n\nThere may be more different cases, like generating hints for classes that are package private or just private, also there hint can be used for whole package.\n\nComplex example generating link hints:\n```java\n@LinkHint(types = { Response.class, Request.class })\n@LinkHint(typeNames = { \"io.goodforgod.graalvm.hint.processor\"})\npublic final class JniConfig {\n\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = --link-at-build-time=io.goodforgod.graalvm.hint.processor,io.goodforgod.graalvm.hint.processor.Response,io.goodforgod.graalvm.hint.processor.Request\n```\n\n### Link All Classes Config\n\nIs the same as using GraalVM flag without options.\n```text\nIf used without args, all classes in scope of the option are required to be fully defined.\n```\n\nExample how to force all classes to link in build time, no matter what how other class declare this hint, if any annotation with all = true found, then it will be used this way.\n```java\n@LinkHint(all = true)\npublic class RequestOnly {\n\n    private String name;\n}\n```\n\nGenerated *native-image.properties*:\n```properties\nArgs = --link-at-build-time\n```\n\n## Group and Artifact name\n\nYou can change the output group and artifact name, by default the *group* will be the package name where the annotated class was located and the artifact will be named *hint*.\n\nFor class:\n```java\npackage io.goodforgod.graalvm.hint.processor;\n\nimport io.goodforgod.graalvm.hint.annotation.ReflectionHint;\n\n@ReflectionHint\npublic class Request {\n\n    private String name;\n}\n```\n\nHint will be generated into `build/classes/java/main/META-INF/native-image/io.goodforgod.graalvm.hint.processor/hint/reflect-config.json` directory.\nWhere *io.goodforgod.graalvm.hint.processor* is *group* name and *hint* artifact name.\n\nYou can override default behavior and select our own *group* and *artifact* name via annotation [processor options](https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html).\n\nAnnotation processor options:\n- *graalvm.hint.group* - group name.\n- *graalvm.hint.artifact* - artifact name.\n\nHere are examples of configurations for Gradle and Maven.\n\n**Gradle**\n```groovy\ncompileJava {\n    options.compilerArgs += [\n            \"-Agraalvm.hint.group=my.group\",\n            \"-Agraalvm.hint.artifact=myartifact\",\n    ]\n}\n```\n\n**Maven**\n```xml\n\u003cbuild\u003e\n  \u003cplugins\u003e\n    \u003cplugin\u003e\n        \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n        \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n        \u003cversion\u003e3.10.1\u003c/version\u003e\n        \u003cconfiguration\u003e\n            \u003cparameters\u003etrue\u003c/parameters\u003e\n            \u003ccompilerArgs\u003e\n                \u003ccompilerArg\u003e-Agraalvm.hint.group=my.group\u003c/compilerArg\u003e\n                \u003ccompilerArg\u003e-Agraalvm.hint.artifact=myartifact\u003c/compilerArg\u003e\n            \u003c/compilerArgs\u003e\n        \u003c/configuration\u003e\n    \u003c/plugin\u003e\n  \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n## License\n\nThis project licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodforgod%2Fgraalvm-hint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodforgod%2Fgraalvm-hint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodforgod%2Fgraalvm-hint/lists"}