Here we solve a problem that many developers face when bundling java applications into an .app. We are going to correctly set the current working path for your Java Application.
Mac OS applications (.app files) are basically packages with a specific folder structure. You can easily explore each app’s structure by clicking on it using right click in Finder and selecting “Show Package Contents”.
Creating a custom .app
Create a folder PROGRAM_NAME.app. The Finder will ask you the following, which you will answer as add.
Now, show contents of you app and inside it create a folder structure /Contents/MacOS. Also create a blank script file launcher.sh (in my case, I am using Sociogram as a program name).
This script needs to be an executable, so open Terminal and run a command like this:
[codesyntax lang=”bash”]
chmod a+x Sociogram.app/Contents/MacOS/launcher.sh
[/codesyntax]
Maybe you have noticed that your .app does not have an icon. Therefore you need an .icns icon. I used a web service (https://iconverticons.com/online/) to convert my PNG file to an appropriate ICNS file.
Now, create a folder Resources and copy your icon there:
The last step now is to create a config file Info.plist that will define, which is an executable file in your app and where is your .app icon:
After these steps, you should have prepared an .app file, which looks like as follows:
Creating a runnable script for a JAR
First, let use create a Java Application that will print out the current working directory and package it into a runnable JAR (sociogram.jar):
[codesyntax lang=”java”]
import javax.swing.*; import java.awt.*; /** * Created by slavkoz on 21/02/16. */ public class Runner { public static void main(String[] args) { JFrame frame = new JFrame(); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(new JTextField(System.getProperty("user.dir")), BorderLayout.CENTER); frame.setContentPane(panel); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }
[/codesyntax]
If we now just run that jar from a launcher script, the default working directory for Java would be “/”, so we may have problem accessing resources, that are packaged inside our .app.
Therefore, let us create an executable socioRunner script that will accept current working dir and run our java application from there. We put the script in the same directory as the launcher script.
[codesyntax lang=”bash”]
#!/bin/sh DIR=$1 APP_JAR="sociogram.jar" APP_NAME="Sociogram 5.0" cd "$DIR" java -Xdock:name="$APP_NAME" -Xdock:icon="$DIR/../Resources/application.icns" -cp "$DIR;.;" -jar "$DIR/$APP_JAR"
[/codesyntax]
Now, we can update the launcher script, which will detect the directory, where it resides and run the socioRunner script with a parameter:
[codesyntax lang=”bash”]
#!/bin/sh # Set the working directory DIR=$(cd "$(dirname "$0")"; pwd) # Run the application exec "$DIR/socioRunner" $DIR
[/codesyntax]
So, voila, now we get the following result when the .app application is run from Finder:
You can download the whole .app file from here: https://blog.zitnik.si/manual_upload/Sociogram.app.zip