Java Hello World, Llvm Edition
Key topics
Diving into the uncharted territory of Java and LLVM, a recent article sparked a lively debate about the practicality of using LLVM with Java code. While some commenters, like drzaiusx11, saw potential in LLVM as a means to facilitate cross-language interoperability in the JVM, others, like TazeTSchnitzel, pointed out that the article wasn't actually about that topic at all. As the discussion unfolded, it became clear that the article was more of an educational exercise, showcasing the new FFM API, with mands noting that using LLVM JIT might not be the most practical choice when HotSpot's built-in capabilities are available. The conversation was marked by some humorous analogies, like almostgotcaught's "frying pan vs flashlight" quip, highlighting the perceived disconnect between the article's content and potential real-world applications.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
49m
Peak period
36
0-6h
Avg / period
10.8
Based on 86 loaded comments
Key moments
- 01Story posted
Dec 7, 2025 at 6:51 AM EST
29 days ago
Step 01 - 02First comment
Dec 7, 2025 at 7:39 AM EST
49m after posting
Step 02 - 03Peak activity
36 comments in 0-6h
Hottest window of the conversation
Step 03 - 04Latest activity
Dec 9, 2025 at 2:24 PM EST
26 days ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
The two things have nothing to do with each other.
I can't think of many actual use-cases where you'd want to use the LLVM JIT over those built-in to HotSpot.
Interfacing with existing LLVM-based systems, writing a very tight inner loop using LLVM where you absolutely need LLVM-like performance, or creating a compiler that targets LLVM using Java would be the main "real-world" use-cases.
https://troymcconaghy.blog/2025/01/13/39-hello-world-program...
> he used python and xelatex
> https://github.com/ttmc/hello-world-ways
[1] https://ctan.org/pkg/minted
[2] https://pygments.org/
Sending system signals is external to the JVM platform
1984: https://en.wikipedia.org/wiki/Objective-C
1995: https://en.wikipedia.org/wiki/Java_(programming_language)
https://cs.gmu.edu/~sean/stuff/java-objc.html
https://en.wikipedia.org/wiki/Distributed_Objects_Everywhere
Sure, they could have taken a bit more, like proper AOT instead of it being a feature only available in third party commercial JDKs, or some low level niceties like C#.
Because I don't see what else good Java has left out, besides AOT in the box and unsigned types.
https://cs.gmu.edu/~sean/stuff/java-objc.html
Bonus points if it is a RS485 port.
Some language that seem to look good might show their true ugly face...
Lisp and Prolog were forbidden due to how easy the whole exercise would be.
I think I'm more looking for some kind of standardized struct definition that translates easily to llvm IR and is flexible enough for a wide variety of languages to target.
Something like this: https://gist.github.com/thomaswp/8c8ef19bd5203ce8b6cd4d6df5e... (Which doesn't meet my criteria because AFAICT isn't used by anything, but is reasonably close to what I want) or this: https://docs.rs/sap-ast/latest/src/ast/lib.rs.html#1-83 (which seems specific to SAP, I would like something more general)
This is the equivalent of giving an author of a website remote code execution (RCE) on your computer.
I get the idea that you can download the script first and carefully read it, but I think that 99% of people won't.
But you still have data on your system that can get deleted or exfiltrated. Or the script can install something bad.
You have to go out of your way to make something like that run in an fhs env. By that point, you've had enough time to think, even with ADHD.
For the most part, installing packaged software simply extracts an archive to the filesystem, and you can uninstall using the standard method (apt remove, uv tool remove, ...).
Scripts are way less standardized. In this case it's not an argument about security, but about convenience and not messing up your system.
Sometimes you see curl -sSLfO. Please, use the long form. It makes life easier for everybody. It makes it easier to verify, and to look up. Finding --silent in curl's docs is easier than reading through every occurrence of -s.
Obligatory xkcd: https://xkcd.com/1168/> for-docs "ls -lrth /mnt/data"
ls -l --reverse -t --human-readable -- /mnt/data
(I'd put in an option to put the options alphabetically too)
Kind of like positing a master `dry-run` command as opposed to different commands implementing `--dry-run` arguments.
I did something like this:
Then I realised that a bit of logic is needed (or more complicated regexp) to deal with some exceptions and moved onto something else.also, putting it out long-form you might catch some things you do out of habit, rather than what's necessary for the job.
The shorthands are for when typing it at a console and the long form versions should be used in scripts.
Dumb trick: Search prefixed with 2 spaces.
Yields exactly one hit on my machine. In the general case, you may have to try one and two spaces.You see this in all the obvious examples of physical security.
In the case of software it's the installation that's the ritual I guess. Complete trust must be conferred in the software itself by definition, so people just feel better knowing for near certain that the software installed is indeed 'the software itself'.
The issue is not the specific form in which code is executed on your machine, but rather who is allowed by you to run code on your computer.
I don't trust arbitrary websites from the Internet, especially when they are not cryptographically protected against malicious tampering.
However, I do trust, for instance, the Debian maintainers, as I believe they have thoroughly vetted and tested the executables they distribute with a cryptographic signature to millions of users worldwide.
Why trust un-signatured files hosted on a single source of truth? It isn't the 90s anymore.
Like apt, dnf, and others.
The default is more than a single source.
Also, a lot of those install scripts do check signatures of the binaries they host. And if you’re concerned that someone could have owned the webserver it’s hosted on, then they can just as easily replace the public key used for verification in the written instructions on the website.
The issue is provenance. Where is the script getting the binary from? Who built that binary? How do we know that binary wasn't tampered with? I'll lay odds the install script isn't doing any kind of GPG/PGP signature check. It's probably not even doing a checksum check.
I'm prepared to trust an executable built by certain organisations and persons, provided I can trace a chain of trust from what I get back to them.
The --enable-native-access option mentioned in the article is part of a large effort we call "Integrity by Default"[1]. The idea is that a library module can violate invariants established by another module (e.g. access to private fields and methods, mutation of final fields etc.) requires approval by the application, so that a library will not be able to have a global effect on the application without its knowledge, and the correctness of each module could be verfied in isolation.
Now, --enable-native-access is also required to use JNI, but JNI can violate the integrity of Java invariants in a much more extensive way than FFM can. For example, JNI gives native code access to private fields in arbitrary modules, while FFM does not. The only invariant FFM can break is freedom from undefined behaviour in the C sense. This is dangerous, but not nearly as dangerous as what JNI can do.
For the time being, we decided to enable both FFM and JNI with the same flag, but, given how more dangerous JNI is, in the future we may introduce a more fine-grained flag that would allow the use of FFM but not of JNI.
[1]: https://openjdk.org/jeps/8305968
When running with -Xcheck:jni, you'll get a warning when trying to mutate a final field with JNI.
Now, enabling this check by default without harming JNI performance proved to be too much of an effort. However, mutating final fields with JNI even today can already lead to undefined behaviour, including horrible miscompilation, where different Java methods can read different values of the field, for final fields that the JVM already trusts to be immutable, such as static finals, record components, or a few other cases (indeed, there are non-final fields that the JVM trusts to be assigned only once, and mutating those with JNI is also undefined behaviour). As the compiler starts trusting more final fields after this change, mutating almost all final fields will lead to undefined behaviour. Then again, using JNI can lead to undefined behaviour in many ways.
So to make sure your JNI code isn't mutating finals, test with -Xcheck:jni (as of JDK 26).
For eg. we could use Spring + Graal VM and get the application into native binaries without worrying too much about the low level stuff.
What are we missing?
GraalVM is for compiling JVM bytecode to native, architecture-specific binaries.
FFM is like "[DllImport]" in .NET, or "extern" definitions in other languages.
The article shows how to auto-generate JVM bindings from C headers, and then allocate managed memory + interact with externally linked libs via the FFM API passing along said managed memory.
https://www.graalvm.org/latest/reference-manual/native-image...
One of the neatest things I've been able to do is compile a .dll library "plugin" for an application which loads plug-ins by invoking a special exported symbol name like "int plugin_main()" using GraalVM and @CEntryPoint
The entrypoint function starts a Graal isolate via annotation params and no native code was needed
i don't know graalvm, but I've used too much ant, buldr, gradle and maven. I'm not really convinced Graal VM would make anything better just because you are more familiar with it.
The author even says to just use what you like because that part doesn't matter.
we're talking about native code here
Recently saw a new FFM-based zero-copy transport and RPC framework using io_uring at https://www.mvp.express/
An interesting time to be in the Java/JVM ecosystem, meanwhile, back in my Spring Boot app...tho least we're on Java 25
I was using it while dabbling on compiler stuff, it was useful to have a set of concise compilation examples. I haven't touched it much lately, unfortunately, and I added the eBPF because the target was there but had no way to validate it (standalone eBPF validator where?) so I think it's probably somewhat wrong... or invalid at least, maybe that's a separate concern for people who would want this.
https://github.com/llir/llvm
8 more comments available on Hacker News