I am writing an application in Java. Does a Java SDK have to be installed to run the application from the command line? If so, can I package the SDK with the application to be installed when installing the application?
From Java 9 onwards you can use jlink to produce a custom JRE for your application. The JRE includes a copy of the java command and (only) the libraries / classes that your application needs. It will be platform specific.
From Java 14 onwards, you can use jpackage to produce (platform specific) native executables for Java applications.
There are also 3rd-party tools that can generate executables, and third party installer generators that (in some cases) can install Java for the end user.
Note: if you take the approach of distributing your application as a self-contained JRE or native executable, the user no longer has the option of updating their Java to address security related issues. It becomes your problem / responsibility ... as the supplier of the software ... to make available in a timely fashion application updates that incorporate the new Java releases with important security patches.
If you use something like GraalVM to compile a native binary, then there is nothing more you should need for a simple application (meaning, nothing is tried to dynamically load classes at runtime with reflection)
Other than that, the Java JRE is required, and can be included as part of an application package; for example, IntelliJ or Eclipse IDE come with their own JRE.
Thanks everyone for your input.
After doing more research I found that by using a jdk greater than 8.?, it is possible to bundle everything an application needs in the deployment process.
Related
In addition to developing classic services on Spring Boot, I want to know Java with it environment better.
When I began to study portability, I came across such concepts as custom JRE (jlink, jmods) and native image (GraalVM, Liberica NIC).
As I understand :
Custom JRE for creating distribution folder with executable file. In folder only necessary dependencies. It arrived in Java 9
Native image for creating executable all in one JAR
Which of them should be used in which cases?
First of all, you should know what a JRE (Java runtime environment) is. Basically, it includes everything required to run Java applications that are already built. A JDK (Java Development Kit) is a superset of a JRE, adding the tools for developing Java applications.
With jlink, you can create JRE images. This means you are creating a Java installation that is capable of running your Java program. This can be done in a way so it only contains the necessary modules. jpackage allows you to create an installer for such a JRE.
On the other hand, a native image is a version of your code that's compiled and optimized for a specific target platform. Typically, it's a single executable file that runs your code. When creating a native image, it takes your application and converts (compiles) it to a platform specific executable (unlike jlink which creates a JRE that is able run your "normal" JAR).
Native-image does not generate a JAR but an ELF/EXE file which can be executed on your device without a Java installation while jlink just creates a (minimal) Java installation capable of running your application.
It should be noted that native-image comes with a few limitations. For example, remote class loading is not possible and if you use Reflection, you need to specify what to reflectively access at compile-time.
I wonder if there is a AOT complier(s) for the Mac to compile Java apps into native executables, therefore eliminating the need for a JRE?
I have seen commercial examples for both Windows and Linux but haven't been able to find anything for the Mac, other than the opensource GCJ which has limited success with some of the poplar java libraries.
A native executable for the Mac would rid it of the JRE and, possibly, allow it to be signed allowing Java developed applications to possibly be accepted into the app store.
Install4J can compile your Java into a native OS X application but the system still should have JRE installed. Install4J just creates a wrapper for a JRE call.
You can use the Avian JVM for this. (Wikipedia article).
You can compile your application to a standalone executable and it supports different class libraries: openjdk, the Android class library implementation (even if you are not running on Android), and a custom class library that is very limited (basically they add methods to it as the authors need APIs to run their own applications).
In the README in the code repository there is a description how to embed the VM and generate a "boot" C++ program that will run your application and refer to the section "bootimage" if you want to AOT compile all the methods and generate a binary image obviating the need for JIT compilation at runtime.
Without the boot image, you can ship the jar files and a executable that will "start" them (the executable will embed the virtual machine). With the boot image, the jar files will additionally be pre-compiled to native code.
On the other hand, if you just need a managed language/platform, you can also use .NET/Mono AOT. See the mkbundle tool included with Mono 2.x.
I have a Java desktop app that runs on both the MacOS and Windows.
I understand that I cannot have one distribution for each, which is not a requirement.
I need to know what tool or tools is best to use when delivering a Java app for each.
The tool should install prerequisites (in this case, Java and some JARs) and look native to the respective operating system.
As for OS X's java situation:
Currently, JDK 6 is bundled in the OS.
Presumably, the next version of the OS will still include JDK 6.
It's publicly stated that the OS will have a well-defined place to install multiple copies of Java runtimes, a public interface choosing which of the Java version, etc. See here.
Apple started contributing back its own code to the open JDK community, so JDK 7 should be available as a separate download, see here.
So, you're not expected to include Java runtime itself into your Java app even then. You're not supposed to install Java in a ramdom place on a filesystem, for example.
As for how you should deploy java apps on OS X:
Double-clicking jar just works.
However, that won't be pretty, because you would only have a generic Java icon in the Dock. You don't want that.
You should use Jar Bundler to make it an honest OS X app. On Mac, it comes with XCode. See the documentation here. You can do that on a non-Mac machine too, using this open-source project.
On Windows, I would recommend either JSmooth or WinRun4J.
On a Mac, the situation is a bit more complex (as the comments point out), but just distributing an executable JAR is probably good enough for now.
I am working on an application called Enchanting. The application, based on Scratch, emits Java source code and compiles it for uploading onto LEGO Mindstorms NXT Robots.
While the application is very early, users have a hard time installing it.
Right now Windows users have to:
download and install a Java Developer Kit
download and install LeJOS (a java library for the NXT)
possibly tweak environment variables
then they can download, install, and run Enchanting itself
If I could provide an installer that would include the JDK, and LeJOS, I could figure out the environment variables at run time, and the process becomes:
Download, install, and run Enchanting
Is there a way to redistribute a JDK?
(Incidentally, Processing (a simplified text-based programming environment) seems to offer a version that comes with the JDK, so it appears that there is a legitimate way to do so).
Addendum: I would like a Windows user who does not have java installed to be able to run a single .exe file to install the JDK, LeJOS, and Enchanting.
The information regarding redistribution is here for Java 10 JDK and here for Java 8 JDK. Currently Java 8's is substantially more detailed than Java 10's.
and you can use PackJacket, to package all the files you need and create an installer.
Assuming you satisfy all the legal terms required to distribute stuff, you can use izpack to install all the prerequisites, including a JDK/JVM and configuration of environment variables.
Quite a number of IBM Eclipse based tools have JDKs with them.
Or you could just emit bytecode directly. You could bundle a much smaller (than the JDK) JVM dynamic language then use it to compile to bytecode or use libraries made for that purpose.
(I got the following from the Projects using Kawa page)
App Inventor for Android uses Kawa to translate its visual blocks language.
...The Nice compiler (nicec) uses Kawa's gnu.expr and gnu.bytecode packages to generate Java bytecode. ...
It's this last one is the one that uses the Kawa language framework to generate bytecode.
Don't forget about Groovy, Jython, Clojure, and Ruby. Interesting fact about Groovy, the interpreter can compile Java code since Groovy is (more or less) a superset of Java.
What's the best way to package Java software for running on Windows? Is there a standard for writing .BAT files which can discover the latest installed JRE on the machine? Are there any Maven plugins for this? What's the deal with executable Jar files?
I would without any doubt recommand you to use Java Web Start, as it allows you easy control over version used (and by far the easier to use update mechanism available nowadays).
Depends on what you need.
We've found that using the One-JAR + JSmooth gives a very good user experience as it allows us to distribute a single EXE-file which can be put anywhere on the users system, as opposed to having installation binaries, which need to be installed and uninstalled etc. etc. etc. JSMooth checks for the existance of the appropriate Java runtime, and redirects to the official download site if none is found.
The reason for One-jar is that you generally need to use library jars which is best to have separately but JSmooth only allows for a single jar file.
Also the One-Jar SDK and JSmooth is scriptable without being tied to Windows, so we can build new versions on our Hudson engine running on Linux.
In the past I've used a java installer package like launchForJ. However, a lot of these packages use Java so you may need to a batch or simple executable written in native windows code that does a quick check to see if Java is already installed then run the installer.
Since Java uses system variables during install you should be able to check if the version (or higher) that you require exists in this way.
The standard way would be to use Java Web Start.
Using Java Web Start technology, standalone Java software applications can be deployed with a single click over the network. Java Web Start ensures the most current version of the application will be deployed, as well as the correct version of the Java Runtime Environment (JRE)
Maven has a Webstart Maven Plugin to help building application bundles that can be deployed via Web Start.
An alternative solution would be to use a cross-platform installer generator to generate, well, an installer. I personally like IzPack (I think that JSmooth is very similar but I have more experience with IzPack) and, if you are specifically targeting the Windows platform, you could use IzPack to Build [a] Native Windows Installers with IzPack Native Launcher:
A problem still arise with IzPack when
the target system does not have a JRE
installed. The user needs to first
install it and then run the IzPack
installer. This is not a problem with
Linux or BSD users since they are
generally skilled and they know how to
do that by hand or with a packaging
system (RPM, DEB, ebuilds, ports,
...). Similarly, a Mac OS X user will
not have much problems since it is
available with the operating system.
However the situation is more
complicated on the Windows platform as
a JRE must be installed. Worse,
several instances can be installed in
a sometimes messy situation.
The IzPack Native Launcher tries to
solve this problem. It is a C++ native
application that is available under
the very permissive MIT License and
that uses wxWidgets for the GUI. It is
thus cross-platform (for the
historians: it was first developed on
a FreeBSD box), but most people will
need it on Windows. It uses a simple
configuration file and will first
check for a JRE. If none can be found,
it will pop-up a dialog to let the
user choose between the following
options:
manually specify a JRE location
download one from the Internet
install one that is provided by the packager (if available).
IzPack also offers a Maven Plugin. Worth the check.