{"id":1178,"date":"2016-10-16T11:55:43","date_gmt":"2016-10-16T11:55:43","guid":{"rendered":"http:\/\/blog.paranoidprofessor.com\/?p=1178"},"modified":"2016-10-16T11:55:43","modified_gmt":"2016-10-16T11:55:43","slug":"making-more-than-jar-files-with-ant","status":"publish","type":"post","link":"https:\/\/blog.paranoidprofessor.com\/index.php\/2016\/10\/16\/making-more-than-jar-files-with-ant\/","title":{"rendered":"making more than jar files with Ant"},"content":{"rendered":"<p>In a\u00a0previous post, <a href=\"http:\/\/blog.paranoidprofessor.com\/index.php\/2016\/10\/08\/compiling-and-making-jar-files-with-ant\/\">making jar files with Ant<\/a>, \u00a0I briefly covered the creation of a Ant script that would compile the Java source files and then create jar file from them.<\/p>\n<p>It was a really neat example of how with less than 100 lines of script ant can compile the source, create a zip file from the source, create a jar and even include the source files in the jar file (optionally).<\/p>\n<p>This is possible due to the powerful list of (over 150) tasks that are available to your scripts. \u00a0This list ranges from the more common tasks like<\/p>\n<ul>\n<li>copy files or directories<\/li>\n<li>delete a file or directory<\/li>\n<li>make directory<\/li>\n<li>zip \/ unzip<\/li>\n<li>tar \/ untar<\/li>\n<li>fix operating system line endings<\/li>\n<li>auto incrementing build number<\/li>\n<li>secure copy<\/li>\n<li>clearcase access tool<\/li>\n<li>cvs access tool<\/li>\n<\/ul>\n<p>This is just a small list of what is available. \u00a0If the list of tasks doesn&#8217;t contain what you need you can either execute any system command. \u00a0It is also possible to extend Ant with new tasks but I won&#8217;t be getting into that right now.<\/p>\n<h2>Creating a package<\/h2>\n<p>It is beyond the scope of this blog entry to cover the creation of something really interesting like creating a Debian or Red Hat Package but Ant could probably do it.<\/p>\n<p>One of the IT groups that I\u00a0have worked with in the past had their own custom package installation system. \u00a0It was really just a zip file with one of the files containing the inventory\u00a0of files in the package as well as which types of operations should be done as part of the install.<\/p>\n<p>The package installer then read the inventory file and proceeded to copy, delete and in general install files to their machine. \u00a0The actual format of their package is irrelevant for this example, however, below is a similar style of how we used Ant to build our packages for that client.<\/p>\n<pre class=\"xml\">\t&lt;target name=\"package\" depends=\"jarfile,srcfile\" description=\"prepare for release\"&gt;\r\n\t\t&lt;echo&gt;\"preparing ...\"&lt;\/echo&gt;\r\n \r\nstep 1\t\t&lt;!-- create a temp directory with name of our package --&gt;\r\n\t\t&lt;mkdir dir=\"${packagename}\"\/&gt;\r\n \r\n\t\t&lt;!-- fill it with all sorts of program goodness --&gt;\r\n\r\nstep2\t\t&lt;!-- contents of our \"static\" files--&gt;\r\n\t\t&lt;copy todir=\"${packagename}\/${packagename}\" verbose=\"No\" preservelastmodified=\"Yes\"&gt;\r\n\t\t\t&lt;fileset dir=\"${package.dir}\" includes=\"**\" \/&gt;\r\n\t\t&lt;\/copy&gt;\r\n \r\nstep 3\t\t&lt;!-- contents of other libraries --&gt;\r\n\t\t&lt;copy todir=\"${packagename}\/${packagename}\/lib\" verbose=\"No\" preservelastmodified=\"Yes\"&gt;\r\n\t\t\t&lt;fileset dir=\"${lib.dir}\" includes=\"**\" \/&gt;\r\n\t\t&lt;\/copy&gt;\r\n \r\nstep 4\t\t&lt;!-- copy our program --&gt;\r\n\t\t&lt;copy file=\"${build.dir}\/${jarname}.jar\" todir=\"${packagename}\/${packagename}\/lib\" verbose=\"No\" preservelastmodified=\"Yes\"\/&gt;\r\n\r\nstep 5\t\t&lt;!-- turn it into a zip file --&gt;\r\n\t\t&lt;zip zipfile=\"${build.dir}\/${packagename}.zip\" basedir=\"${packagename}\" \r\n\t\t\tincludes=\"**\"&gt;\r\n\t\t&lt;\/zip&gt;\r\n \r\nstep 6\t\t&lt;!-- turn it into a tar file --&gt;\r\n\t\t&lt;tar compression=\"gzip\" destfile=\"${build.dir}\/${zipfile}-${version.num}.tar.gz\"&gt;\r\n\t\t\t&lt;tarfileset dir=\"${packagename}\" &gt;\r\n\t\t\t\t&lt;include name=\"**\" \/&gt; \r\n\t\t\t&lt;\/tarfileset&gt;\r\n\t\t&lt;\/tar&gt;\r\n \r\nstep 7\t\t&lt;!-- clean up after ourselves --&gt;\r\n\t\t&lt;delete dir=\"${packagename}\"\/&gt;\r\n\t&lt;\/target&gt;<\/pre>\n<p>The actual ant tasks and their comment should actually be enough, but just in case I have summarized each step in the following table.<\/p>\n<p>&nbsp;<\/p>\n<table class=\"w3-table-all\">\n<tbody>\n<tr>\n<th>Step<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td>1.<\/td>\n<td>Create a temporary directory using the name of the package.<\/td>\n<\/tr>\n<tr>\n<td>2.<\/td>\n<td>Copy all files from my directory that contained some of the more static\u00a0package files into\u00a0the temporary directory. \u00a0This directory contains any other configuration or data files.<\/td>\n<\/tr>\n<tr>\n<td>3.<\/td>\n<td>Copy all libraries from the lib directory into the temporary directory.<\/td>\n<\/tr>\n<tr>\n<td>4.<\/td>\n<td>Copy our newly created java library into the temporary directory.<br \/>\nNote: we could have created the java library in that directory directly but that would have not been so obvious compared to the build file we have.<\/td>\n<\/tr>\n<tr>\n<td>5.<\/td>\n<td>Create a zip file using the temporary directory as our source. \u00a0This will create the zip file with the same name as our package which is quite convenient.<br \/>\nNote: the permissions get lost on the runInterface.sh file<\/td>\n<\/tr>\n<tr>\n<td>6.<\/td>\n<td>Create a gzipped tar file using the temporary directory as our source. This will create the tar\u00a0file with the same name as our package which is quite convenient.<br \/>\nNote: the permissions get lost on the runInterface.sh file<br \/>\nYou could get around this by running an operating system command (tar).<\/td>\n<\/tr>\n<tr>\n<td>7.<\/td>\n<td>Remove the temporary directory as no longer necessary.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Below is the complete source code for a log4j2 based Hello world application. \u00a0It isn&#8217;t the program that is so interesting but how the build script, using the package generation seen above can create our zip with our program.<\/p>\n<p>If you look closely at the build script you will see it includes the two log4j2 jar files in the classpath allowing us to have a runnable jar not just a\u00a0normal jar.<\/p>\n<p>Simply unzip the package into a directory and the scripts can be run immediately.<\/p>\n<div id=\"code-link-1178\" class=\"sh-link code-link sh-hide\"><a href=\"#\" onclick=\"showhide_toggle('code', 1178, 'Show complete example (341 More Words)', 'Hide code'); return false;\" aria-expanded=\"false\"><span id=\"code-toggle-1178\">Show complete example (341 More Words)<\/span><\/a><\/div><div id=\"code-content-1178\" class=\"sh-content code-content sh-hide\" style=\"display: none;\"><\/p>\n<p><strong>HelloWorld.java<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">package de.companyname.helloworld;\r\n\r\nimport org.apache.logging.log4j.LogManager;\r\nimport org.apache.logging.log4j.Logger;\r\n\r\npublic class HelloWorld {\r\n\r\n\tpublic HelloWorld()\r\n\t{\r\n\t\tcommunicate();\r\n\t}\r\n\tpublic void communicate()\r\n\t{\r\n\t\tLogger logfile = LogManager.getLogger(HelloWorld.class.getName());\r\n\t\t\r\n\t\tlogfile.debug(&quot;HelloWorld starting &quot;);\r\n\t\t\r\n\t\tlogfile.info(&quot;Hello World!&quot;);\r\n\r\n\t\tlogfile.debug(&quot;HelloWorld finishing &quot;);\r\n\t}\r\n\t\r\n\tpublic static void main(String args[])\r\n\t{\r\n\t\tnew HelloWorld();\r\n\t}\r\n}\r\n<\/pre>\n<p><strong>log4j2.xml<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\r\n&lt;Configuration xmlns=&quot;http:\/\/logging.apache.org\/log4j\/2.0\/config&quot;&gt;\r\n\r\n\t&lt;Appenders&gt;\r\n\t&lt;File name=&quot;FILE&quot; fileName=&quot;${sys:LOGDIR}\/logfile.log&quot; append=&quot;true&quot;&gt;\r\n\t\t&lt;PatternLayout pattern=&quot;%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C (%F:%L) - %m%n&quot;\/&gt;\r\n\t&lt;\/File&gt;\r\n\t&lt;Console name=&quot;STDOUT&quot; target=&quot;SYSTEM_OUT&quot;&gt;\r\n\t\t&lt;PatternLayout pattern=&quot;%d{yyyy-MM-dd HH:mm:ss} | %-5p | %C{2} (%F:%L) - %m%n&quot;\/&gt;\r\n\t&lt;\/Console&gt;\r\n\t&lt;\/Appenders&gt;\r\n\r\n\t&lt;Loggers&gt;\r\n\t\t&lt;Root level=&quot;debug&quot;&gt;\r\n\t\t&lt;AppenderRef ref=&quot;STDOUT&quot; \/&gt;\r\n\t\t\t&lt;AppenderRef ref=&quot;FILE&quot; \/&gt;\r\n\t\t&lt;\/Root&gt;\r\n\t&lt;\/Loggers&gt;\r\n\r\n&lt;\/Configuration&gt;\r\n<\/pre>\n<p><strong>build.xml<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;project default=&quot;world&quot; basedir=&quot;.&quot;&gt;\r\n\r\n&lt;property file=&quot;project.properties&quot;\/&gt;\r\n\r\n\t&lt;property name=&quot;lib.dir&quot; value=&quot;${basedir}\/lib&quot;\/&gt;\r\n\t&lt;property name=&quot;src.dir&quot; value=&quot;${basedir}\/src&quot;\/&gt;\r\n\t&lt;property name=&quot;class.dir&quot; value=&quot;${basedir}\/bin&quot;\/&gt;\r\n\t&lt;property name=&quot;build.dir&quot; value=&quot;${basedir}\/final&quot;\/&gt;\r\n\t&lt;property name=&quot;package.dir&quot; value=&quot;${basedir}\/package&quot;\/&gt;\r\n\t&lt;property name=&quot;packagename&quot; value=&quot;${jarname}-${version.num}&quot;\/&gt;\r\n \r\n\t&lt;path id=&quot;classpath&quot;&gt;\r\n\t\t&lt;fileset dir=&quot;${lib.dir}&quot; includes=&quot;**\/*.jar&quot;\/&gt;\r\n\t&lt;\/path&gt;\r\n\r\n\t&lt;target name=&quot;clean&quot; description=&quot;remove anything we created&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;cleaning ...&quot;&lt;\/echo&gt;\r\n\t\t&lt;delete dir=&quot;${class.dir}&quot;\/&gt;\r\n\t\t&lt;delete dir=&quot;${build.dir}&quot;\/&gt;\r\n\t&lt;\/target&gt;\r\n\r\n\t&lt;target name=&quot;copysource&quot; description=&quot;copy source code for jar&quot; if=&quot;copysource&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;copying ...&quot;&lt;\/echo&gt;\r\n\t\t&lt;mkdir dir=&quot;${class.dir}&quot;\/&gt;\r\n\t\t&lt;copy todir=&quot;${class.dir}&quot; verbose=&quot;No&quot; preservelastmodified=&quot;Yes&quot;&gt;\r\n\t\t\t&lt;fileset dir=&quot;${src.dir}&quot; includes=&quot;**\/*.java&quot; \/&gt;\r\n\t\t&lt;\/copy&gt;\r\n\t&lt;\/target&gt;\r\n\r\n\t&lt;target name=&quot;compile&quot; depends=&quot;copysource&quot; description=&quot;compile source code&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;compiling ...&quot;&lt;\/echo&gt;\r\n\t\t&lt;mkdir dir=&quot;${class.dir}&quot;\/&gt;\r\n\t\t&lt;javac srcdir=&quot;${src.dir}&quot; destdir=&quot;${class.dir}&quot; classpathref=&quot;classpath&quot; debug=&quot;on&quot;\/&gt; \r\n\t&lt;\/target&gt;\r\n\r\n\t&lt;target name=&quot;jarfile&quot; depends=&quot;compile&quot; description=&quot;generate jar file&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;build jar ...&quot;&lt;\/echo&gt;\r\n\t\t&lt;mkdir dir=&quot;${build.dir}&quot;\/&gt;\r\n \r\n\t\t&lt;tstamp&gt;\r\n\t\t\t&lt;format property=&quot;today.timestamp&quot; pattern=&quot;yyyy-MM-dd HH:mm:ss&quot; \/&gt;\r\n\t\t&lt;\/tstamp&gt;\r\n \r\n\t\t&lt;jar destfile=&quot;${build.dir}\/${jarname}.jar&quot; basedir=&quot;${class.dir}&quot;&gt;\r\n\t\t&lt;manifest&gt;\r\n\t\t\t&lt;attribute name=&quot;Built-By&quot; value=&quot;${user.name}&quot; \/&gt;\r\n\t\t\t&lt;attribute name=&quot;Main-Class&quot; value=&quot;${mainclass}&quot; \/&gt;\r\n\t\t\t&lt;attribute name=&quot;Implementation-Version&quot; value=&quot;${version.num} build #${build.num}&quot;\/&gt;\r\n\t\t\t&lt;attribute name=&quot;Built-Date&quot; value=&quot;${today.timestamp}&quot;\/&gt;\r\n\t\t\t&lt;attribute name=&quot;Class-Path&quot; value=&quot;..\/lib\/log4j-core-2.6.2.jar ..\/lib\/log4j-api-2.6.2.jar ..\/resources\/log4j2.xml&quot;\/&gt;\r\n\t\t&lt;\/manifest&gt;\r\n\t\t&lt;\/jar&gt;\r\n\t&lt;\/target&gt;\r\n\r\n\t&lt;target name=&quot;srcfile&quot; description=&quot;prepare source tar file&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;gather source ...&quot;&lt;\/echo&gt;\r\n\r\n\t\t&lt;zip zipfile=&quot;${build.dir}\/${zipfile}-${version.num}.zip&quot; basedir=&quot;${src.dir}&quot; includes=&quot;**&quot;&gt;\r\n\t\t&lt;\/zip&gt;\r\n\t&lt;\/target&gt;\r\n \r\n\t&lt;target name=&quot;package&quot; depends=&quot;jarfile,srcfile&quot; description=&quot;prepare for release&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;preparing ...&quot;&lt;\/echo&gt;\r\n \r\n\t\t&lt;!-- create a temp directory with name of our package --&gt;\r\n\t\t&lt;mkdir dir=&quot;${packagename}&quot;\/&gt;\r\n \r\n\t\t&lt;!-- fill it with all sorts of program goodness --&gt;\r\n\r\n\t\t&lt;!-- contents of our &quot;static&quot; files--&gt;\r\n\t\t&lt;copy todir=&quot;${packagename}\/${packagename}&quot; verbose=&quot;No&quot; preservelastmodified=&quot;Yes&quot;&gt;\r\n\t\t\t&lt;fileset dir=&quot;${package.dir}&quot; includes=&quot;**&quot; \/&gt;\r\n\t\t&lt;\/copy&gt;\r\n \r\n\t\t&lt;!-- contents of other libraries --&gt;\r\n\t\t&lt;copy todir=&quot;${packagename}\/${packagename}\/lib&quot; verbose=&quot;No&quot; preservelastmodified=&quot;Yes&quot;&gt;\r\n\t\t\t&lt;fileset dir=&quot;${lib.dir}&quot; includes=&quot;**&quot; \/&gt;\r\n\t\t&lt;\/copy&gt;\r\n \r\n\t\t&lt;!-- copy our program --&gt;\r\n\t\t&lt;copy file=&quot;${build.dir}\/${jarname}.jar&quot; todir=&quot;${packagename}\/${packagename}\/lib&quot; verbose=&quot;No&quot; preservelastmodified=&quot;Yes&quot;\/&gt;\r\n\r\n\t\t&lt;!-- turn it into a zip file as well --&gt;\r\n\t\t&lt;zip zipfile=&quot;${build.dir}\/${packagename}.zip&quot; basedir=&quot;${packagename}&quot; includes=&quot;**&quot;&gt;\r\n\t\t&lt;\/zip&gt;\r\n\r\n\t\t&lt;!-- turn it into a tar file --&gt;\r\n\t\t&lt;tar compression=&quot;gzip&quot; destfile=&quot;${build.dir}\/${zipfile}-${version.num}.tar.gz&quot;&gt;\r\n\t\t\t&lt;tarfileset dir=&quot;${packagename}&quot; &gt;\r\n\t\t\t\t&lt;include name=&quot;**&quot; \/&gt; \r\n\t\t\t&lt;\/tarfileset&gt;\r\n\t\t&lt;\/tar&gt;\r\n \r\n\t\t&lt;!-- clean up after ourselves --&gt;\r\n\t\t&lt;delete dir=&quot;${packagename}&quot;\/&gt;\r\n\t&lt;\/target&gt;\r\n\r\n\t&lt;target name=&quot;world&quot; depends=&quot;package&quot;&gt;\r\n\t\t&lt;echo&gt;&quot;build script version 1.00&quot;&lt;\/echo&gt;\r\n\t&lt;\/target&gt;\r\n&lt;\/project&gt;\r\n<\/pre>\n<p><strong>project.properties<\/strong><\/p>\n<div class=\"sbody-code\">\n<pre>version.num = 3.13.047\r\nbuild.num = 9\r\nmainclass = de.companyname.helloworld.HelloWorld\r\njarname = communication\r\nzipfile = communication-src\r\ncopysource = true<\/pre>\n<\/div>\n<p><strong>\u00a0<\/strong><strong>runInterface.sh<\/strong><\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n#!\/bin\/bash\r\nLOGDIR=`pwd`\/log\r\nCP=&quot;`pwd`\/lib\/log4j-api-2.6.2.jar:`pwd`\/lib\/log4j-core-2.6.2.jar:`pwd`\/lib\/communication.jar:resources&quot;\r\nCFGFILE=`pwd`\/resources\/log4j2.xml\r\nPGM=de.companyname.helloworld.HelloWorld\r\n\r\nif [ ! -d $LOGDIR ]\r\nthen\r\n mkdir $LOGDIR\r\nfi\r\n\r\necho first run\r\nCMD=&quot;java -DLOGDIR=$LOGDIR -cp $CP $PGM &quot;\r\necho $CMD\r\n$CMD\r\necho .\r\n\r\necho second run\r\necho .\r\ncd lib\r\nCMD=&quot;java -DLOGDIR=$LOGDIR -Dlog4j.configurationFile=$CFGFILE -jar communication.jar&quot;\r\necho $CMD\r\n$CMD\r\necho .\r\n<\/pre>\n<p><strong>other setup notes<\/strong><\/p>\n<pre>create directory structure\r\nmkdir \\development\\hello\\src\\de\\companyname\\helloword\r\nmkdir \\development\\hello\\package\r\nmkdir \\development\\hello\\package\\resources\r\nmkdir \\development\\hello\\lib\r\ncopy the log4j2.xml to resources directory\r\ncopy log4j2 jar files to lib directory\r\ncopy build.xml hello directory\r\ncopy project.properties hello directory\r\ncopy runInterface.sh hello directory\r\ncopy runInterface.bat to hello directory\r\ncopy HelloWorld.java to helloworld directory\r\n\r\nNote: make sure your path delimiters are correct in build script if you are automatically creating manifest file.<\/pre>\n<p><\/div>\n<p>&nbsp;<\/p>\n<p>Note: The\u00a0example was compiled with java 1.8 and uses log4j-api-2.6.2.jar and log4j-core-2.6.2.jar.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a\u00a0previous post, making jar files with Ant, \u00a0I briefly covered the creation of a Ant script that would compile the Java source files and then create jar file from them. It was a really neat example of how with &hellip; <a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2016\/10\/16\/making-more-than-jar-files-with-ant\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[20,3],"tags":[73,12,78],"_links":{"self":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1178"}],"collection":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/comments?post=1178"}],"version-history":[{"count":22,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1178\/revisions"}],"predecessor-version":[{"id":1583,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1178\/revisions\/1583"}],"wp:attachment":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/media?parent=1178"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/categories?post=1178"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/tags?post=1178"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}