{"id":15045765,"url":"https://github.com/kohlschutter/jdk.compiler.standalone","last_synced_at":"2025-04-10T00:43:31.463Z","repository":{"id":198880336,"uuid":"701721573","full_name":"kohlschutter/jdk.compiler.standalone","owner":"kohlschutter","description":"Standalone jdk.compiler / JDK javac Compiler Framework + Compiler Tree API","archived":false,"fork":false,"pushed_at":"2023-10-14T13:06:37.000Z","size":111,"stargazers_count":46,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T00:43:25.054Z","etag":null,"topics":["compiler","java","javac","jdk"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kohlschutter.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":"2023-10-07T11:22:02.000Z","updated_at":"2023-11-29T16:46:30.000Z","dependencies_parsed_at":"2023-10-14T18:32:18.826Z","dependency_job_id":"e80df636-5d7c-4329-87d5-68db55f9abf5","html_url":"https://github.com/kohlschutter/jdk.compiler.standalone","commit_stats":null,"previous_names":["kohlschutter/jdk.compiler.standalone"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kohlschutter%2Fjdk.compiler.standalone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kohlschutter%2Fjdk.compiler.standalone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kohlschutter%2Fjdk.compiler.standalone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kohlschutter%2Fjdk.compiler.standalone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kohlschutter","download_url":"https://codeload.github.com/kohlschutter/jdk.compiler.standalone/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137998,"owners_count":21053775,"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","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":["compiler","java","javac","jdk"],"created_at":"2024-09-24T20:52:15.257Z","updated_at":"2025-04-10T00:43:31.439Z","avatar_url":"https://github.com/kohlschutter.png","language":"Java","funding_links":[],"categories":["compiler"],"sub_categories":[],"readme":"# Standalone jdk.compiler / Java Compiler Framework + Tree API\n\n## What\n\nThis repository builds standalone `jdk.compiler` artifacts (the Java code behind `javac`, etc.)\nthat can be used just like other regular Maven dependencies.\n\n## Why\n\n### Motivation\n\nA typical way of using the Java Compiler API is to rely on the presence of such API in the Java VM\nthat runs the code requiring it.\n\nStarting with Java 16, using the internals of the Java Compiler API requires a series of\n`--add-opens` incantations to the running VM, such as:\n\n```\n--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED\n--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED\n--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED\n--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED\n```\netc.\n\nThe reason is clear: Eventually, we cannot rely on the presence of said API in the JDK, since\n`jdk.compiler` is an internal module that we really shouldn't touch.\n\nSince the Compiler Framework code is licensed as GPLv2+Classpath-Exception, let's make it\na separate component that we can use regardless of what's available in the\ncurrent VM!\n\n### Benefits\n\nWith this standalone compiler, you can rely on all Java 11 javac features to be available,\neven when using newer Java versions.\n\nSpecifically, this is allows you to:\n\n- compile code even if your Java environment isn't a full JDK (Java JRE, for example!)\n- target Java 1.7 for compilation without any warnings or restrictions.\n- parse and compile Java 21 source code from Java 11 or newer\n- use the Compiler Tree API without resorting to `--add-opens` trickery that may eventually fail\n  in newer Java releases\n- build a modified compiler with additional features or custom tweaks\n\n### Examples\n\nSee this [jsweet fork](https://github.com/kohlschutter/jsweet). jsweet makes exhaustive use of\nthe Compiler Tree API, and now we can run it in Java 17 without prying open some JDK internals. \n\n## How\n\n### Usage\n\nFirst, add one of the following Maven dependencies (but not both) to your project:\n\nFor the Java 11 compiler:\n\n```xml\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.kohlschutter.jdk.compiler\u003c/groupId\u003e\n        \u003cartifactId\u003estandalone-jdk11\u003c/artifactId\u003e\n        \u003cversion\u003e1.1.3\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\nFor the Java 21 compiler (which runs on Java 11 or newer, even with JRE-only):\n\n```xml\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.kohlschutter.jdk.compiler\u003c/groupId\u003e\n        \u003cartifactId\u003estandalone-jdk11\u003c/artifactId\u003e\n        \u003cversion\u003e1.1.3\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\nIf your project is modularized, also add the following statements to your `module-info.java`:\n\n```\n  requires standalone.jdk.compiler;\n  requires com.kohlschutter.jdk.standaloneutil;\n```\n\nThis gives you access to all `com.sun.tools.*` and `com.sun.source.*` packages, however they are\nactually prefixed by `standalone.`, i.e., `standalone.com.sun.tools.*`, etc.\n\nSo you need to change your code to use `standalone.com.sun.`... instead of `com.sun.`...\nFor example use `standalone.com.sun.tools.javac.api.JavacTool` instead of\n`com.sun.tools.javac.api.JavacTool`.\n\nIf you use `javax.tools.ToolProvider.getSystemJavaCompiler()`, change this to our own version:\n`com.kohlschutter.jdk.standaloneutil.ToolProvider.getSystemJavaCompiler()` (or just modify the\n`import` statement).\n\nThe original Compiler framework refers to certain files from the JDK's home directory, specifically\n`lib/modules` (which contains all default `modules`), as well as `lib/ct.sym`, which contains the\nAPI fingerprints to support `-release` compatibility checks.\n\nThe standalone compiler uses its own copies for both `lib/modules` contents as well as `lib/ct.sym`\nfrom a recent JDK 11 java home directory, which is automatically included via the\n`com.kohlschutter.jdk:standalone-home` dependency.\n\n### Project setup and structure\n\nThe code in this repository relies on copies of the \"jdk.compiler\" code\nobtained from Open Source Java JDKs (for example, Eclipse Temurin).\n\nThese copies reside in a separate repository and are added as submodules to this project.\n\nEach submodule refers to a different JDK version, which allows the creation of\nmultiple Maven artifacts, one for each major JDK version.\n\n### Limitations\n\nTo use this artifact, you currently need Java 11 or better.\n\n### Building from source\n\nClone this repository, initialize submodules and build:\n\n```\ngit clone https://github.com/kohlschutter/jdk.compiler.standalone.git\ncd jdk.compiler.standalone.git\ngit submodule update --init\nmvn clean install\n```\n\nAlso see [jdk.compiler.home](https://github.com/kohlschutter/jdk.compiler.home) for the\ncorresponding JDK home artifact.\n\n### Executable jar with embedded dependencies\n\nExecutable jar files (`java -jar ...`) are built with `-Djar-with-dependencies` enabled:\n\n```\nmvn clean install -Djar-with-dependencies\n```\n\nExecutable jars are then placed in\n`standalone-jdk11/target/standalone-jdk11-VERSION-jar-with-dependencies.jar` (for JDK11) and\n`standalone-jdk21/target/standalone-jdk21-VERSION-jar-with-dependencies.jar` (for JDK21).\n\n### GraalVM native image\n\nExecutable [GraalVM native images](https://www.graalvm.org/22.0/reference-manual/native-image/)\nare built with `-Dnative` enabled (this expects `GRAALVM_HOME` to be set to the home directory of\na recent GraalVM SDK):\n\n```\nmvn clean install -Dnative\n```\n\nExecutables are then placed in\n`standalone-jdk11/target/standalone-jdk11-VERSION-javac` (for JDK11) and\n`standalone-jdk21/target/standalone-jdk21-VERSION-javac` (for JDK21).\n\n### Compiling itself\n\n#### Using native-image\nObtain the GraalVM native-image from the step above and copy it to an external path, e.g.\n`$HOME/standalone-jdk21-javac`. If you want to compile everything, you need the `jdk21` version,\notherwise `jdk11` works as well.\n\nAll you then need is to specify the path to this binary when building the project:\n\n```\nmvn clean install -Dcustom-javac=$HOME/standalone-jdk21-javac\n```\n\n#### Using jar-with-dependencies\n\nYou can also use the regular jar-with-dependencies jars, but then you need to write a little\nwrapper script that can be executed by Maven:\n\n```\n#!/bin/sh\n\n/path/to/some/java-home-directory/bin/java -jar $HOME/standalone-jdk21-jar-with-dependencies.jar $@\n``` \n\nSave the script to an external place like `$HOME/standalone-jdk21-javac-jar-with-dependencies`\nand build the project:\n\n```\nmvn clean install -Dcustom-javac=$HOME/standalone-jdk21-javac-jar-with-dependencies\n```\n\nYou can experiment with using different Java JDKs/JREs to host the compiler. Anything Java 11 or\nnewer should work.\n\n## When\n\n### Future enhancements\n\n- We could support multiple different compiler versions to run side-by-side in the same VM.\n- We could build `javac` binaries (via GraalVM native-image) with custom configurations\n- This approach may be used for other jdk-internal components as well.\n\nIf you have an idea, please reach out!\n\n### Changelog\n\n#### _(2023-10-14)_ jdk.compiler.standalone 1.1.3\n\n- Fix Maven POM setup that would prevent getting the correct dependencies in other projects, take 2\n- No longer build jar-with-dependencies by default\n\n#### _(2023-10-14)_ jdk.compiler.standalone 1.1.2\n\n- Fix Maven POM setup that would prevent getting the correct dependencies in other projects\n\n#### _(2023-10-14)_ jdk.compiler.standalone 1.1.1\n\n- Open all exported packages\n\n#### _(2023-10-13)_ jdk.compiler.standalone 1.1.0\n\n- Add the compiler from JDK21, and backport it to Java 11 (!).\n- Add GraalVM native-image support.\n- Add self-contained jar-with-dependencies for both JDK11 and JDK21.\n- Various fixes. The standalone compiler can now compile itself.\n\n#### _(2023-10-10)_ jdk.compiler.standalone 1.0.0\n\n- Initial release.\n\n## Who\n\nThis repository has been put together by [Christian Kohlschütter](https://kohlschuetter.github.io/blog/).\n\n### Getting involved\n\nIf you encounter a bug, please file a [bug report](https://github.com/kohlschutter/jdk.compiler.standalone/issues).\n\nIf you want to contribute, please open a [pull request](https://github.com/kohlschutter/jdk.compiler.standalone/pulls)\nor reach out directly.\n\n### License\n\nThe code itself carries the original license, GNU General Public License\nversion 2 only, subject to the \"Classpath\" exception as provided in\nthe LICENSE file that accompanies this code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkohlschutter%2Fjdk.compiler.standalone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkohlschutter%2Fjdk.compiler.standalone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkohlschutter%2Fjdk.compiler.standalone/lists"}