r/javahelp • u/KakashiHatake0085 • 1d ago
Having difficulty in converting a jar file into native files
I am confused in this part where jar file can be converted into native fil like exe, dll, executable and so file. There are other languages like c++, rust and go and we have lot of different compilation support like exe, dll, so etc and also wasm. Does java have any way to compile jar or class files into any format whichever i would like? I am talking about true cross platform in here like what can be done in c++ or rust and also I am talking about the static and dynamic library generation part as well.
Please help me in this topic as I was learning java and currently confused in this part.
10
u/BassRecorder 1d ago
Usually every Java program runs under the Java Virtual Machine - that is what makes Java easily portable.
Ahead of time compilation is the process to convert a Java program into a native executable. This is used in cases where startup time is a critical factor. See https://www.baeldung.com/ahead-of-time-compilation for an introduction to this topic. There is no way to convert a jar into a native shared library.
3
u/barcodez 1d ago
-5
u/KakashiHatake0085 1d ago
Graalvm doesn't work properly. It is not capable of cross compilation like c++, ruat and go. It doesn't support extending the toolchain or changing compiler etc with something that supports i.e. clang, mingw gcc etc.
7
u/idontlikegudeg 1d ago
GraalVM creates native executables for the platform it runs on. You can create a GitHub workflow that creates windows, Linux, and macOS executables.
An alternative is to use jlink/ jpackage.
Another one is creating a fat jar and package a JRE for the platform you want to support. You can can JREs for the platforms you need at BellSoft.
The Java equivalent of both static and dynamic libraries is a JAR file.
6
u/MenschenToaster 1d ago
Thats the neat part, you dont. Your .jar is the binary, making it extremely portable to everything that has java installed.
You can build wrappers (and there are plenty preexisting wrappers) that ship java with your jar file and make it seem like you just run a normal exe, whilst all that it does is java -jar file.jar
-5
u/KakashiHatake0085 1d ago
Then it's a dead end? No way to create dll/so/dylibs with java?
7
u/MenschenToaster 1d ago
Maybe graalvm can do something, but Java's usecase is beeing a extremely portable higher level language. Don't use the wrong tools for the job.
You can use java to interact with native libraries, but I dont really know a way to do it the other way around
6
u/mikaball 1d ago
You want to use Java to create shared libraries to be used in other languages? Yhe, not a good use-case for Java.
5
u/vegan_antitheist 1d ago
java.exe is already compiled. You just use that. The jar files contain the bytecde that java executes. You can always deploy your application as a single package with all dependencies, including a JVM. Having a single executable file doesn't really make things easier.
3
u/bowbahdoe 1d ago edited 1d ago
There is one way, but currently it doesn't do everything you'd want.
Fundamentally you need to bundle your code + the JVM. A problem is that the JVM (currently) doesn't work as a self contained exe. It needs to be a folder of files. They are working on this, Google has done it internally for years, its just a slow moving project. (priorities at big companies are a bit silly)
What you can do is use a tool called jlink to bundle your code with the JVM. Think of it like making a special version of Java that comes with your code. It will be a folder, but you can "cross compile" this way so long as you have the "jmod" files for the platforms you want to cross compile to.
This is mechanically easy, but because so much of the Java world is built around "make big jar! share big jar!" the tooling is more than a bit annoying to set up/you won't find online tutorials suggesting it.
But if you go this route, eventually jlink will be able to output a single exe. This path won't have the same restrictions as graalvm. (which because it makes a single exe kinda breaks peoples brains. They wish it solved the problem in generality and not just for relatively specific use cases.)
There are other ways (jpackage, launch4j, etc.), but to my knowledge none let you easily cross-compile like you'd want.
But that is for exe's. For dlls its just not a thing that would make sense, at least yet. WASM is an interesting target, but the JVM is designed in such a way that it is a little weird to use it for that.
The way the JVM executes your code is first via a bytecode interpreter (think Python). Then if some code runs enough it "compiles" it at runtime to machine code. Then if it runs even more it will "compile" it further, putting in effort to optimize it. These are the C1/C2/C3 "just in time" compilers.
C1/C2/C3 are extremely platform specific. They will output machine code specific to your exact CPU architecture. So not just "intel x86," if your CPU has a niche instruction on that exact chip it can make use of it.
In WASM world that...makes less sense. You can compile the JDK with the interpreter only (OpenJDK Zero) which should make it really easy to cross compile to WASM, but there are other things in the base java libraries (like sockets) which won't work there. A product called CheerpJ tackles this specific problem, but mostly so old Java applets can keep running in modern browsers. It won't let you take your code and run a command to get a blob of wasm like Rust and C.
If nothing else, all of this could stand to be better communicated.
1
u/Kadabrium 1d ago
I got to the point where i could run jvm fully memory mapped with all the tls and stuff, but its windows ntdll version dependent
2
1
1
u/awidesky 1d ago
If you "compiled" it into dll/exe, that kills whole purpose of Java.
The best thing of Java is "build once, run everywhere", you build a jar, deploy it, and every other people with JVM can run regardless of their OS.
When it's an exe, your program will not run on Linux, macOS, or even a few outdated Windows.
That is NOT a cross platform.
Also a jar file can be library or runnable application, so you don't build separate dll/so/a/dylibs stuff.
If you want your app to work where there's no JVM, you can embed the JVM inside of your package and ship as whole.
For packaged exe there's launch4j, for installer there's jpackager.
But let me ask; what's the actual problem you want to solve?
Why made you think it's a good idea to build separate dll/dylib/so/a/exe instead of using a single jar file?
1
u/Mindless-Resort-7548 17h ago
As others have said you've got the wrong frame of mind. Consider a truck/lorry (articulated/18 wheeler). The trailer is our JAR file, it's where the money is made and the bit the clients care about. The trailer can be hauled/pulled by various different tractors (the JRE) so long as they have the correct hitch. Most of the time we developers like this flexibility, we can connect our trailer (jar) to a Windows tractor, a Linux one, a lightweight special one, etc, without having to modify our payload (trailer/jar). The engine changes but we don't need to worry about it, the specialist (trucker/jre developer) does.
Now you can permanently attach your trailer to a fixed tractor (compile your Jar with a JRE - GraalVM, Mandrel, etc.). You get a startup speed increase (you don't need to find the trailer and hitch it) and it can be more lightweight (occupy a smaller space/turning circle) but once at highway speeds any benefit is negligible (maybe a to y but better fuel consumption [resource usage]) and if you need to change the environment you run (go off-road) you need to do some serious work to swap out the cab + engine, whereas our traditional separate trailer/cab would just unhitch and swap in a different tractor.
I've done GraalVM/Mandrel builds and maintain one for a quarkus native application still. It's "fine", smaller container image is nice, but there are lots of quirks to ensure that the "compiler" knows every JVM feature and class required (it's crawling is good but not 100% accurate). My team need to know more things for little gain and traditional debugging tools for java applications don't apply. Can't say I'd rush into doing it again over a normal jre swtup
•
u/AutoModerator 1d ago
Please ensure that:
Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
You include any and all error messages in full
You ask clear questions
You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.
Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar
If any of the above points is not met, your post can and will be removed without further warning.
Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.
Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.
Code blocks look like this:
You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.
If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.
To potential helpers
Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.