I have an OS X objective-c app which programmatically invokes the Java command to run a Java program.
If I'm correct, Java is no longer installed by default on OS X. I want to ship my app and not force users to download Java before they can use the app.
How can I ship a copy of the java executable along with the runtime (rt.jar). Of course I can copy rt.jar in the app bundle of course but what about the java binary? Can I just copy this as well?
I think in your case, the best option would be to include the Java Installer Kernel (small install that downloads and installs the latest version of Java, if necessary).
The main problem with bundling the binaries per-se in your app is basically, security. Vulnerabilities are discovered routinely in the JRE and patched. If you bundle an specific version and a vulnerability is discovered after your release, you will be basically weakening the security of the machines where your application is installed. As you obviously don't want to do that, it is better to try to include logic to detect if a compatible version is present, or otherwise properly install the right version. Many installer packages include options like this: For example, OpenOffice/LibreOffice are native apps but they require Java to be present, and they use a similar installation method as the one described above.
Each self-contained application package includes the following items:
Application code, packaged into a set of JAR files, plus any other application resources (data files, native libraries)
Copy of the JRE, to be used by this application only
Native launcher for the application, multiple launchers for a single package are supported
Metadata, such as icons
Multiple package formats are possible. Built-in support is provided for several types of packages. You can also assemble your own packages by post-processing a self-contained application packaged as a folder, for example if you want to distribute your application as a ZIP file.
--
Self-contained application packages have the following drawbacks:
"Download and run" user experience
Unlike web deployment, the user experience is not about "launch the application from the web." It is more one of "download, install, and run" process, in which the user might need to go through additional steps to get the application launched. For example, the user might have to accept a browser or operating system security dialog, or find and launch the application installer from the download folder.
Larger download size
In general, the size of self-contained application packages is larger than the size of a standalone application, because a private copy of the JRE is included.
Package per target platform
Self-contained application packages are platform-specific and can only be produced for the same system on which you build. To deliver self-contained application packages on Windows, Linux, and OS X, you must build your project on all three platforms.
Application updates are the responsibility of developer
Web-deployed Java applications automatically download application updates from the web as soon as they are available. The Java Autoupdate mechanism takes care of updating the JRE to the latest secure version several times every year. Self-contained applications do not have built-in support for automatic updates.
You can ship a JRE with your app (see licensing). To give the user a copy of JRE, put one in and let them install it themselves or make a application bundle.
Related
I would like to know if it is possible to configure the Java VM used by Eclipse to run in this way, that it uses JavaFX SDK libraries.
Please be aware! I don't want to build JavaFX applications on my own in Eclipse, e.g. by using E(fx)clipse or other plugins.
Another remark: I don't use Java development perspective in Eclipse or a Java project. So it won't work to add the external .jars of JavaFX as user libraries!
In my use case I have an third-party GUI application based on JavaFX that has to be started out of Eclipse.
If I try to start this application I receive the following error:
The system reqirements are not met.
Could not find: javafx.properties
in:
/Applications/Eclipse.app/Contents/Eclipse/plugins/org.eclipse.justj.openjdk.hotspot.jre.full.macosx.x86_64_17.0.2.v20220201-1208/jre/lib
Your Java Virtual Machine seems not to support JavaFX,
required to run the XXX.
Please make sure you provide a valid path to the Java FX
modules during gui installation.
As you can see by the error message my Eclipse runs on a MacOS x64 system.
But I think the way to configure the VM of Eclipse should work on each system the same way.
Thank you.
Steve
If you have a third-party GUI application, then you do not need an IDE like Eclipse.
Ideally the publisher of your app would have provided the app as a package that includes the JavaFX/OpenJFX libraries as well as all the parts of a JDK/JVM needed to run that app on your Mac.
If the publisher gave you only the bare-bones app without the needed libraries & JDK/JVM, you can obtain a JDK/JVM bundled with those libraries.
At least two vendors supply a JDK with JavaFX/OpenJFX libraries:
ZuluFX by Azul Systems
LibericaFX by BellSoft
Both are available free-of-cost with optional support plans available for sale. Download either product as an installer specific to your Mac, while paying attention to either Intel-based Mac or Apple Silicon (ARM, AArch64) based Mac.
You can verify the install by using a console such as Terminal.app to run:
java --version
… and:
which java
You can also use the Finder to locate your installed JVMs by choosing Go > Go to Folder… where you paste:
/Library/Java/JavaVirtualMachines
If your app contains the necessary MANIFEST.MF file, you may be able to launch your app by double-clicking. If not, use a console such as Terminal.app with the java command to launch the app.
High level: I am working on a JavaFX app that I'd like to automatically update
Things I've looked at:
Add ability to automatically update co-bundled app (Open JDK official auto updater issue)
UpdateFX (Library for handling automatic updates)
Issue I am having: Trying to package two separate javafx native executables into one package.
Description:
I have created a JavaFX UI application that checks for an updated version upon startup. The application is delivered by building a native (using jfx packager) package for each OS: Liux, Windows and OSX.
If there's a newer version available the app downloads the required update into a temporary folder.
To update itself, the app technically needs to overwrite some of its own files. While this is possible to do on Linux and OSX, Windows locks all of the jar files that I need to update while the main application is running.
To get around this, I created a small "updater" application that I would download. My main application would download all of the updates AND the updater application. The main application would then launch the updater and kill itself.
The updater would continuously try to update that application files (this was in some kind of loop in case it took a while for the main application to shut down).
Once the updater would finish, it would simply call the correct main program's executable file and the update would be completed.
This works...BUT: In order to run my updater application, I am relying on the client's machine having java (and having the correct version to boot). The whole point of using the javafx native packager is to make sure that the JRE is distributed with the app and that there is no dependency on any local version.
I wanted to try a hack:
Instead of having my updater be a regular jar (java application). I could make the updater be a JavaFX application that I package natively.
I'd then manually take the generated native executable out of the updater and just distribute it with my main application.
Since the folder structures for both main executable as well as updater executable would be the same, I was hoping that both executables could piggy back on one bundled JRE
The hack only works on OSX - on both windows and linux there are local config files that the executable relies on to invoke the correct java file.
Is there any way to get around this issue? Is there any way to force the packager to output a custom "package.cfg" (in the case of windows) that would allow me to bundle two executables?
I realize this is a long shot, but any advice would be appreciated.
I may have asked my question just a bit before the code to do what I wanted was included in javapackager.
Short story is that this is now possible to do using javapackager that is part of JDK 1.8 release > 60 (I am now using 74)
Here's a link to the official oracle documentation: Oracle Doc
It's also possible to use Maven to build your JavaFX app to have secondary launchers via: javafx-maven-plugin
I make my executable jar in exe format, but I want to add JRE with this because if JRE is not present in their machine, they can use it with this included JRE.
But I do not want to install this JRE in their machine. This JRE is only used by this application only. It will just like game or other application. I use launch4j to make jar to exe but i did not find any option from where it can attach JRE and it has no option from where I can link my jar dynamically.
How do I achieve that?
If there is other free installer then mention it, and please give the procedure with example.
Since it has been established that your app. has a GUI, I will suggest Java Web Start as the answer.
But I do not want to install this JRE in their machine.
That is not a sensible requirement. The user might already have a usable JRE installed, if they don't they probably also don't want every Java based application to be installing its own 'private' JRE.
Oracle's deployJava.js can do the checking, and help guide the user through the steps of installing (which basically comes down to click 'OK' when prompted).
I make my executable jar in exe format,..
If you only intend to support Windows, what is the attraction of coding in Java? JWS supports any platform for which Java is available. That brings a lot more potential customers for the app.
I want to use free installer.
JWS is entirely free. Just like the JRE.
..please give the procedure with example.
Do you run an IDE? If not, do you otherwise have Ant installed? If that is a yes to either one, check out my small JNLP API examples. Each comes with complete source and a build file (an Ant build.xml).
Within a couple of keystrokes & a few moments, you can see the app. installed and launched on your desktop. For the end user, it is even simpler. Just click a link in a web page, and it all happens automatically (possibly with a security prompt - for the protection of the user).
I like JSmooth. You can give it a try here:
http://jsmooth.sourceforge.net/features.php
Flexible automatic Java VM detection
Detects the location of any Sun JVM installed. The wrappers use
several strategies to detect all the JVM available on a computer,
using windows registry, environment variables, windows path.
Detects
and uses Microsoft's JView (for 1.0 and 1.1 Java applications), if
available.
The JVM search sequence is fully customizable using the
GUI. You can force the executable to search in the path first, and in
the registry last, or in JAVA_HOME first. We have all the flavours!
Sometimes it's more convenient to bundle a JRE with your application.
JSmooth can deal with that too, you just need to define in which
folder the JRE is expected. It falls back nicely to a standard JVM
search if the JRE is not where it should be.
Specify which versions of
the JVM are compatible with your software. You can set a minimum
version, but also a maximum JVM version.
Documentation: http://jsmooth.sourceforge.net/docs/jsmooth-doc.html
Take a look at launch4j.
I had to use it, and it worked out very well.
You can set a minimum version of a needed JRE, bundle a JRE, or if a JRE is not found (and not bundled) the launcher may lead the user to a download location of an appropriate JRE.
There are various further features launch4j offers, and as opposed to another suggestion here, launch4j is activly developed
http://launch4j.sourceforge.net/
I'm new to the programming scene. Been working with C++ for about 5 months now, and have decided I want to start getting into Java. I'm using Eclipse as my IDE, and obviously Java for the language. I'm trying to write a simple HelloWorld application, which can be run through a command prompt executable.
In Visual Studio, it seems it's rather easy to create an executable. All I've ever had to do is use a pull down arrow and choose Release, and then run my build. The purpose of wanting to be able to write/run Java in command prompt is so that I'm able to practice some of the language basics before I go in full force with Swing.
So bottom line, what is the easiest way to create a command prompt .exe written with Java?
Thanks in advance!
Java doesn't natively allow building of an exe, that would defeat its purpose of being cross-platform.
AFAIK, these are your options:
Make a runnable JAR. If the system supports it and is configured appropriately, in a GUI, double clicking the JAR will launch the app. Another option would be to write a launcher shell script/batch file which will start your JAR with the appropriate parameters
There also executable wrappers - see How can I convert my Java program to an .exe file?
See also:
Convert Java to EXE: Why, When, When Not and How
Creating a native installer using jpackage
A java packaging tool named jpackage was released as part of the Java Development Kit (JDK) version 16.
This tool works in conjunction with native packaging tools for various platforms (e.g. WIX for Windows, RPM, and DEB for Linux distributions, DMG for Mac) to allow building native installers for Java applications which can then be run as executables. For distribution, it may be possible to distribute just the executable for the application, independent of the installer (I don't know, I didn't try that).
A nice, tutorial style, blog post that describes the use of the jpackage tool to create a native Windows installer for a Java application is:
How to create a Windows Native Java application (generating .exe file)?
Customizing the runtime image using jlink and jdeps
The packaging tool can (optionally) be combined with the jlink tool:
jlink - assemble and optimize a set of modules and their dependencies into a custom runtime image
This allows you to customize the runtime image for your application to only include the required custom selected modular parts of your application code, java runtime, and 3rd party libraries, rather than distributing a complete java runtime.
Optionally, you can also use the jdeps tool to determine inputs to jlink.
Complete discussion of usage of jdeps + jlink + jpackage + a native bundle creator (e.g. wix/rpm/deb/dmg) is outside of scope for a StackOverflow answer, but various resources can be found on the web if you search.
Creating a standalone .exe instead of an installer
This can be done using warp-packer to create a exe out of the image and app launcher created by jlink.
How to create a standalone .exe in Java (that runs without an installer and a JRE)
Third party tools can help deliver a solution
If you wish to use all these tools in combination, things can get complicated, and I'd advise using a 3rd party utility or template to help perform this task. For example:
badass-jlink-plugin (documentation) -> "allows you to create custom runtime images for modular applications with minimal effort. It also lets you create an application installer with the jpackage tool."
For JavaFX specific applications (as your question has a JavaFX tag), you could review:
JPackageScriptFX -> "demonstrates how projects can use scripts to build self-contained, platform-specific executables and installers of their JavaFX applications via the jdeps, jlink, and jpackage tools."
For native mobile deployments, see Gluon Mobile
This question was Windows specific, but for completeness, if your target is native application deployment on a mobile device, then likely you will need to use a 3rd party solution such as Gluon Mobile.
Background Rationale (ignore if not needed)
creating a native installer using jpackage might be a bit of work, so why would you do it?
Here are some reasons:
When an application is distributed via an installer created using jpackage, that application can be installed on a target system without requiring the user to manually install other dependencies (such as a Java Runtime). The installer will take care of ensuring that your application and any dependencies it requires are installed.
The application ships with its own customized version of the Java Runtime. This means that if the user doesn't install a JRE, and, if they have installed a version of the JRE which is incompatible with your application, your application will still function correctly.
The application can be installed and uninstalled using standard OS facilities for the target platform. Most users of those platforms are familiar with these.
Yes, Java is cross-platform for the most part, but many users don't care much about that, instead they just want a smooth and familiar installation (and uninstallation) experience for their application and jpackage can help accomplish that.
Typical Java programs compile into .jar files, which can be executed like .exe files provided the target machine has Java installed and that Java is in its PATH. From Eclipse you use the Export menu item from the File menu.
Creating .exe distributions isn't typical for Java. While such wrappers do exist, the normal mode of operation is to create a .jar file.
To create a .jar file from a Java project in Eclipse, use file->export->java->Jar file. This will create an archive with all your classes.
On the command prompt, use invocation like the following:
java -cp myapp.jar foo.bar.MyMainClass
I have a working JNLP application which I need to distribute to various non-technical end users.
If the user's machine has a recent JVM installed, everything is fine. They just double-click the JNLP file I send them and Java Web Start does the rest.
Now I would like to distribute something that works with or without a JVM, e.g. a .exe file that auto-downloads a compatible JVM if none is present, then invokes javaws.exe to download the .jar files and launch the application.
Launch4J is the closest match I have found, but it cannot launch a program through javaws.exe. The only options are java and javaw
I would like a product that can:
Generate a self-contained .exe file that does not require a JVM to be pre-installed
Parse the .jnlp file and determine the correct JVM to download if necessary (I know Java Web Start can download a JVM if necessary, but I want to avoid having to download two, the first to bootstrap Java Web Start and the second to run the application which may require a specific but different JVM.)
Download and install the JVM automatically, not simply direct the user to a Java download page or open a new installation wizard.
Prompt for an admin password if necessary (for permissions to install the JVM. I don't think this is built into the Sun JVM installers.)
Show only one security dialog (I would like to prompt the user just once, to confirm they trust the generated .exe, but I do not want a second prompt to confirm they trust the .jar file which will be from the same source and signed with the same certificate.) I assume this will require the auto-downloader to install the certificate before launching JWS.)
(not essential) Download application resources (e.g. .jar files) in the background simultaneously with the JVM. This would require the cache to be running before the JVM is installed, so the cache would have to be implemented in native code and the DownloadService would later interface to it using JNI.
Does a product like this exist? I suspect it does not but It's worth a shot.
Update I found this article which has solutions to some related problems, though it is designed for offline installation and I am mostly concerned with online installation.
I have been able to do this & use it in production.
write a simple bootstrap class, jar it, and Launch4j the jar.
here's the main for the simple bootstrap class:
public static void main(String[] args) {
try {
final File jnlp = File.createTempFile("temp", ".jnlp");
final URL url = new URL("http://yourjnlp-wherever-youre-hostingit.jnlp");
yourCopyStreamMethodYouWrote(url.openStream(),new FileOutputStream(jnlp));
Desktop.getDesktop().open(jnlp);
} catch (final Throwable t) {
// do something useful here
}
}
You can also consider compiling your project with Excelsior JET. Apart from everything else it also creates a self-sufficient distribution of reasonable size.
I've run into the same problem. I ended up with a BAT, a Shell and eventual a DMG for Macs.
I found this comment on automaded JRE installation for Windows using Nullsoft installer:
http://nsis.sourceforge.net/Java_Launcher_with_automatic_JRE_installation
I think outside JNLP you will find hard to get automation for all platforms. However on my project, up for two year, I haven't seen complains about users having to get java by themselves. I believe most machines will have it already. Windows user complained about not having a shortcut, but that is easy to do using vbs.
Also on the Mac DMG AppBundle, their is way to specify the JRE. Mac will have the lastest version, unless the are older PowerPC based machines. In that case no Java6.
Of you end up with several launcher, I would recommend an automated update strategy.
Another approach might be also distributing a Sun JRE with a .BAT-file invoking it with the /S switch, which cause a silent install.
I have not seen anything else allowing for a completely silent Java install combined with invoking javaws.
Ok i get what you are trying to do but why don't you want use javaws? Launch4J looks like a good option as alternate to having java installed, as it will allow seamless usage of the jar file.
javaws is more or less uses java.exe with security permissions and some launch options. But the security permissions can be disabled if you use a certificate that the user trusts.
Also i am unsure when javaws was introduced but i am sure it was available in java 1.5 which i near EOL. So unless your user has not had a java installed for many years i doubt getting them to launch jnlp would be a problem. Even if they are running an older version you can add a required version of java to the jnlp and this will be automatically downloaded for that application only.
Though not free for non-commercial use, Install4j offers a native installer system for Java applications. JRE bundling is supported. I am not sure it can parse JNLP automatically, but it may be something worth checking out.
As an sample use case, the Java-based Integrated Genome Browser gets distributed with an installer generated by this tool. See its install4j configuration file.