Split a source into multiple zip files using ANT - ant

I want to ask if the following is possible with ANT scripting, hopefully not using any external libraries. I have the current script.
<project default="zip" name="antexample">
<target name="zip">
<tstamp/>
<zip destfile="dest/new.zip" basedir="src" excludes="*.properties"/>
<echo file="metadata.properties"/>
<copy todir="dest">
<fileset dir=".">
<include name="*.properties"/>
</fileset>
</copy>
</target>
</project>
What I hope to be able to do is split the src directory into more than one zip dependent on size. So every time a zip file reaches the limit of 1mb it starts to create a new zip to the limit of 1mb and so on until all of the data is zipped.
Hopefully someone can help. Many thanks in advance.

Related

How can PMD HTML Report's Error Description Link Show Local Folder

I am using PMD source code analyzer (PMD) for my java web project through ant task. The computer is offline (not connected to the Internet). Part of ant task is as follows:
<target name="pmd">
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask">
<classpath>
<fileset dir="E:/pmd-bin-6.41.0/lib">
<include name="*.jar"/>
</fileset>
</classpath>
</taskdef>
<pmd shortfilenames="true" cachelocation="pmd.cache" encoding="UTF-8">
<ruleset>web/resources/category/java/bestpractices.xml</ruleset>
<formatter type="html" tofile="report.html">
</formatter>
<fileset dir="src/java/">
<include name="**/*.java"/>
</fileset>
</pmd>
</target>
When I run pmd target, report.html file is generated ok. The html file basically lists <fileName, lineNumber, description> triplets.
e.g.
foo.java...43...The initializer for variable "tempIDNo" is never used (overwritten on lin 67)
The description in this html file has a link as file:///E:ws/project/${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedassignment which does not work. E:ws/project/ is the folder where my project resides.
As a matter of fact, I have all the necessary html files (such as pmd_rules_java_bestpractices.html) unzipped in E:/pmd-doc-6.41.0 folder.
Could you please help me how to set up description link in html file to show local folder?
Thank you.
Here is the solution I have come up with:
(Using suggestion from (How can I create a link to a local file on a locally-run web page?)) Before ant pmd target define property pmd.website.baseurl
<propery name="pmd.website.baseurl" value="file:///E:/pmd-doc-6.41.0"/>
(Using usage/suggestion from (https://ant.apache.org/manual/Types/filterchain.html#expandproperties), ANT replacing strings in specified files using file with properties ) Change inside target as follows
...
<pmd ...>...
</pmd>
<copy file="report.html" tofile="report2.html">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ExpandProperties"/>
</filterchain>
</copy> ...
Run the ant target.

How to echo the file names that only copied or removed by sync task in ant?

I'm trying to copy the schema files from my workspace to a config folder as part of build.
I've achieved that by using the sync task.
These are my requirements:
1.Need to replace only the latest not every file each time.
2.Need to display in console, what are the files being changed (copied /removed)
<target name="copy-schema">
<sync todir="C:/config/schema">
<fileset dir="${schema.dir}" id="schema_dir"/>
<preserveintarget preserveemptydirs="true">
<include name="**/**" />
</preserveintarget>
</sync>
</target>
This copies the schema Files, but I'm not able to see what are the files copied.
I've tried the below,
<target name="copy-schema">
<sync todir="C:/config/schema">
<fileset dir="${schema.dir}" id="schema_dir"/>
<preserveintarget preserveemptydirs="true">
<include name="**/**" />
</preserveintarget>
</sync>
<property name="filesCopied" refid="schema_dir"/>
<echo>${fileCopied}</echo>
</target>
But it prints all the files in the directory.
Any help is appreciated.
Thanks in advance
The sync task supports a verbose attribute to log the files that are being copied.
Try adding the verbose attribute in your sync:
<sync todir="C:/config/schema" verbose="true">

ANT: ways to include libraries and license issues

I have been trying to use Ant to compile and ready a project for distribution. I have encountered several problems along the way that I have been finally able to solve but the solution leaves me very unsatisfied. First, let me explain the set-up of the project and its dependencies.
I have a project, lets call it Primary which depends on a couple of libraries such as the fantastic Guava. It also depends on another project of mine, lets call it Secondary. The Secondary project also features some dependencies, for example, JDOM2. I have referenced the Jar I build with Ant in Primary.
Let me give you the interesting bits of the build.xml so you can get a picture of what I am doing:
<project name="Primary" default="all" basedir=".">
<property name='build' location='dist' />
<property name='application.version' value='1.0'/>
<property name='application.name' value='Primary'/>
<property name='distribution' value='${application.name}-${application.version}'/>
<path id='compile.classpath'>
<fileset dir='libs'>
<include name='*.jar'/>
</fileset>
</path>
<target name='compile' description='Compile source files.'>
<javac includeantruntime="false" srcdir="src" destdir="bin">
<classpath refid='compile.classpath'/>
</javac>
<target>
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<jar destfile='${build}/${distribution}.jar'>
<fileset dir="bin"/>
<zipgroupfileset dir="libs" includes="*.jar"/>
</jar>
</target>
The Secodnary project's build.xml is nearly identical except that it features a manifest as it needs to run:
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<jar destfile='${dist}/${distribution}.jar' basedir="${build}" >
<fileset dir="${build}"/>
<zipgroupfileset dir="libs" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="lu.tudor.ssi.kiss.climate.ClimateChange"/>
</manifest>
</jar>
</target>
After I got it working, trying for many hours to not include that dependencies as class files but as Jars, I don't have the time or insight to go back and try to figure out what I did wrong. Furthermore, I believe that including these libraries as class files is bad practice as it could give rise to licensing issues while not packaging them and merely including them in a directory along the build Jar would most probably not (And if it would you could choose not to distribute them yourself).
I think my inability to correctly assemble the class path, I always received NoClassDefFoundError for classes or libraries in the Primary project when launching Second's Jar, is that I am not very experienced with Ant. Would I require to specify a class path for both projects? Specifying the class path as . should have allowed me to simply add all dependencies to the same folder as Secondary's Jar, should it not?
You may use the MANIFEST.MF "Class-Path: " to cross-reference your jars.
If they are all in the same directory this will probably work as follows (using it in both projects!):
<target name='jar' description='Create a jar file for distribution.' depends="compile">
<pathconvert property="manifest.classpath" pathsep=" ">
<path refid="compile.classpath" />
<flattenmapper />
</pathconvert>
<jar destfile='${build}/${distribution}.jar'>
<fileset dir="bin"/>
<manifest>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
</target>
This way you can tell the java runtime environment that your jar needs others to work, expecting them to be in the same directory as the jar you are trying to run.
As a result your primary.jar should have secondary.jar in it's classpath and secondary.jar should have guava.jar in it's classpath.
Another way to create the string may be ants manifestclasspath task (https://ant.apache.org/manual/Tasks/manifestclasspath.html) that can handle subdirectories.
If you are goin to use more and more libraries, you may want to have a closer look at ivy or even maven.

CreateProcess error=206, The filename or extension is too long

I'm trying to call Findbugs via Ant, but receiving this error:
Cannot run program "C:\Program Files (x86)\Java\jre6\bin\javaw.exe" (in
directory "H:\Users\MyName\workspace\MyProject"):
CreateProcess error=206, The filename or extension is too long
How can I fix this? o.O
I had the same problem.
I used
<fileset dir="${basedir}/build">
<include name="**/*.class"/>
</fileset>
inside findbugs target and it seems that there is too much .class files to be passed to findbug (?via command line?) because when I used
<fileset dir="${basedir}/build/com/domain/package">
<include name="**/*.class"/>
</fileset>
that had low number of classes, the error was gone.
So, I solved the problem by making one jar file and feeding it to findbugs target with
<findbugs home="${findbugs.home}">
...
<class location="${basedir}/targets/classes-to-analyze.jar"/>
</findbugs>
I think one of the effective file paths are really long when java tries to compile clases.
One worth try is to put codebase in a directory such as C:\MyProject instead of something like C:\Users\MyName\workspace\MyProject
To solve this issue you need to generate a manifestclasspath and a pathing jar.
First Generate your classpath.
<path id="javac.path">
<fileset dir="lib/" includes="**/*.jar"/>
</path>
Next Generate your manifestclasspath
<target name="generate-manifest-classpath">
<manifestclasspath property="manifest.classpath" jarfile="pathing.jar">
<classpath refid="javac.path"/>
</manifestclasspath>
<jar destfile="pathing.jar" basedir="${the location of your build classes}">
<manifest>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
<path id="javac.classpath">
<pathelement path="pathing.jar"/>
</path>
</target>
Next Implement your Manifestclasspath
<javac srcdir="${foo.dir}" destdir="${bar.dir}"
<classpath refid="javac.classpath"/>
</javac>
This will solve the 206 error message if implemented correctly.
I had the same error on IntelliJ while starting debug mode only. To fix is I've changed:
Run > Edit Configurations > "Configuration" tab > Shorten command line
to "JAR-manifest"

Exclude empty directories with Jar Jar Links

I am using an Ant task from Jar Jar Links to embed classes from a 3rd-party jar file (objenesis) in my distributable jar file (example.jar). Jar Jar will translate classes from the original package (org.objenesis) to one of my choosing.
It works but it leaves empty directories in the distributable jar.
Here is a simplified build.xml:
<target name="jar" depends="compile">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="lib/jarjar-1.1.jar"/>
<jarjar jarfile="dist/example.jar" excludes="org.objenesis.**">
<fileset dir="build/classes/main"/>
<zipfileset src="lib/objenesis-1.2.jar"/>
<rule pattern="org.objenesis.**" result="org.thirdparty.#1"/>
</jarjar>
</target>
A sample of contents of the example.jar includes (as expected):
org/thirdparty/Objenesis.class
org/thirdparty/ObjenesisBase.class
but also these empty directories (undesirable):
org/objenesis/
org/objenesis/instantiator/
org/objenesis/instantiator/basic/
My question: how to I exclude these empty directories?
I tried the "zap" option (listed in the doc), but that didn't work.
This appears to be a known issue in Jar Jar, listed in their issue tracker: http://code.google.com/p/jarjar/issues/detail?q=empty&id=32
Given that this was raised almost three years ago and doesn't appear to have got any traction, I suppose your options are to contribute a fix, or to work around it.
An example Ant target to work around it, taking advantage of Ant's support for removing empty directories on copy, would be:
<target name="unpolluted-jarjar" description="JarJars without empty directories">
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="${location.lib}/build/jarjar-1.2.jar"/>
<jarjar basedir="${location.classes}" destfile="${location.dist.binaries}/my-app.jar">
<zipfileset src="${location.lib}/shipped/dependency.jar"/>
<rule pattern="com.example.dependency.**" result="com.example.my-app.jarjar.com.example.dependency.#1"/>
</jarjar>
<mkdir dir="${location.dist.binaries}/exploded"/>
<unzip src="${location.dist.binaries}/my-app.jar" dest="${location.dist.binaries}/exploded/my-app.jar"/>
<copy includeemptydirs="false" todir="${location.dist.binaries}/unpolluted/my-app.jar">
<fileset dir="${location.dist.binaries}/exploded/my-app.jar"/>
</copy>
<jar destfile="${location.dist.binaries}/my-app-unpolluted.jar">
<fileset dir="${location.dist.binaries}/unpolluted/my-app.jar"/>
</jar>
</target>
It's a bit grungy, but it achieves what you want.

Resources