{"id":335,"date":"2015-09-18T10:31:45","date_gmt":"2015-09-18T14:31:45","guid":{"rendered":"http:\/\/pmcgovern.ca\/wp\/?p=335"},"modified":"2021-12-12T12:34:33","modified_gmt":"2021-12-12T17:34:33","slug":"compile-groovy-to-executable-jar","status":"publish","type":"post","link":"https:\/\/pmcgovern.ca\/wp\/?p=335","title":{"rendered":"Compile Groovy to Executable JAR"},"content":{"rendered":"<p>I&#8217;ve been working on automating some deployment tasks using Jenkins and Groovy. Fun stuff, but dealing with dependencies at runtime is a hassle. Yes, Maven will fetch everything you need, but sometimes you don&#8217;t have line-of-sight to Maven Central from a production machine or don&#8217;t want to to download the Interwebs.<\/p>\n<p>Fortunately, Maven&#8217;s Assembly Plugin can cram everything into a single executable JAR. Here is a simple Groovy example to show how to do it:<\/p>\n<p><a href=\"https:\/\/github.com\/paulmcgovern\/groovy-standalone\">https:\/\/github.com\/paulmcgovern\/groovy-standalone<\/a><\/p>\n<p>The Groovy script in the project accepts two numbers, and outputs true if the first number multiplied by three equals the second. Maven exec will execute it if you set the script as the main class in the POM.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\"><plugin>\n  <groupid>org.codehaus.mojo<\/groupid>\n<artifactid>exec-maven-plugin<\/artifactid>\n<version>1.2.1<\/version>\n<configuration>\n<mainclass>ca.pmcgovern.Main<\/mainclass>\n<\/configuration>\n<\/plugin>\n<\/pre>\n<p>The compiled JAR is 6M (<em>sic.<\/em>) and arguments can be passed with <strong>exec.args<\/strong> JVM parameters:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">$ mvn exec:java -Dexec.args=\"2 6\"\n[INFO] Scanning for projects...\n[INFO]\n[INFO] ---------------------------------------------------------------\n[INFO] Building groovy_standalone 1.0-SNAPSHOT\n[INFO] ---------------------------------------------------------------\n[INFO]\n[INFO] &gt;&gt;&gt; exec-maven-plugin:1.2.1:java (default-cli) @ groovy_mvn &gt;&gt;&gt;\n[INFO]\n[INFO] &lt;&lt;&lt; exec-maven-plugin:1.2.1:java (default-cli) @ groovy_mvn &lt;&lt;&lt;\n[INFO]\n[INFO] --- exec-maven-plugin:1.2.1:java (default-cli) @ groovy_mvn ---\n2 * 3 = 6 : true\n[INFO] ---------------------------------------------------------------\n[INFO] BUILD SUCCESS\n[INFO] ---------------------------------------------------------------\n[INFO] Total time: 2.262s\n[INFO] Finished at: Fri Sep 18 09:40:41 EDT 2015\n[INFO] Final Memory: 11M\/149M\n[INFO] ---------------------------------------------------------------\n<\/pre>\n<p>To build the stand-alone JAR run the Assembly plugin:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">$ mvn compile assembly:single\n<\/pre>\n<p>In this case, the jar weighs in at a svelte 17M, but can be run directly with Java:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">$ java -jar target\/groovy_mvn-1.0-SNAPSHOT-jar-with-dependencies.jar 2 6\n2 * 3 = 6 : true\n<\/pre>\n<p>The JAR works because the main class is specified in the manifest and the plugin is set to include dependencies in the POM:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\"><plugin>\n  <groupid>org.apache.maven.plugins<\/groupid>\n<artifactid>maven-assembly-plugin<\/artifactid>\n<version>2.4<\/version>\n<configuration>\n<archive>\n<manifest>\n<mainclass>ca.pmcgovern.Main<\/mainclass>\n<\/manifest>\n<\/archive>\n<descriptorrefs>\n<descriptorref>jar-with-dependencies<\/descriptorref>\n<\/descriptorrefs>\n<\/configuration>\n<\/plugin>\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been working on automating some deployment tasks using Jenkins and Groovy. Fun stuff, but dealing with dependencies at runtime is a hassle. Yes, Maven will fetch everything you need, but sometimes you don&#8217;t have line-of-sight to Maven Central from&#8230;<\/p>\n","protected":false},"author":1,"featured_media":622,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[],"class_list":["post-335","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/posts\/335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=335"}],"version-history":[{"count":9,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/posts\/335\/revisions"}],"predecessor-version":[{"id":877,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/posts\/335\/revisions\/877"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=\/wp\/v2\/media\/622"}],"wp:attachment":[{"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pmcgovern.ca\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}