Understanding Deployment on Java 9+ - java

After ignoring Java updates for quite some time, I now want to move on from the somewhat shady Java 10.0.2 Runtime I found somewhere to Java 13. As it turns out, Oracle stopped the "monolithic" JRE philosophy after Java 8 and I can't seem to find any definitive answers to my questions on how I'd go about deployment.
Here's what I think stays the same:
IDE (eclipse) workflow mostly stays the same
If I want to use the program myself, I can compile it to a .jar that will run on the JVM that comes with the JDK, just like with a Java 8 runtime
Now, here comes the tricky part I can't wrap my head around: Deployment on other machines
Create a module-info.java that lists the dependencies of that program
Compile a .jar as always using the eclipse dialogue
Use jlink to create a runtime image for that program to ship alongside
...But what now?
How are these images making the program work? I read that they're some sort of small JRE for that program alone, which would remove the need for Java to be installed on the target system, but how would that be cross-platform?
Or are they some sort of "patch" to the JRE that is available to download from the official site? That would explain why that is still being updated, but it wouldn't remove the need for Java to be installed on the target machine.
TL;DR:
Is there anything wrong with my understanding so far?
How do jlink-ed runtime images work?
How are they cross-platform?
Does the target machine still need any sort of pre-installed Java-related software e.g. a runtime / the runtime provided in the link?
Thank you very much for reading through my wall of text and thank you in advance for the answer!
EDIT: Made the point of question four clearer.

All my questions have been answered by Slaw in the comments to the original question, so I'll sum them up here in this answer.
My understanding so far is correct
jlink creates a mini-JRE with the modules the program needs, as specified in module-info.java
They're not, one would need to e.g. Linux-JDK to create a linux-specific version etc.
All files needed to run/interprete the program are contained in the runtime image
Also thanks for the extr info! I'll make sure to look into JMOD, and from what I read about jpackage, it's something to be very excited for.

Related

running java code form terminal getting error

I found some reference that says I can add #!/usr/bin/java --source 12 at the beginning of the file and run the file directly from the terminal.
I am able to run using this on my local machine, however, when I tried the same on Github action I'm getting the error error: invalid value for --source option: 12
I'm not really an expert in shell scripting or java, can someone help me understand what this --source means is it the java version, I tried setting up the same version (jdk18) on Github action but still did not work.
java (the runtime executable) can only run class files. Until, that is, java12, where a normal JDK distribution (and not the bizarro JREs that some packagers like Azul publish ^1) has a java.exe that can run java files straight up. It's simple sugar - the compiler is still involved, of course. It's just that java will execute it for you.
You don't need --source 12; just java MySourceFile.java is fine. Edit that comment at the top of your source file, it should just be #!/usr/bin/java. The thing you do need is that java on your command line PATH is a java v12 or higher, and it is not. There isn't anything your java source file can do about this, you're going to have to impose on your users to have at least java12 installed or this simply does not and can not be made to work. It looks like you're on some linux distro or other; apt or yum or snap or whatever package manager you have will tell you how to fix this: Install java17, and uninstall the rest or use java-alternatives or whatever mechanism your package manager has to set the default executable (the one /usr/bin/java links to). Read the documentation of the package supplying java17, possibly following some links to the generalized java infrastructure package, it should tell you.
Mostly this is a red herring, this just isn't how java files are distributed. It's virtually pointless because:
Java is not a language that tends to be used for quick shell script-esque things. Such things tend to be self-fulfilling prophecies: Because nobody does this, library authors aren't thinking about it when they develop their APIs and the users of their libraries won't file enhancement requests for this either. Because common libraries aren't convenient when used for quick off-the-cuff shell scripts, java isn't used for it, thus perpetuating the cycle.
Any serious java app would definitely involve packages, dependencies, and more - and such apps cannot be run like this.
Class files are as platform agnostic as source files are. There is no sane reason to distribute java-written shell-script-esque tooling as a source file instead of a jar, except for off-the-cuff editing off them, which gets you right back to point #1 and #4.
The java core APIs work on a model of lowest common denominator: If there is a major OS that cannot or doesn't work in a certain way, then java simply does not expose this at all. For example, on all posix systems (i.e. pretty much every major OS except windows), you have your usual TERM, KILL, HUP, etc signals. Java core libs don't let you interact with them (unless you dip into hidden sun.misc.* API which doesn't reliably work in the first place). This makes java extra unsuitable for quick command line scripting where you want a different model: If at least one OS can do it, the language should have a library for it, and that library should simply fast-crash if you attempt to use it on an OS that doesn't support it. One easy way around this is a third party library that adds support for OS-specific stuff, but your model of distribution (stick #!/usr/bin/java at the top and distribute a source file) cannot include dependencies.
Java as a runtime model is mostly focused on running things eventually very quickly, at the cost of starting off slowly. This is fantastic for web servers which need to run efficiently but will be running for quite some time. It's utterly unsuitable for shell scripting, though.
CONCLUSION: You don't want to stick #!/usr/bin/java at the top even if you could make it work.
[1] A JRE is a java distribution without compilers and other development tools like jstack. These cannot run java SomeSourceFile.java, obviously; they do not have a compiler. However, JREs died - there are no JREs anymore; JDK8 is the last one that shipped with an official JRE. The JRE serves as a distribution model: The end user installs a JRE, and you ship your jars to them. This model is obsolete (you are now responsible to get something that can run your class files on the deployment machine), and therefore JREs died. However, some packagers of OpenJDK builds, such as Azul, still publish them, confusing matters. Hence, 'bizarro'. Azul and co have relatively good reasons for doing it, but, you shouldn't be using these unless you really know what you are doing.

Java behaving in a different way on arm64

I am still working on the issue Java AWT Fonts scrambled which I posted here a while ago. More Debugging has been done, and it seems like the arm64 java is the problem. When running 32 bit java on arm64 it is working fine, same on amd64, arm32 and x86.
Is arm64 Java expected to behave different with that code? Shouldn't Java react the same way on every architecture? If yes, where could I open a Bug for that? I am using Oracle Java Runtime Environment if that matters. Java is so complex that I am not sure which is the right place to open that bug so it can get adressed and investigated.
Java is supposed to be platform independent but there are limits when resources of the underlying system need to be used. In that case platform dependency comes into play and you might see different behaviors with different JDKs. Fonts are provided by the operating system so you have some kind of platform specific stuff going on here as well.
Your original question and this one lack some fundamental thing: A workable source that shows the effect on your system. With that it would be possible to try to reproduce your problem on other peoples' systems and might come up with an answer why you have this effect. Your original question e.g. lacks the information what Font you're actually using and I don't see any code where you write the text that appears scrambled.

Patching a bug in the JDK for an individual application

I have established through another question that the problem I'm having with my JavaFX program is due to a bug in the JDK that is not going to be fixed anytime soon. I was even informed that the bug is in PrismTextLayout.
So having found the source code for this, how would I implement some kind of patch which would allow me to fix this bug for my application only. Obviously if I did fix the problem, I would contribute it back to a future JDK, but for now I just want a quick fix.
I thought a simple google search for patching the JDK, etc would turn up heaps of information, but actually, virutally nothing.
Can someone, if not explain how to patch, at least point me in the right direction for some documentation on this subject.
Patching a JavaFX class without actually building the whole JDK or JavaFX is quite easy. I did that for example for the class SVGPath some time ago.
Extract the class source from the source zip which is distributed with the JDK and add it to your project in the correct folder according to its package name. In my case this would be javafx/scene/shape/SVGPath.java.
Explicitly add ${JDK_HOME}/jre/lib/ext/jfxrt.jar to your classpath.
Run your program with the java options "-Djava.ext.dirs=".
This procedure is essential to be able to override the existing classes in jfxrt.jar.
That is it.

Compiling this OCR Library Code

I came upon this simple Library that someone wrote in java GetImageText.java for OCR in images so i tried compiling it on my Ubuntu via terminal but i get several error as shown below in this paste :
Compilation Errors
Can Someone help me with it , it is absolute necessity that i test this code , its explanation can be found here
I think the problem is that i do not have com.sun.image.code.jpeg in my system, although java is definitely installed. Although I am not sure how to import this package without using an IDE.
The problem is that the library you are trying to recompile depends on INTERNAL classes1. Portable libraries are not supposed to do that!
What has happened is that the class has been removed or replaced. This happens from time to time, and that is the reason that people are not supposed to write code that depends on INTERNAL classes.
Solutions:
Bug the authors of the library to fix the problem.
Figure out which version(s) of Java that the library supports, and stick with those.
Find an alternative library that supports the version(s) of Java that you need.
Non-solution: Compiling the library on an older version of Java and running on a newer one is likely to fail. The class needs to be present at runtime, as well as at compile time.
1 - Anything in the "com.sun" tree counts as INTERNAL. Sometimes people have no choice but to have such a dependency. However, they still needs to deal with the potential consequences for portability.

This program wants jpargmp

I am trying to compile a pidigits program from the language shootout. The java one wants jpargmp. I can not find any information whatsoever on jpargmp. Can anyone help me?
jpargmp is a native C/C++ library that the program depends on.
If you have a pre-compiled version of the library (called something like libjpargmp.so on *nix or libjpargmp.dll on Windows) ensure its in a directory which is specified in the java.library.path system property. If you don't have a copy of the library, you may have compile it - See this question
There's a discussion forum for the benchmarks game ask your question there!

Categories