{"id":1605,"date":"2016-02-21T14:34:05","date_gmt":"2016-02-21T12:34:05","guid":{"rendered":"https:\/\/blog.zitnik.si\/?p=1605"},"modified":"2017-09-04T15:39:16","modified_gmt":"2017-09-04T13:39:16","slug":"creating-a-mac-os-app-from-a-runnable-jar-file","status":"publish","type":"post","link":"https:\/\/blog.zitnik.si\/?p=1605","title":{"rendered":"Creating a Mac OS .app from a runnable JAR file"},"content":{"rendered":"<p>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.<\/p>\n<p>Mac OS applications (.app files) are basically packages with a specific folder structure. You can easily explore each app&#8217;s structure by clicking on it using right click in Finder and selecting &#8220;Show Package Contents&#8221;.<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.41.png\" rel=\"attachment wp-att-1606\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1606 size-full aligncenter\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.41.png\" alt=\"Screen Shot 2016-02-21 at 11.42.41\" width=\"501\" height=\"354\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.41.png 501w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.41-300x212.png 300w\" sizes=\"auto, (max-width: 501px) 100vw, 501px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.53.png\" rel=\"attachment wp-att-1607\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1607\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.53.png\" alt=\"Screen Shot 2016-02-21 at 11.42.53\" width=\"612\" height=\"216\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.53.png 612w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.42.53-300x106.png 300w\" sizes=\"auto, (max-width: 612px) 100vw, 612px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Creating a custom .app<\/p>\n<p>Create a folder PROGRAM_NAME.app. The Finder will ask you the following, which you will answer as add.<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.46.37.png\" rel=\"attachment wp-att-1608\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1608\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.46.37.png\" alt=\"Screen Shot 2016-02-21 at 11.46.37\" width=\"438\" height=\"172\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.46.37.png 438w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-11.46.37-300x118.png 300w\" sizes=\"auto, (max-width: 438px) 100vw, 438px\" \/><\/a><\/p>\n<p>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).<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.49.45.png\" rel=\"attachment wp-att-1611\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1611\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.49.45.png\" alt=\"Screen Shot 2016-02-21 at 12.49.45\" width=\"768\" height=\"195\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.49.45.png 768w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.49.45-300x76.png 300w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.49.45-470x120.png 470w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><br \/>\nThis script needs to be an executable, so open Terminal and run a command like this:<\/p>\n<p>[codesyntax lang=&#8221;bash&#8221;]<\/p>\n<pre>chmod a+x Sociogram.app\/Contents\/MacOS\/launcher.sh<\/pre>\n<p>[\/codesyntax]<\/p>\n<p>Maybe you have noticed that your .app does not have an icon. Therefore you need an .icns icon. I used a web service (<a href=\"https:\/\/iconverticons.com\/online\/\" target=\"_blank\" rel=\"noopener\">https:\/\/iconverticons.com\/online\/<\/a>) to convert my PNG file to an appropriate ICNS file.<\/p>\n<p>Now, create a folder Resources and copy your icon there:<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.51.25.png\" rel=\"attachment wp-att-1612\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1612\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.51.25.png\" alt=\"Screen Shot 2016-02-21 at 12.51.25\" width=\"658\" height=\"101\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.51.25.png 658w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.51.25-300x46.png 300w\" sizes=\"auto, (max-width: 658px) 100vw, 658px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>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:<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.54.14.png\" rel=\"attachment wp-att-1613\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1613\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.54.14.png\" alt=\"Screen Shot 2016-02-21 at 12.54.14\" width=\"985\" height=\"380\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.54.14.png 985w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.54.14-300x116.png 300w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.54.14-768x296.png 768w\" sizes=\"auto, (max-width: 985px) 100vw, 985px\" \/><\/a><\/p>\n<p>After these steps, you should have prepared an .app file, which looks like as follows:<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.55.39.png\" rel=\"attachment wp-att-1614\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1614\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.55.39.png\" alt=\"Screen Shot 2016-02-21 at 12.55.39\" width=\"651\" height=\"400\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.55.39.png 651w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-12.55.39-300x184.png 300w\" sizes=\"auto, (max-width: 651px) 100vw, 651px\" \/><\/a><\/p>\n<p><strong>Creating\u00a0a runnable script for a JAR<\/strong><\/p>\n<p>First, let use create a Java Application that will print out the current working directory and package it into a runnable JAR (sociogram.jar):<\/p>\n<p>[codesyntax lang=&#8221;java&#8221;]<\/p>\n<pre>import javax.swing.*;\r\nimport java.awt.*;\r\n\r\n\/**\r\n * Created by slavkoz on 21\/02\/16.\r\n *\/\r\npublic class Runner {\r\n    public static void main(String[] args) {\r\n        JFrame frame = new JFrame();\r\n\r\n        JPanel panel = new JPanel();\r\n        panel.setLayout(new BorderLayout());\r\n        panel.add(new JTextField(System.getProperty(\"user.dir\")), BorderLayout.CENTER);\r\n        frame.setContentPane(panel);\r\n\r\n        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);\r\n        frame.pack();\r\n        frame.setVisible(true);\r\n    }\r\n}<\/pre>\n<p>[\/codesyntax]<\/p>\n<p>If we now just run that jar from a launcher script, the default working directory for Java would be &#8220;\/&#8221;, so we may have problem accessing resources, that are packaged inside our .app.<\/p>\n<p>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.<\/p>\n<p>[codesyntax lang=&#8221;bash&#8221;]<\/p>\n<pre>#!\/bin\/sh\r\n\r\nDIR=$1\r\nAPP_JAR=\"sociogram.jar\"\r\nAPP_NAME=\"Sociogram 5.0\"\r\n\r\ncd \"$DIR\"\r\njava -Xdock:name=\"$APP_NAME\" -Xdock:icon=\"$DIR\/..\/Resources\/application.icns\" -cp \"$DIR;.;\" -jar \"$DIR\/$APP_JAR\"<\/pre>\n<p>[\/codesyntax]<\/p>\n<p>Now, we can update the launcher script, which will detect the directory, where it resides and run the socioRunner script with a parameter:<\/p>\n<p>[codesyntax lang=&#8221;bash&#8221;]<\/p>\n<pre>#!\/bin\/sh\r\n\r\n# Set the working directory\r\nDIR=$(cd \"$(dirname \"$0\")\"; pwd)\r\n\r\n# Run the application\r\nexec \"$DIR\/socioRunner\" $DIR<\/pre>\n<p>[\/codesyntax]<\/p>\n<p>So, voila, now we get the following result when the .app application is run from Finder:<\/p>\n<p><a href=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-13.32.45.png\" rel=\"attachment wp-att-1616\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1616\" src=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-13.32.45.png\" alt=\"Screen Shot 2016-02-21 at 13.32.45\" width=\"503\" height=\"57\" srcset=\"https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-13.32.45.png 503w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-13.32.45-300x34.png 300w, https:\/\/blog.zitnik.si\/wp-content\/uploads\/2016\/02\/Screen-Shot-2016-02-21-at-13.32.45-490x57.png 490w\" sizes=\"auto, (max-width: 503px) 100vw, 503px\" \/><\/a><\/p>\n<p>You can download the whole .app file from here:\u00a0<a href=\"https:\/\/blog.zitnik.si\/manual_upload\/Sociogram.app.zip\" target=\"_blank\" rel=\"noopener\">https:\/\/blog.zitnik.si\/manual_upload\/Sociogram.app.zip<\/a><\/p>\n<div style=\"margin-top: 0px; margin-bottom: 0px;\" class=\"sharethis-inline-share-buttons\" ><\/div>","protected":false},"excerpt":{"rendered":"<p>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&#8217;s structure&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/blog.zitnik.si\/?p=1605\">Continue reading<span class=\"screen-reader-text\">Creating a Mac OS .app from a runnable JAR file<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":1645,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-1605","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-computer-engineering","entry"],"_links":{"self":[{"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/posts\/1605","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1605"}],"version-history":[{"count":4,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/posts\/1605\/revisions"}],"predecessor-version":[{"id":1647,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/posts\/1605\/revisions\/1647"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=\/wp\/v2\/media\/1645"}],"wp:attachment":[{"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1605"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1605"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zitnik.si\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1605"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}