4 ms·
Note that FFM requires that you explicitly allow the use of native code with --enable-native-access (and soon JNI will, too: https://openjdk.org/jeps/8307341 ht
by pron 3y ago
Note that FFM requires that you explicitly allow the use of native code with --enable-native-access (and soon JNI will, too: https://openjdk.org/jeps/8307341 https://openjdk.org/jeps/8307341). As JEP 454 (https://openjdk.org/jeps/454 https://openjdk.org/jeps/454) states:
> To allow code in a module M to use unsafe methods without warnings, specify the --enable-native-access=M option on the java launcher command line. Specify multiple modules with a comma-separated list
The warnings will become errors in a later release.
This means that no library you're using (even some transitive dependency) can call native code without you, the application author, knowing about it. This restriction on native code is part of the work on "integrity by default": https://openjdk.org/jeps/8305968 https://openjdk.org/jeps/8305968
- nvm0n2 3y agoBut how is that connected to the concern expressed? Problem: If the JVM ecosystem starts to depend more on native code it gets less pleasant to work with. Answer: There is this command line flag that is used to activate the FFI. There doesn't seem to be any relation between these two things, unless you're trying to imply that because of the flag people just won't use the FFI at all and will write pure Java instead. Which would be strange, as the justification for investing so much into Panama in the first place is the expectation that it will be used, because native code is getting more important rather than less. There are two ways to avoid the JVM ecosystem becoming crappy due to native code: 1. Encourage the development of pure Java libraries. 2. Make native code work better. Panama tries to do (2) but it's got a lot of missing functionality that the scripting lang ecosystems nail. How do you compile a Java library that uses native code? Python/Node/Ruby worlds know how, but OpenJDK ignores the question. How do you ship a Java library that uses native code? Python/Node/Ruby worlds know, but OpenJDK ignores the question. These problems have been pointed out before and Panama guys just say not in scope. The community hasn't come together to solve these problems either. Maven/Gradle are too disorganized to come up with answers in the absence of any leadership from OpenJDK. Everyone reinvents the wheel when it comes to loading shared libs from JARs. It's a mess and nobody is solving it. So that leaves (1), encourage the development of pure Java libs. This also isn't working. People write in C/C++/Rust because that way everyone can access the functionality regardless of what ecosystem they work in, so such projects get the biggest collection of stakeholders. That's more important that implementation language, so Java is losing badly everywhere. Pure Java libraries are never best in class anymore (they once sometimes were), which is how you end up with situations like this: https://blogs.oracle.com/developers/post/open-sourcing-jipher https://blogs.oracle.com/developers/post/open-sourcing-jiphe... > We’ve chosen to base our products on OpenSSL because it is the most open and most widely used cryptographic toolkit on the planet. At Oracle, we make extensive use of the OpenSSL 3.0 FIPS 140 provider to operate in regulated markets. We like the OpenSSL FIPS provider so much we decided to build a Java cryptography toolkit on top of it called Jipher. By converging on a single toolkit (OpenSSL) we reduce our attack surface, simplify security patching, achieve assembly-optimized performance, and help our customers meet regulatory compliance requirements. It means the first use of Panama in the wild is to replace the built in memory safe Java SSL stack with OpenSSL, a giant pile of C with a long history of memory safety vulns, and it's Oracle itself doing this because OpenSSL is "the most widely used" library and nothing else matters. They even say replacing Java SSL with OpenSSL will reduce the attack surface. If even the well funded OpenJDK developers working in Java can't outcompete the poorly funded OpenSSL devs working in an unproductive language, then what chance do other Java library devs have? None at all! Native code will always win because it will be faster and have a bigger community, and in the end there's safety in numbers. This is very sad. It means Java's future is as a collection of thin wrappers around bug-prone C APIs accessed via Panama, which, as you are well aware pron, will make Loom virtually useless as it cannot work with native code by design. A long steady decline is the most likely path here, in which Java libs get hollowed out to try and keep up with the functionality and performance of native libs (e.g. http/3), and so Java devs steadily lose the benefits of the JVM. There are things Java could do to avoid this fate but the OpenJDK people are never going to do them.
- pron 3y ago> How do you compile a Java library that uses native code? Python/Node/Ruby worlds know how, but OpenJDK ignores the question. Because you compile it like any other Java library. > How do you ship a Java library that uses native code? Python/Node/Ruby worlds know, but OpenJDK ignores the question. It doesn't. jmod files and the jmod tool were added in JDK 9 precisely for that (and other things, too). > If even the well funded OpenJDK developers working in Java can't outcompete the poorly funded OpenSSL devs working in an unproductive language, then what chance do other Java library devs have? None at all! People aren't really rewriting OpenSSL in Python or JS, either, but high-level languages are many times more popular than low-level ones [1], and you're misreading the normal behaviour of a fragmented market, when it's worth it to compete and over what. I don't think any language today has a healthier library ecosystem than Java. That's not to say it's as good as wish it would be, but no one seems to do it better. There is, however, a problem with build tools not supporting newer JDK features (that are coming faster now than before) and we'll need to do something about that. [1]: https://www.devjobsscanner.com/blog/top-8-most-demanded-programming-languages/ https://www.devjobsscanner.com/blog/top-8-most-demanded-prog...
- geodel 3y ago> There is, however, a problem with build tools not supporting newer JDK features This is important point. From my experience in Enterprise IT the build pipeline is roughly at JDK-8 level in terms of generating deployable artifacts. I have contorted by maven build config to invoke jlink on builder nodes to make standalone artifacts that won't need JDK on target machines. But it is not optimal for few reasons 1) I have to manually track what JDK modules I need to include in build. 2) Its hard to get new JDK installed on build machines for ones, forget the dot upgrades to keep it latest bug fix level. Their reasoning is build machine is just to invoke maven build. Only target machines need latest patched JDKs. 3) From JDK-8 they are now directly jumping to make docker/kubernetetes builds which are fine but totally different direction if I am just looking to make no-fuss standalone Java application to run on a Linux VM. As one can see some of these are organizational issues not necessarily technical one. But as single developer with no power to force IT infra teams on supporting alternate workflows I am basically stuck with JDK-8 workflows. What is missing in setup is somehow to tell maven I want to generate a standalone Java app using jlink for linux ver.N target so gather up all modules / java binary and other tools required based on information in this pom file without relying on JDK version of builder . This should be able to run builder machine so it remains integrated with current build pipleline.
- josephcsible 3y agoOh no, not more command line flags to allow functionality that always worked before! That same decision with modules and reflection in Java 9 is why so much stuff is stuck on Java 8 still.
- pron 3y agoIt has nothing to do with why so stuff is stuck on Java 8. In fact, one of the goals of those flags to prevent that from recurring. 99% of the problems migrating from JDK 8 are due to low level libraries depending on internal implementation details that were never subject to backward compatibility and that changed in JDK 9, which was a huge release (https://openjdk.org/projects/jdk9/ https://openjdk.org/projects/jdk9/). Libraries became intentionally non-portable, and applications didn't know that they were made non-portable by the libraries they were using, often inadvertently (transitive dependencies). Now, whenever a library does something that bypasses the spec, i.e. the portion that's covered by backward compatibility, it cannot do it without the application knowing about it and approving it. An application that sticks to the spec and enjoys Java's compatibility, portability, and safety doesn't need to add any flags.
- _old_dude_ 3y agoDevelopers should understand if a dependency use C bindings. But why bother end users with a command line flag. Perhaps there is a manifest entry/flag so the command line flag is not required ?
- pron 3y ago1. Application developers frequently don't know how the libraries they're using work, and often don't even know what libraries they're using because they're transitive dependencies (even a version update of a library can pull in a new transitive dependency). If a library imposes any kind of risk on the application, the application has to acknowledge that it accepts it. 2. The last word is given to the application, and the point is that libraries must not make decisions that have a global impact on behalf of the application. That's why an executable JAR, i.e. an application, can grant such permission in its manifest but library JARs cannot. See more here: https://openjdk.org/jeps/8305968 https://openjdk.org/jeps/8305968, https://openjdk.org/jeps/8307341 https://openjdk.org/jeps/8307341