Live data from Hacker News

Using jlink to cross-compile minimal JREs

jakewharton.com

61–66 of 66 posts

Re: Using jlink to cross-compile minimal JREs

#61
post #57

Earlier quoted context omitted.

It's a real shame that modularization focused almost entirely on solving the JDK vendor's problems rather than solving the application author's problems. Specifically, modularization can and should have been taken as a chance to allow multiple versions of the same dependency to exist within a single scope within an application. At present, this is sort of achievable by taking control of classloading and invoking defi…

> Specifically, modularization can and should have been taken as a chance to allow multiple versions of the same dependency to exist within a single scope within an application.... Modules do it to the best extent possible, but they don't make it prominent because, quite simply, it's impossible to do in a way that's good enough to be advisable. In order for a library to be properly isolatable, it has to be written in…

It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other.

While libraries directly parsing some sort of conf file may be a little bit of a pattern on the JVM, it doesn't have to be... And the libraries could certainly define a new pattern to allow the user to define different versions of their configs for different library versions.

I agree that, as it stands, modules enhance security by providing a stronger version of the visibility system. IMO that is important but it's just such a low bar to shoot for since it doesn't really improve the situation much more than everyone just following the rules

Re: Using jlink to cross-compile minimal JREs

#62
post #22

Earlier quoted context omitted.

We already have that, it's called a package manager. The concept has a number of problems (multiple runtime versions for multiple programs, who pays for and controls the repository, etc etc).

I don't know, my package manager doesn't let me download an application without runtime - say QBittorrent without Qt or Deluge without Gtk and Python - double click on an icon, and then say "It looks like you are trying to write a letter run an app that needs a library" and then proceeds to fetch it... from my package manager. I mean, 80/20 principle. You would only have to write code for the dozen or so runtimes, an…

> my package manager doesn't let me download an application without runtime

That's not true (most package managers have options to force downloads without dependencies), but anyway why would you even want to do that, considering you eventually have to download the runtime anyway...?

> And then when it is going, people would add metadata to their apps themselves, and we would no longer have to ship the runtimes together with the apps.

We had that too, it's Java Web Start and the current MS equivalent (clickonce or whatever it's called). Never worked particularly well for Java (which is why it was removed), works a bit better for Windows because, surprise surprise, the OS vendor made deployment conditions more predictable, as it controls both OS and runtimes. They would never have an incentive to provide the same to third-party runtimes.

> Think of the metadata it like a 21st century shebang line.

The problems of that approach are legion.

The hard truth is that shared libraries (and hence shared runtimes) are an accident of history, meant to cope with a scarcity of storage and bandwidth that we've long overcome. The ideal program is a single static executable that Just Runs regardless of what is going on around it. Everything else is a source of unnecessary complexity for both user and developer.

Re: Using jlink to cross-compile minimal JREs

#63
post #57

Earlier quoted context omitted.

> Specifically, modularization can and should have been taken as a chance to allow multiple versions of the same dependency to exist within a single scope within an application.... Modules do it to the best extent possible, but they don't make it prominent because, quite simply, it's impossible to do in a way that's good enough to be advisable. In order for a library to be properly isolatable, it has to be written in…

It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other. While libraries directly parsing some sort of conf file may be a little bit of a pattern on the JVM, it doesn't have to be... And the libraries could certainly define a new pattern to allow the user to define different versions of their configs for di…

> It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other.

It suffers from the same problems -- doesn't work if a library has an implicit assumption it's the only copy, and does otherwise. It's the best anyone can do, and modules do it as well as it can be done, it's just not something you want to encourage because there are too many cases where even the best is just not good enough. I don't think that instantiating multiple instances of a library whenever there's a version conflict is the right default. It turns an accidental configuration situation into a significant runtime choice.

Still, if you want a tool that makes this best-effort attempt easier, take a look at layrry: https://github.com/moditect/layrry. It basically exposes module's "multi-versioning" as a configuration rather than programmatically.

> IMO that is important but it's just such a low bar to shoot for since it doesn't really improve the situation much more than everyone just following the rules

Actually, it's something that can only be done deep in the VM. Modules exist to provide some runtime guarantees that nothing else can (except the SecurityManager, but that was so problematic that few used it and fewer still did it correctly). Without modules, there can be no strong security guarantees made.

Re: Using jlink to cross-compile minimal JREs

#64
post #63

Earlier quoted context omitted.

It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other. While libraries directly parsing some sort of conf file may be a little bit of a pattern on the JVM, it doesn't have to be... And the libraries could certainly define a new pattern to allow the user to define different versions of their configs for di…

> It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other. It suffers from the same problems -- doesn't work if a library has an implicit assumption it's the only copy, and does otherwise. It's the best anyone can do, and modules do it as well as it can be done, it's just not something you want to encourage…

As far as I can tell, Layrry does not allow two versions of the same library to be in scope at the same time.

Re: Using jlink to cross-compile minimal JREs

#65
post #63

Earlier quoted context omitted.

> It seems to work just fine without anything horrific happening in Rust. Direct dependencies can be renamed and indirect dependencies simply don't clash with each other. It suffers from the same problems -- doesn't work if a library has an implicit assumption it's the only copy, and does otherwise. It's the best anyone can do, and modules do it as well as it can be done, it's just not something you want to encourage…

As far as I can tell, Layrry does not allow two versions of the same library to be in scope at the same time.

I don't know what you mean by "in scope" but modules do allow multiple versions to exist in the same process in different layers. That's what module's entire layer mechanism is about (internally, it uses class-loader isolation), and Layrry configures module layers (that's where it gets its name). It's in one of the first examples: https://github.com/moditect/layrry

So modules absolutely do support that by design, but again, for that to work well you need to really know what that duplicated library does (same goes for Rust or any language), and it's not a recommended practice in general because it can fail in really horrible ways if you're unaware of some implicit assumptions in the library.

Re: Using jlink to cross-compile minimal JREs

#66
post #26

JLink is a pretty nice tool - easy to use and understand, relatively fast, big app size wins. A few misc thoughts: Figuring out what modules you need to ship can be done with the jdeps tool, but, you have to watch out for some gotchas. One is that you have to run it on each JAR or set of jars. It's slow so it helps to do this incrementally. Another is that some critical JVM functions are implemented as 'plugins' that…

I know that you're hawking your own software, but it looks quite cool. However, I wouldn't want to be a pioneer. Who uses it and for what? Do you have testimonials? Or maybe other HNers, have you used it?

We now have a brands and testimonials section!

https://hydraulic.software/

Post reply on HN