JEP 544: Ahead-of-Time Code Compilation

(openjdk.org)

103 points | by Skinney 4 days ago ago

22 comments

  • cogman10 3 days ago ago

    Leyden has been relying pretty heavily on training runs which I get, but man is that a pretty hard burden to setup.

    The tooling for doing these sorts of training runs doesn't really exist, you end up needing to do something more bespoke as part of your build pipeline if you want it there. That can be especially tricky with more complicated applications like the ones I maintain.

    I like what these can deliver, but dislike the effort needed to get it going.

    • jgon 3 days ago ago

      I completely agree. I know that there has been some work on command line ergonomics for this stuff, but my hope is that after the bulk of the Leyden work is done, another project starts up aimed at unifying all of the various disparate tools that modern Java now has. You have training runs to generate bytecode/compiled code, you have jlink to create a distributable JRE for your app, leaning on jdeps and various other tools to correctly create it, you have the venerable jar file, but all in all the process of actually getting a java project ready to distribute in a way that doesn't presuppose a relevant pre-installed JRE on the user's side, and which takes advantage of the various facilities available to modern Java is still a pretty bespoke and painful process.

      Compared to Go and Rust, and just throwing a static binary to someone or some server, Java kind of sucks. And that's unfortunate because the language, the runtime, and even the dependency situation all feels pretty competent, there's not some huge gulf that makes Java "old". Its really just the every about setting up a project and then distributing it, so the "start" and "end" of a project, that currently sucks, and I fear that so much of the great work the Java team is doing is going to go largely unused if they don't work to make it easier for the average developer to utilize it.

    • elric 3 days ago ago

      The complexity of training depends heavily on your goals. If your goal is to improve startup time, it's actually pretty simple.

      If your goal is peak performance across the board and you can't wait for runtime optimizations to kick in, you're going to have a harder time. But in many of the things I've worked on, startup time has been a bigger issue than JIT->peak.

    • pjmlp 3 days ago ago

      Yes, OpenJ9 and ART do it much more easily, the JIT cache is updatable across executions, so there isn't an explicit training run required.

  • cyberax 4 days ago ago

    Excelsior JET did that 25 years ago: https://en.wikipedia.org/wiki/Excelsior_JET

    It's a shame that Sun/Oracle never partnered with them to bring native apps. This could have saved Java on the desktop.

    • wahern 4 days ago ago

      Don't forget GCJ. It wasn't removed from GCC until about 2016, a nearly 20-year long run, though interest had waned many years prior.

      I don't remember if GCJ supported loading and running code dynamically with a built-in JIT or interpreter. I think it was just pure AOT, which caused some compatibility headaches.

    • pjmlp 4 days ago ago

      They were not the only ones, see PTC, Aicas, IBM, and a few others.

      The big difference until GraalVM and OpenJ9 became available as open source, was that all those vendors made AOT compilation a commercial feature, and thus most devs never cared they existed.

      In fact GraalVM was one of the main reasons Excelsior JET eventually closed doors.

    • misja111 3 days ago ago

      The JRockit JVM had it already 20 years ago, and the company was even bought by Oracle shortly afterwards.

    • patwolf 4 days ago ago

      IBM's J9 had AOT for a long time too. I wonder how JEP 544 compares.

    • DonHopkins 3 days ago ago

      The only thing that could possibly save Java on the desktop would require Oracle not owning it.

  • rerdavies 2 days ago ago

    Why would you not AOT compile at install time?! That would allow the compile to use CPU-specific features? And put a compiled preamble for class initialization on applicable functions that patches the VTABLE to skip the class initialization code.

    • samus 2 days ago ago

      There is no install time in Java. If you want something to happen at install time you'd have to ship a shell script with the installer that does a brief training run when the application is first started.

  • treyd 3 days ago ago

    What are the architectural differences between this and Android's ahead-of-time runtime?

    • Skinney 3 days ago ago

      This JEP is essentially about caching the JIT's generated code for later runs. The JIT is still free to discard the cache if it deems it worthwhile.

  • harlan_pdx 3 days ago ago

    Startup time being the main benefit means simple training runs get you most of the value. Going for peak throughput is where the setup gets heavy.

  • java-man 4 days ago ago

    I hope at some point we'll get AOT-only mode (or compile to native) and maybe even cross-compilation.

    • layer8 4 days ago ago

      That would place significant limitations on the applications that can be compiled. As the JEP explains: “Features such as dynamic class loading, dynamic linkage, dynamic dispatch, and dynamic reflection bring vast expressive power, and have been fundamental to the platform's success. HotSpot handles these features naturally, while static compilers struggle with them. Even heroic amounts of static analysis cannot make up for the fact that these features require many decisions to be made at run time. Implementors of static compilers for Java code have therefore resorted to incompatible constraints, such as closed-world assumptions, and to putting significant burdens on developers, such as having to identify in advance the classes eligible for reflection.”

      Therefore I don’t see AOT-only becoming an integral part of standard Java in the foreseeable future.

    • nirvdrum 4 days ago ago

      If you haven't checked it out yet, GraalVM's Native Image [1] already let's do AOT compilation suitable for distribution. You have to do some configuration to deal with reflection and dynamic class loading since there's no JVM in the produced build, but it comes with tooling to simplify that. And that restriction is being addressed by Project Crema [2].

      [1] -- https://www.graalvm.org/latest/reference-manual/native-image... [2] -- https://github.com/oracle/graal/issues/11327

    • exabrial 4 days ago ago

      progress, not perfection! Java is on fire right now with new stuff landing. We'll get there!

    • invalidname 4 days ago ago

      We have that in Codename One, yes it's not really "Java" but it compiles bytecode AOT and cross compiles to some of the platforms.

    • samus 3 days ago ago

      That won't be necessary when 544 lands. The only thing you'd gain is not having to ship the JIT compilers in a jlink build. Also, I'm fairly certain that the JIT compilers can be turned off with some combination of runtime flags to ensure only the AOT generated code is executed.

    • za3faran 3 days ago ago

      GraalVM native-image already provides an AOT-only executable.