Cannot build DMG from .JAR with javapackager - java

I've tried building a DMG file from my jar by running the following command:
/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/bin/javapackager -deploy -native dmg -srcdir bin -srcfiles MyTest.jar -srcfiles p -appclass com.example.Test -name MyTest -outdir deploy -outfile MyTest -v
But it keeps giving the following error message:
Bundler DMG Installer skipped because of a configuration problem: Main application jar is missing.
Advice to fix: Make sure to use fx:jar task to create main application jar.
The funny thing is that if I copy the same folder into another Mac and run the same command, it will build DMG successfully. Therefore I believe it is something related to my config or system environment.
Do you have any idea what is going on and how to fix it?

I found that the order of the option -srcfiles is very important. The last -srcfiles should be the JAR file. In my case, I put -srcfiles p after -srcfiles MyTest.jar, that's why it did not work. Strangely it happened only to some Macs and some JDK, not all of them have this issue.

javapackager was deprecated from java11, and I had the same issue on my local setup even with java8. There is a new tool called jpackage, here is a simple example:
jpackage -t dmg -n AppName --main-class main.core -i . --main-jar AppName.jar --icon ~/Downloads/path-toicons8-log-96.icns

Related

Issue with copy JRE into docker and run java command

I am copying the working version of the JRE directory into docker and trying to run /JRE/bin/java.
But it throws ash: java not found error. I am doing the same in a linux VM . Just copying the JRE folder and executing java command which works fine in VM. I don't want to download JRE from anywhere.
Want this specific JRE bundled.How to resolve this.
I entered into the shell console and navigated to the JRE/bin/ directory and executed "java". even then it fails . The error is same ash: java not found error.
Dockerfile:
FROM alpine:latest
ENV HOME=/root \
DEBIAN_FRONTEND=noninteractive \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8 \
LC_ALL=C.UTF-8 \
DISPLAY=:0.0 \
DISPLAY_WIDTH=1024 \
DISPLAY_HEIGHT=768
RUN apk --update --upgrade add \
bash \
fluxbox \
x11vnc \
xterm \
xvfb
COPY MyJavaApp MyJavaApp/
WORKDIR /MyJavaApp
ENV PATH="./JRE/bin:${PATH}"
When are you copying the JRE directory to the docker? i.e Docker build time or after spinning up the Docker container?
Looks like you are correctly copying the local Java directory to the image, however the current location cannot access the java binaries, thus, make sure to set the PATH. It should be something like,
RUN export PATH=/JRE/bin:${PATH}
or pass the path to the ENV in the Dockerfile,
ENV PATH="/JRE/bin:${PATH}"

jpackage creates 2 copies of JRE

I use jpackage (with JDK 14) for creating a standalone JavaFX application.
The output of jpackage looks strange, it consists of two the same copies of JRE and all files in app folder, except App.cfg file, can be deleted without any problem.
Does jpackage can do not generate unnecessary files?
What I have:
I have a simple project created from Maven archetype org.openjfx:javafx-archetype-simple:0.0.3.
And I just added maven-shade-plugin for creating jar with dependencies and a simple launching class for it (like NewMain class here).
I do:
mvn package
mvn javafx:jlink
jpackage --package-type app-image --dest targetApp --name App --runtime-image target/image --main-jar testApp-1.0-SNAPSHOT.jar --input target
As result I have two folders with JRE (absolutely the same ones):
targetApp\App\runtime
targetApp\App\app\image
And all files (and folders) (JRE (~53 MB), Jar (~9 MB), classes...) in targetApp\App\app can be safely deleted, except App.cfg file.
After deleting these files I run targetApp\App\App.exe and it works fine.
The deleting reduces the size of App from 118 to 56 MB.
An additional question: I use Windows and jpackage generates the result for Windows (a lot of dll files and exe), do I can create a standalone application in Windows for Mac and Linux?
You get this result because you already created an uber-jar which contains everything in addition to what you specified via --input target which, according to the documentation, has the following effect.
All files in the input directory will be packaged into the
application image.
Try whether it works to just remove the option --input target or don't create the uber-jar. Instead use the maven-dependency-plugin to copy all dependencies into a single folder, say target/libs, and then explicitly specify --input target/libs.
Your second question:
You cannot cross-create applications for other targets, if that is your question.
You might want to check out the JPackageScriptFX project on GitHub. It contains a sample multi-module maven project structure and build scripts for Mac and Windows that will build all available package types and executables for both platforms. You can find it here: https://github.com/dlemmermann/JPackageScriptFX
My solution without Oracle's jpackage: AdoptOpenJDK + jpackager + macOS => .pkg, .dmg
Download AdoptOpenJDK_13. Unzip and put into /Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk
Download jpackager for (in my case osx) from https://mail.openjdk.java.net/pipermail/openjfx-dev/2018-September/022500.html. Unzip.
Copy jdk.packager.jar and jpackager to the /Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/bin (!!!)
In /yourworkspace/target should be the programA.jar file. (In my case it is a small program created with OpenJFX + openjdk13)
The /yourworkspace/jlink denotes on your JRE with bin,lib etc. you might have created via jlink. (In my case I have my custom JRE + JavaFX modules)
The /yourworkspace/icons contains .icns .
create jpackager.command file in your workspace with the content:
#! /bin/bash
ABSPATH=$(cd "$(dirname "$0")"; pwd -P)
launcher=`ls $ABSPATH/target/*.jar`
for eachfile in $launcher
do
if [ -f "$eachfile" ];then
echo Creating .pkg ...
echo "$eachfile"
basename="${eachfile##*/}"
/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/bin/jpackager \
create-installer \
--runtime-image $ABSPATH/jlink \
--name ProgramA \
--input $ABSPATH/target \
--main-jar $basename \
--version 1.0 \
--copyright "Nikita Gromov 2020" \
--name "ProgramA-macos" \
--mac-bundle-name "ProgramA" \
--output $ABSPATH/appimage \
--icon $ABSPATH/icons/20200220101822955_easyicon_net_32.icns
fi
done
Double click on jpackager.command which is located in /yourworkspace and wait until the jpackager has created ProgramA-macos-1.0.pkg and ProgramA-macos-1.0.dmg under /yourworkspace/appimage
My solution without Oracle's jpackage: AdoptOpenJDK + jpackager + Windows => .msi
Install WiX (!!!) Important step.
Download AdoptOpenJDK_11. Will be installed under C:\Program Files\AdoptOpenJDK\jdk-11.0.6.10-hotspot
Download jpackager (in this case win) from https://mail.openjdk.java.net/pipermail/openjfx-dev/2018-September/022500.html. Unzip.
Copy jdk.packager.jar and jpackager to the C:\Program Files\AdoptOpenJDK\jdk-11.0.6.10-hotspot\bin (!!!)
In /yourworkspace/target should be the programA.jar file. (In my case it is a small program created with OpenJFX + openjdk11)
The /yourworkspace/jlink denotes on your JRE with bin,lib etc. you might have created via jlink. (In my case I have my custom JRE + JavaFX modules)
The /yourworkspace/icons contains .icns .
create jpackager.bat file in your /yourworkspace folder with the content:
set openjdk=C:\Program Files\AdoptOpenJDK\jdk-11.0.6.10-hotspot\bin
set saveto=%cd%
cd %openjdk%
jpackager create-installer --runtime-image %saveto%/jlink --input %saveto%/target --main-jar ProgramA.jar --version 1.0 --copyright "Nikita Gromov" --name "ProgramA-win" --output %saveto%/appimage --icon %saveto%/icons/icon.ico --win-menu --win-shortcut --win-dir-chooser
Note The ProgramA.jar should be in /yourworkspace/target path (!!!)
Double click on jpackager.bat which is located in /yourworkspace and wait until the jpackager has created ProgramA-win-1.0.msi under /yourworkspace/appimage
Custom JRE + JavaFX mods on Windows
Create /yourworkspace/jlink.bat file. The content of it should be:
SET openjdk=C:\Program Files\AdoptOpenJDK\jdk-11.0.6.10-hotspot\bin
SET fx=C:\Programme\AdoptOpenJDK\javafx-jmods-11.0.2
set saveto=%cd%
cd %openjdk%
jlink --module-path %fx% --add-modules=javafx.base --add-modules=javafx.controls --add-modules=javafx.fxml --add-modules=javafx.graphics --add-modules=javafx.web --add-modules=javafx.media --add-modules=javafx.swing --bind-services --output "%saveto%\jlink"
This creates the /yourworkspace/jlink folder with a custom JRE+JavaFX libraries which you will link to jpackager.

Adding multiple dependent Jars using Javafxpackager

I'm having issues adding multiple packages in the command line.
javafxpackager -createjar -outfile outjar -srcdir /dest/to/src -classPath
libs/library1.jar:libs/library2.jar -appClass pathto.MainClass -v
I've tried with spaces and multiple -classPath flags and obviously I've tried the colons as well. I'm working in Ubuntu and the program works great in Eclipse, but when I package it, it works until I try to do something that requires an external library. If I use only one I can do that function fine, but need multiples to work fully.
If anyone can shine some light on this I would greatly appreciate it.
Instead of:
-classPath libs/library1.jar:libs/library2.jar
use:
-classpath "libs/library1.jar;libs/library2.jar"
Whatever it is that parses the JavaFX-ClassPath that is created in the manifest by the packager doesn't like you having : to separate the libraries. When you use a ; instead in the -classpath argument, the generated JavaFX-ClassPath will use a space to separate the libraries and the runtime will then be able to use both libraries.
Here is a sample manifest I generated using the JavaFX packager on OS X (which worked for me).
$ jar xf HelloWorld.jar
$ cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
JavaFX-Application-Class: HelloWorld
JavaFX-Class-Path: lib/phrases.jar lib/friend.jar
JavaFX-Version: 2.2
Created-By: JavaFX Packager
Main-Class: com/javafx/main/Main
Jar containing the manifest was generated using the command on OS X 10.8 Java 1.8.0-ea-b113:
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/javafxpackager -createjar -classpath "lib/phrases.jar;lib/friend.jar" -srcdir . -outfile HelloWorld -appclass HelloWorld

Convert Java application to Mac OS X app

Is there a way to convert a Java application into a Mac OS X executable app?
I use NetBeans to develop in Java, and I'd like to "pack" the "dist" folder into an app (just for convenience)
Use the Apple Java Extensions and its Guide
The Apple Java Extensions contains a very complete development guide with information on the deployment of Java applications on Mac OS X and the production of application bundles. It also introduces other aspects of the Apple Java Extensions, like the support for integration with the standard Mac OS X UI.
Other references:
JarBundler.
Make a Mac OS X App Bundle
Creating a osx app bundle in Java registered to a protocol url
There is a library that let's you package your Java app
Packr: https://github.com/libgdx/packr
Packages your JAR, assets and a JVM for distribution on Windows (ZIP), Linux (ZIP) and Mac OS X (.app), adding a native executable file to make it appear like the app is a native app.
It can even minimize the JRE for you.
jar2app
Packr is a great tool, but at the time I found that I wanted something "easier to use", so jar2app was born. I know this is an old question but perhaps other people might find this program easier to use than other alternatives. If they don't, there's a direct reference in the FAQ to other alternatives (such as Packr).
You can use javapackager tool to build the application and wrap it in into an installer, the following commands show how to convert a jar file into a bundle file:
commands
mkdir -p package/macosx
cp Test.icns package/macosx
jdk=$(/usr/libexec/java_home)
$jdk/bin/javapackager -deploy -native dmg \
-srcfiles Test.jar -appclass package.Test -name Test \
-outdir deploy -outfile Test -v
cp deploy/bundles/Test-1.0.dmg installer.dmg
ls -l
open installer.dmg
To change the application icon and more info MacJava.
As of JDK14 there is also 📦 jpackage (JEP-392), currently promoted from incubation phase to a production-ready feature.
Example usage that worked with an swt app (assumes all the required jar files reside in the files folder; you can also provide a custom resource folder with --resource-dir):
jpackage --type dmg \
-i files \
-n Bigly \
--main-class com.biglybt.ui.Main \
--main-jar BiglyBT.jar \
--java-options -XstartOnFirstThread \
--mac-package-name BiglyBt \
--icon app.icns \
--verbose
For the full option list use:
jpackage --help
WARNING: It's probably debatable whether it's a bug or not, and maybe it will be addressed in a future release, but in the current version, if you specify the input folder as -i ., and do not provide a custom destination with --dest then jpackage will bundle everything in the current folder... including the bundle it just created, i.e. it goes recursive on itself when . is both the input folder and the output :D .
Since some of the links in the accepted answer are no longer available or suitable in 2020, 8 years from the question was asked, I would like to share my findings that I confirmed working today.
There is a tool, javapackager, shipped with java, can package java application on Windows, Linux, macOS for you.
Here is the official manual: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html
(Also there are other helpful tools here: https://docs.oracle.com/javase/8/docs/technotes/tools/ )
For packaging a mac application, I used this command:
javapackager \
-deploy \
-native image \
-srcdir ./csv-encrypt-tool-mac \
-srcfiles csv-encrypt-tool.jar \
-srcfiles dict \
-srcfiles config \
-srcfiles log \
-outdir ./dist \
-outfile csv-encrypt-tool \
-appclass some.package.CsvEncToolApp \
-name "csv-encrypt-tool" \
-title "csv-encrypt-tool" \
-nosign \
-v \
-BjvmOptions=-Xmx4096m \
-BmainJar=csv-encrypt-tool.jar \
-Bicon=icon.icns
And this is the explanation:
-deploy \ # Assembles the application package for redistribution with sys JRE
-native image \ # Build a .app file. If you want a .dmg, use -native dmg
-srcdir ./csv-encrypt-tool-mac \ # directory where my jar and resource files in
-srcfiles csv-encrypt-tool.jar \ # my executable jar, path relative to -srcdir
-srcfiles dict \ # one of my resource directories, path relative to -srcdir
-srcfiles config \ # another one of my resource directories, path relative to -srcdir
-srcfiles log \ # again, one of my resource directories, path relative to -srcdir
-outdir ./dist \ # where I want the package to be put
-outfile csv-encrypt-tool \ # the output file name without extension, the final file (or bundle which is a directory actually) will be csv-encrypt-tool.app
-appclass some.package.CsvEncToolApp \ # the class with main method, which is the entry point of the whole app
-name "csv-encrypt-tool" \ # the name (not very sure what this is for)
-title "csv-encrypt-tool" \ # the title (not sure what it is either)
-nosign \ # not sign the app since this is just an internal tool, if you want to publish it, signing is necessary
-v \ # verbose
-BjvmOptions=-Xmx4096m \ # I need 4GB max heap size
-BmainJar=csv-encrypt-tool.jar \ # the jar file with main class
-Bicon=icon.icns # the icon
After the command is executed, there will be some files and directories created in dist, where I want the package be, and one of the directories is bundles. The application is put in there.
Since I just built an internal tool, there is no need to sign and packaged without other production ready options. You can refer to the official manual for help.
Hope this help others who do not know how to package an application on macOS in 2020, just like me.
So none of these options worked for me (maybe because I am running OS X 10.15, maybe because most of these projects are years old, who knows). Installing Catalina made the existing app I had built around the Java app no longer work.
Ultimately, this post helped: Just use Automator to run a script that runs the java command to launch the jar. I wanted to make an app to launch Colossus, a Java version of the old Avalon Hill board game Titan. I wrote a shell script that looks like:java -Xmx256m -jar /my/path/to/the/game/Colossus.jar net.sf.colossus.appmain.Start and then created an automator application whose only action was "Run Shell Script" that launches that script. Works like a charm, no installing Ant, no command line apps requiring you to download java vms, and best of all it uses an Apple tool so will work with newer versions of OS X.
You can try this app , it bundles your jar file into Mac app
Edit: it's easy to use , select the Jar file and an Icon. Here you can see the screen shoot.
https://github.com/aprsn/Mac-App-Creator

Convert .Jar to .Dmg

I have a java application with jar file and a lib folder to go with it,and i want to bundle my application along with the lib files and folders into a .DMG file to run on MAC OS x so if anybody has a similar experience please help me out.
Thanks in advance
You put all your files in one folder together. Then you open the Disk Utility (Applications -> Utilities -> Disk Utility) and choose "New Image from folder..."
That's all.
You might want to make a dmg disk image from the makefile/build file:
hdiutil create -srcfolder <directory> <dmg_file_name>.dmg
You can use the javapackager tool to build the you_app.app application and wrap it into an installer:
mkdir -p package/macosx
cp you_icon_app.icns package/macosx
jdk=$(/usr/libexec/java_home)
$jdk/bin/javapackager -version
$jdk/bin/javapackager -deploy -native dmg \
-srcfiles you_app.jar -appclass you_app_name -name you_app_name \
-outdir deploy -outfile you_app_name -v
cp deploy/bundles/you_app_name-1.0.dmg you_app_name-installer.dmg
And done.
I use a maven plugin: osxappbundle-maven-plugin

Categories