Deploy Jar With Java? - java

I was wondering how to include Java itself with a jar file so that people don't have to have Java installed already. Is it possible and if so, how do you do it?

To execute the jar in the first place you'd need to have java installed. So it would be best to include a JRE installer in a separate file if you'r including one. Also, you'd have to have a different installer for each target platform so this would be somewhat impractical for general distribution because of the inflated file size.

This is like asking "Can we include the chicken that lays the egg, in the egg?". Answer, no.
As to solving the bigger problem though, there is at least one strategy that might work well for applets, JWS apps. and (possibly) single Jars of desktop apps. that are launched from a link (I've never tried that, though). This approach uses JS to check for the right JRE before providing a link to the Jar.

In order to get a computer to do something, you need to have code that the operating system knows how to handle. Most modern operating systems do not know how to handle Java code unless you install a Java Runtime Engine - to them JAR files are just ZIP files.
Hence you need some code which can be executed directly (without Java) and the simplest is just to use a Java launcher. Many exist - see Java packaging tools - alternatives for jsmooth, launch4j, onejar - but e.g. launch4j is maintained and supports the <path> tag to specify a relative path to an included JRE. Those are unfortunately rather large, but you could provide two versions. One with the JRE, and one without (which then prompts the user to install a JRE).

Related

Package JRE and Jar in to a Windows Executable (exe)

I wish to package both my current system's JRE with a Java (JAR) application that I have created. On Mac I can simply create an app bundle and write a simple script to wire the two together. On Windows I am having trouble finding such a simple solution.
I tried launch4j, but to the best of my knowledge this does not let me package the JRE inside the executable; it must remain as a relative file.
I tried exe4j, but this also does not let me package the JRE within the exe.
My project does not use modules, so unclear how I can incorporate jpackage.
I want to distribute the file (as a portable non-installed app) to people working within my company. They are mostly somewhat computer illiterate, and will be scared off by seeing TWO files (one exe, one JRE).
I also do not want to deal with the headache of asking them to install a java runtime themselves, and end up with everyone having some different runtime. Simply, it is much easier for me to package the JRE with the Jar together as a single file and deliver to the end-user. We are doing this with our mac distributions, and everyone is happy.

Deploying JARs with Java 9 and above (JDK11 in this case) (JLink confusion?)

I'm a Java veteran, but I've been using JDK8 for a long time. I've decided I finally want to upgrade, so I've been using Java11. I've been enjoying the new features, but I've gotten the point where I need to deploy my software.
In the past I would export a runnable JAR from Eclipse and bundle it with an appropriate JRE. Then I'd use both to run the software from an OS-specific program (e.g. an EXE file that fires up the bundled JRE with the given JAR). Of course, now this isn't really an option because JREs are a thing of the past. Supposedly the new system in its place is much lighter weight and straight forward, the only problem is I can't figure out how to actually use it.
I've been reading about how to deploy programs with JDK9 and above and have seen people mention JLink and link documentation to it, but I can't seem to find a straight answer on how to just simply export a runnable JAR. The thing is - I don't really need all of the module support and don't really want to have to configure it. Is there a tool for simply exporting something I can run? How is this done now?
Sorry if this is a dumb question, I'm just genuinely confused at how this all works and can't really find anything online that lays it out in a clear and concise way. There's a lot of documentation on JLink and what it does, but I haven't really found anything that explains the root purpose for all of it.
TL;DR; how do I export working Java programs with JDK9 and above using Eclipse (latest version)?
Thank you for your time!
...how to just simply export a runnable JAR.
Well, if you're not planning on using modules for your application classes, the JAR part should be the same as before. You basically just have to create your own JRE using jlink, e.g.:
jlink --add-modules java.se --output jre
That would create a jre folder with a runtime image that includes all the java.se modules.
You can then bundle that with your JAR like before.
The interesting part here is that you can pick and choose which modules go into this runtime image. java.se is an aggregator module that transitively includes a bunch of other modules. But you could also specify your own specific list of modules, leaving out some of the ones you don't need, making the final runtime image smaller.
I've spent literally months on trying to figure out how to create a single, clickable executable using Java 9+. I now conclude that it is impossible. Whether you use jlink directly yourself, or indirectly via Maven or Gradle, the result is that jlink produces a full directory structure that you are left to "distribute to your users" (somehow, I guess magically, since nothing in Java 9+ tells you anything about how you're supposed to do this). Then, once your user (somehow) has this directory on their machine, they are forced to invoke runtime-image-directory/bin/your-program-name. As though your user is a programmer who is happy to have to install a directory structure, and drill down to invoke a specific file name, which is buried in a directory with lots of other files, rather than being a user who USED to be able to simply double-click on a .jar file to run it. This makes me really wonder if whomever designed all this thought at all about the "user experience". The fact that there appears, as of Java 9+, to be NO WAY to simply deliver ONE file (such as a .jar) to users, together with the fact that just BUILDING this "runtime image" is fantastically complicated, means that developers are going to abandon Java in droves. It really seems to me that the brainiacs at Oracle simply didn't think this through. They have created a death knell to Java by making something onerous for developers to build and distribute, and onerous for users to invoke. I don't see how this situation can be allowed to remain without Java ultimately dying off. Somebody please correct me if I am missing something here, but I've spent months now trying to figure out how to create a runnable jar in Java 9+, USING MODULES, and it appears there is no way to do it.

How do I create an Installer for a Java Application?

This is still awhile down the road for me but for my Project Implementation class we have to create a program and then distribute it. I have written an application in Java and from the specification I have made in the previous class (Project Design) my application will need to be platform-independent.
For mac and linux the user can just run the jar file from the terminal, but for windows I would like to have the Application installed to the path user chooses (default: C:\Program Files(x86)\NameOfApplication), Create a desktop shortcut (if the user wishes to have one), install under the start menu (if the user wants it to) and then also show up in the add\remove programs list.
Is there any easy way to do this?
Is it any harder if I did decided to create an installer for mac and linux?
Thanks in Advance.
You can create an installer with NSIS, even for a Java application.
You might also consider distributing your application via Java Web Start.
There are opensource installer generators for java. I have never used one before. Here is a good resource of links
I recommend using Java Web Start.
It has several advantages.
Available for all major desktop platforms
Single distribution for all JWS-enabled platforms
Code-signing and sandboxing
Versioning and incremental updates
Automatic installation of JREs and optional packages
It has one major disadvantage.
Internet connectivity is required if JWS, JRE, and/or an Optional
Package is not present on the system
Have a look here and here
Install4j does what you want, although you have to pay for it. Personally, I am not aware of any free alternatives. You can make installers for Linux and Mac OS as well.
you can use Exe4J, see http://www.ej-technologies.com/products/exe4j/overview.html
You can do most of that using standard JNLP:
http://docs.oracle.com/javase/1.4.2/docs/guide/jws/developersguide/syntax.html
You make a JNLP file that takes the executable JAR from some local (or remote) location and creates a Desktop icon for it (of your chosing). Only difference is that the actual JAR will be placed in the JDK's jar cache directory (not in a directory of your choice - I don't think the user would care much).
The huge advantage with this is that if you make a JNLP that installs the jar from a remote location, you can remotely upload a new version of the jar to that location, and when the user next accesses the jar locally, your latest version will be downloaded and placed into local cache.
Also I recommend you use a smart "fat JAR" builder, which packages all dependency jars inside the executable jar. Eclipse IDE has a way to export a project in this format (and also adds the necessary class-loader so that all works ok from on fat jar).
If your target OS is windows I highly recommend Advanced Installer. It's very very easy to use and will let you create your own native microsoft installer (.msi) with specific target Java VM and a bunch of useful windows features, even in the free version. Note you can also include a private jre into the package.
http://www.advancedinstaller.com/top-freeware-features.html
If you want a "package one deploy everywhere" solution then IzPack is the way to go, platform independant, free and open source.
http://izpack.org/
Depending on the complexity of your project Java Web Start could be a very good option, it's very simple configure and maintain but it relies on the browser's java plugin and believe me... most users DON'T like being warned about certificates and risks everytime they launch an application.

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

Merging Multiple Jars in to a Single Jar

my application needs multiple jars to work. Since it is a desktop application i can not hold the user responsible of installing. So in my build script i unzip the jars content in to my build directory delete manifest files, compile my software and jar it again. Everything works as it should my question is are there any long term side effects to this process?
In the past, there were JARs with weird content (like the DB2 driver which contains com.ibm and com.IBM; after decompressing in a Windows filesystem, those two packages would be merged).
The only issue you need to be aware of are signed jars and other files in META-INF which might have the same name in multiple source JARs.
A simple solution for all these issues is to use One-JAR. It allows to wrap several JARs into one without unpacking them, first. And read this answer: Easiest way to merge a release into one JAR file
A simpler solution (IMO) is using Maven's assembly plugin, which is also described in one of the answers to another question which was linked to in a previous Q&A. This is provided you are using Maven (which is a recommended tool by its own right) as a build tool.
If you want a no fuss way for the end user to kick off a program with multiple jar dependencies you may want to look at Launch4j or Jsmooth (I prefer Launch4j). Both are programs that create executables that wrap jar(s) and the JRE together so that to the end user it appears no different then any other executable.
Another great option is ProGuard, which can also shrink and/or obfuscate the code too.
If your primary target platform is Windows desktop, then you could also consider generating an Windows native exe from the jars of your application
If some of the jars are signed you lose the signature by unpacking/repacking it.
Well you're throwing away the MANIFEST of your third party jars, so that could cause you problems. For example you could be causing security issues by throwing away the "Sealed" attribute.
Why not just create a simple installer and a script to launch your application which sets the CLASSPATH correctly?
One-JAR will do the job, and has a new release (0.97) which supports frameworks like Spring and Guice, which users are now packing into One-JAR archives. http://one-jar.sourceforge.net
Ference Hechler also did some great work inside Eclipse with the Eclipse export wizard: we worked together on FatJar/One-JAR from which the Eclipse work grew, and I can recommend that as an approach, though I don't know how well it handles the frameworks.

Categories