Running Windows-Compatible .jar files on Linux? - java

Our CE project includes a .jar file which is written for Windows only for some reason. Unfortunately, I do all my coding related projects on Ubuntu and I'm really not willing to install VS on windows and start over on a new environment and lose a lot of efficiency.
The jar file requires some other files to work but the directory formats differ in Linux so I'm getting errors of it not finding the files when I try to open it from Linux.
I've already asked for the source code or a more compatible version but the TA's aren't really cooperative in my case.
Is there any way I could circumvent this problem and fix the incompatible directory formats issue(For example by running through wine)?
Edit: I tried decompiling the jar, but it wasn't fully successful and some of the files came out corrupted.

Because the original maintainers didn't think that this JAR would be run on other OSes, you're stuck placating their arbitrary requirement. You're going to want to use a VM (Wine isn't an emulator and you're going to run into significant pain using it and Java to run a JAR) to set this up and execute their JAR.
Once you get a hold of the source, you can build a new JAR which asks the OS which file separator to use instead of allowing the code to assume Windows. Or use NIO.

Related

running java installer with bundled jre

We currently ship a java(jar) installer of our application. Taking into acount the changes to jdk11 we want our users to have the same easy install experience. So, what we are looking for, is to have just one file that can be run even if there is no java installed, it should just start our old java installer.
Probably, this means that we jave to bundle the jre and have a script that runs the jar, but the problem is how to run the batch file natively ? We need this to work on Windows and Mac. Most tools we are looking into require java to run the wrapped jar.
You have to build 2 different scripts/installers, one for each platform. Even looking at very popular software like Chrome, the platform choice is still there (even though you're usually directed to the correct choice based on the information your browser provides them with)
Depending on how much time you can put in this task, the quickest (and dirtiest) solution would be having an archive for each platform that contains the script .bat for Windows and .sh for OS X together with the jre (also different per platform), ask the user to unarchive and run the script which will run your jar with the packed jre. Otherwise, you'll need to create an MSI/exe for windows and a dmg (or other installer type) for MacOs.
I have done the dmg before with a bundled jre and can try to look for the details if you need them (I no longer have access to the code but can probably find the details). It was a free solution but it did require an OS X computer to create the dmg.
One option that I used before and works very well is install4j but the price is not small.
LE: Self contained packaging - although I haven't used this before, it seems like the best current option for your problem.
And an open source option - packr.
that Self Contained packaging doesn't really help, same for packr, same for launch4j. Because all those just generate a application image with a lot of files and directories.
Problem is before that, as an installer you want 1 big exe (or dmg for mac) that does it all, single click
We are already at the stage like SCP or Packr. Because that is easy or current installer.exe and jre\ sub dir and a batch/sh file besides it. Problem is how to get from that directory structure to a single exe that runs.
So what we should have is something that can zip that in a self extracting archive, when clicking on that it should auto extract to the temp dir of the OS, then run directly a command on it (like a batch file or directly in that extracted dir: .\jre\bin\javaw.exe -jar installler.jar)
But nobody seems to have made such a thing, the closest that we have is eclipse with Oomph:
[1] https://git.eclipse.org/c/oomph/org.eclipse.oomph.git/tree/plugins/org.eclipse.oomph.extractor/src/extractor.c
[2] https://git.eclipse.org/c/oomph/org.eclipse.oomph.git/tree/plugins/org.eclipse.oomph.extractor.lib/src/org/eclipse/oomph/extractor/lib/BINExtractor.java
problem is a bit that is doing the extracting through java and still wants a vm first.

Java Exelsior error when using on other computers

I am using Excelsior to make my jar executable into a .exe and I'm getting errors when putting the exe and folder contents on another computer. The program packs what looks like the java run time into a folder called 'rt'. The .exe runs fine on my own computer but when I try on others I get this error:
Invalid Excelsior JRE directory "C:\ programFolder\rt": path canonicalization failded
Anyone know what could cause this error or if you have used Excelsior could you help me out with this? I have posted on their forums but with no luck.
Are you sure you are copying the EXE file that was processed by the packager (JetPackII), not the EXE emitted by the compiler?
Also make sure to install the latest updates (for Excelsior JET 9 it is Maintenance Pack 2 as of today.)

Jar works from cmd - not from double-click (additional library)

I seem to have a strange issue which is most likely to be caused by not understanding how the including of additional libraries in java work.
I wrote a program that uses jnetpcap.jar to work with pcap files. The application is running fine when I start it from eclipse and has also worked many times by exporting a runnable jar (copying required-libraries to sub-folder). It even worked on other computers.
As mentioned in jnetpcap doc, the computers running windows have put jnetpcap.dll into C:\Windows (according on every machine the x86 or x64 dll)
Anyhow, the following scenario is reproducable on my and other machines:
running the complete eclipse project works
running from cmd with java -jar pcapdump.jar works
double-click jar the gui etc. works - but the "main work" is not done, so no pcap file is used.
I don't see any errors in my logs.
Configuration in eclipse:
added an external user library. pointing to my local jnetpcap.jar and source-jar.
When exporting as runnable-jar with copying libs to sub-folders the jnetpcap.jar gets copied into a separate sub-folder. Like I did it many times before.
Anyhow the described problem exists today and I don't know what I am doing wrong or what may be wrong.

Making my Java program easily distributable

I have installed the Java 3D API on PC via the exe installer, which simply created a new directory with j3dcore.jar, vecmath.jar, j3dutils.jar in a lib sub-directory and j3dcore-ogl.dll in a bin sub-directory.
Netbeans had no issues and my code compiled and executed smoothly, however once I built my project and tried to run it from the command prompt I got an UnsatisfiedLinkError saying that no j3dcore-ogl in java.library.path.
Google came to the rescue and gave me 3 viable solutions:
by copying the dll file into my JRE's bin directory
by adding the path of the dll file to the library path (java -Djava.library.path=dllpath)
load the dll in the program with System.load() (I couldn't get this one to work, actually)
My question is: Is there an elegant solution to this problem, that I missed?
It seems tedious that for each different PC someone would like to use this program on, he'd have to either copy the dll or add it to the library path before it can run. (Side question: How come Netbeans didn't have a problem with the dll?)
Making my Java program easily distributable
If you mean 'easy for the end user' look to Java Web Start.
A passer-by asks:
Can you package the dll dependencies with Web Start?
Yes, but much, much better. You can package the natives for each platform in separate Jars, and supply them only to the platform that uses that native, even so far as partitioning the download between 32 & 64 bit versions of the natives.
JWS puts the natives on the run-time class-path of the application, ready for loading in code.
This all happens automatically for the end user, they click a link, approve the trust dialog(s) when asked, and the application installs - possibly with desktop integration, and appears on screen like magic.
JWS apps. that use natives need to be distributed as all-permissions security level, because the JVM cannot guarantee the actions of anything that 'goes native'.
Edit - After re-reading your question, your issue sounds different. However I'm able to get my running like so, by just dropping all dll files in the same directory as the .bat file starting the java process:
java -classpath ./YourJar.jar;./lib/j3dcore.jar;./lib/vecmath.jar;./lib/j3dutils.jar package.MainClass
And that works on multiple user's PCs, so I know simply dropping it in the working directory works.
I believe it depends on the version of Java being used - 64 bit or 32 bit. The correct dll file (of the same name) needs to be in the working directory.
I think I was getting a similar problem when the wrong dll was being used, and it's not OS-dependent (if your 64 bit OS has 32-bit Java installed, you'd need the 32 bit j3dcore-ogl.dll file).
So the question is, which version of Java are you using (when running outside of your IDE), and which version of the dll are you putting (if any) in the working directory? I don't need any dll files in my path settings to get this working on other's PCs, and did not use System.load(), and did NOT copy files into my user's JRE/bin directory - so I know this is possible without the 3 options you mention.
If you put the dlls in the same directory than you Jar, does it work?
If yes, you could consider distributing it like this.
I guess DLL are searched in all folders in %PATH% on windows. (LD_LIBRARY_PATH for UNIX flavors)
Could you try by adding the path to dll to %path% variable?
It appears that you are trying package a product with many jars as dependencies. You may benefit from One-Jar. It claims to have native dll support.

Is it impossible to embed Java3D in a way that I don't need to install it?

I'm running a big application and a small part of it includes Java 3D, the problem is many users need to use the code, but it isn't practical for everyone to install Java 3D just to run the application if they aren't even going to use that section of the application.
Is it possible through compiling an extra jar, or changing some paths, to include Java 3D in a project without installing it on a system? Or perhaps to manually include any dlls?
The demos at java3d prove that it is possible.
You only need to include the required jar files to your projects distribution.
Yes, it is possible. You will need to pull the required jars and native libraries from the java3d site. I pulled them from the java3d demos, but that requires digging through the xml launch descriptor files.
The place you'll run into the most trouble is when linking to the .so / .dll files. This is typically specified on the classpath before your app starts, but since you don't know what platform you're using until your app starts, it's a catch22.
There are two possible solutions:
1. Bootstrap your program with a simple class that detects the platform and sets up a new jvm (with the proper libraries specified) for the real application.
2. Dynamically load the libraries (I've never actually used this method for native implementations, but I see no reason why it wouldn't be possible).
Unfortunately, neither method is terribly straight forward.
I've done this with no problems (and many users tested that it works, Windows OS) by simply adding the jars to the classpath and dropping the appropriate dlls into the "working" directory where the .bat file running Java started. One catch is I had to have two bat files - one 32 bit and one 64 bit. Each bat file copy/renames the appropriate dll to j3dcore-ogl.dll, since depending on which version of Java (32/64 bit) you're running, a different jar is needed.
Example .bat file:
del j3dcore-ogl.dll
copy j3dcore-ogl-64.dll j3dcore-ogl.dll
java -Xmx2048m -classpath ./YourJar.jar;./lib/tinylaf.jar;./lib/j3dcore.jar;./lib/j3dutils.jar;./lib/vecmath.jar your.package.MainClass
#pause

Categories