Show HN: Standalone Jdk.compiler, Java Compiler Framework and Tree API
github.comWith this standalone compiler, you can rely on all Java 11 javac features to be available, even when using newer Java versions. Specifically, this allows you to:
- compile code even if your Java environment isn't a full JDK (Java JRE, for example!)
- target Java 1.7 for compilation without any warnings or restrictions.
- use the Compiler Tree API without resorting to --add-opens trickery that may eventually fail in newer Java releases
- build a modified compiler with additional features or custom tweaks
I made this after finding that the otherwise superb "jsweet" Java-to-JavaScript transpiler failed to build and run with Java 16 or newer. Surprisingly, I couldn't find any prior work other than "proper" standalone compilers like Eclipse's ecj that would properly work with modern Java runtimes.
I'm excited to see what can be done now that we have this scaffolding. In the repository, I see > By adding support for GraalVM native image, we could build javac binaries with custom configurations Can you elaborate on what's missing for GraalVM native image support? Is there a particular behavior of javac (e.g. reflection, dynamic class loading, keeping threads alive at compile-time, ...) that is a show stopper for native image compatibility? Overall this project looks cool, and native-image support may allow integration into tools like Babashka to do some crazy things like downloading Java source from somewhere then compiling and loading it into the running image. I think native image support is actually trivial to implement, it's just not done yet since it wasn't a priority. There are indeed some reflection calls that need to be configured via META-INF/native-image config files, but nothing out of the ordinary. Adding GraalVM native-image support required a little more hand-holding than expected, but is now available with version 1.1.0. The project can now also compile itself. Exciting times. Thanks! I will try experimenting with release 1.1.0 sometime. This is actually kind of an important concept given how the Java module system now works. There are lots of useful internal bits in the JDK that should really be available to outside use. But because the openjdk project wants to be able to move things around, the internals shouldn't be used directly by applications (shouldn't have ever been used, I guess). So extracting out these bits into separate library code is important. But it also stinks because now there's a fork of this compiler code, which won't necessarily get updates or fixes from openjdk (not without a lot of manual diligence). Anyway, it's definitely a commendable project and I hope that we see more like it. Java 11 is pretty much done now, so I'm hoping that maintenance overhead is minimal. I've actually noticed the opposite in a project I wanted to use: code rot. It would simply not work when running in Java 16 or newer... So that's why I created this project. Super cool, and thanks for doing this. A neat use case would be to replace Error Prone's use of the compiler tree API. If this gets a Java 21 version soon, I may be able to use it for a new project I was just going to make an Error Prone plugin for. I have the JDK21 compiler working now (it's on github, but not released yet). Funny enough, you can compile Java 21 code from Java 11 now :) If you're interested in testing this, please let me know by opening a ticket on Github. Cheers! I've just released version 1.1.0 with support for JDK21 (run with Java 11 or newer) as well as GraalVM native-image. Give it a try. That's a great idea! I also ran into errorprone problems myself. Working on a JDK21 compiler port right now... Very nice, thank you for taking this on! A few questions; the implication here is that ecj does not export the Java compiler api, is that correct? How do j2ee components that require compilation (jsp )handle the “—add-open” requirement? There's actually a public Java SDK module, javax.compiler, which Java compiler implementations (including ECJ) are supposed to use, so users can call them via Service Provider Interface. In Java 8, Oracle called javac's AST parser code the "Compiler Tree API", but that's now degraded to mere implementaton-specifics of the internal "jdk.compiler" module.