ANT war task fails with strange error message - ant

I am trying to create a war file out of an eclipse project using ant
The responsible ant target looks like this
<target name="jar" depends="build" description="Erzeugt das WAR File">
<war destfile="${project.dir.dist}/xyz.jar" webxml="${basedir}/WebRoot/WEB-INF/web.xml" duplicate="fail" basedir="${basedir}">
<lib dir="${project.dir.dist}" excludesfile="${project.dir.dist}/xyz.jar" />
<classes dir="${project.dir.bin}" />
<webinf dir="${basedir}/WebRoot/WEB-INF" excludes="*.class" />
<metainf dir="${basedir}/WebRoot/META-INF" />
</war>
</target>
And it fails with the following error:
F:\eclipse_workspaces\skyeye\railWeb\build.xml:35: Syntax error in property: ??? ???i8?
Google search turned up only this: http://209.85.135.132/search?q=cache:OrmNOY9EJd0J:teamcity.jetbrains.com/viewLog.html%3Bjsessionid%3D114D52086BAE423B2F69A99B4CFACACD%3FbuildId%3D29573%26tab%3DbuildChangesDiv%26buildTypeId%3Dbt134+ant+war+task+%22Syntax+error+in+property%22&cd=1&hl=en&ct=clnk&client=firefox-a
Can anybody explain, what the heck is going on?

The propblem was that I used 'excludesFile' assuming it would exclude a single file. Instead ANT tried to parse it as an property file which gets difficult since it actually was a jar file.

The correct way to exclude a jar file is given in the documentation. If anyone face same issue, they can refer to this link.
This example is taken from the documentation, here we are removing jdbc1.jar from lib
Assume the following structure in the project's base directory:
thirdparty/libs/jdbc1.jar
thirdparty/libs/jdbc2.jar
build/main/com/myco/myapp/Servlet.class
src/metadata/myapp.xml
src/html/myapp/index.html
src/jsp/myapp/front.jsp
src/graphics/images/gifs/small/logo.gif
src/graphics/images/gifs/large/logo.gif
then the war file myapp.war created with
<war destfile="myapp.war" webxml="src/metadata/myapp.xml">
<fileset dir="src/html/myapp"/>
<fileset dir="src/jsp/myapp"/>
<lib dir="thirdparty/libs">
<exclude name="jdbc1.jar"/>
</lib>
<classes dir="build/main"/>
<zipfileset dir="src/graphics/images/gifs"
prefix="images"/>
</war>
will consist of
WEB-INF/web.xml
WEB-INF/lib/jdbc2.jar
WEB-INF/classes/com/myco/myapp/Servlet.class
META-INF/MANIFEST.MF
index.html
front.jsp
images/small/logo.gif
images/large/logo.gif

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.

How to Setup an ANT file to create a JAVA JAR that is containing/packaging this calculator?

I already made a running program which is calculator in IntelliJ IDEA and make a test and it goes fine. My problem is that how to setup an ANT file to create a JAVA JAR that is calculator.
Hoping for your answers..
tnx.
This is an example of an ant target that does jar creation.
<!-- roll up everyting into a single jar file -->
<target name="dist" depends="clean, compile" description="Generate the distribution file.">
<!--
Copy the library .jars to the directory where the distribution will be located
-->
<copy todir="${dist}">
<fileset dir="${lib}"/>
</copy>
<!-- TODO: Generate the MANIFEST.MF file on the fly -->
<jar jarfile="${dist}/myCalculator.jar" basedir="${build}" manifest="tools/MANIFEST.MF"/>
<!-- dump to web server -->
<copy todir="${web-files}">
<fileset dir="${dist}"/>
</copy>
</target>
Take a look at the Ant manual page for the Jar task. There are lots of examples there.

Creating an ear-File with ant

I am new to ant i referred many sites , i need to build.xml for my project which consists
of two modules i have application.xml file which represents corresponding war file
so my question is it sufficient to add the application.xml file
<ear destfile="${dist.dir}/${ant.project.name}.ear" appxml="${conf.dir}/application.xml">
<metainf dir="${build.dir}/META-INF"/>
<fileset dir="${dist.dir}" includes="*.jar,*.war"/>
</ear>
whether this will refer the corresponding war files or i need to compile the whole scenario please let me know. how solve this.
I'm not 100% sure what you're asking.
In order to use the <ear> task, you already need to have compiled the required jars and wars.
If those jars and wars have already been built, you simply refer to them in your <ear> task as you did in your example. The application.xml must already exist before you build your ear. The application.xml doesn't build the jars and wars, you have to do that.
If you haven't already built the wars and jars, you need to do that first. A general outline of a build.xml looks something like this:
<project name="foo" basedir="." default="package">
<!-- Some standard properties you've defined -->
<property name="target.dir" value="${basedir}/target"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<property name="xxx" value="yyy"/>
<!-- Compile properties that allow overrides -->
<property name="javac.nowarn" value="false"/>
<property name="javac.listfiles" value="false"/>
<property name="javac.srcdir" value="source"/>
<property name="javac.distdir" value="${target.dir}/classes"/>
<target name="clean"
description="cleans everything nice and shiny">
<delete dir="${target.dir}"/>
</target>
<target name="compile"
description="Compiles everything">
<mkdir dir="${javac.distdir}"/>
<javac srcdir="${javac.srcdir}"
destdir="${javac.destdir}"
[...]
[...]/>
</target>
<target name="package.jar"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package.jar2"
depends="compile"
description="Package jarfile">
<jar destfile="${target.dir}/jarname2.jar"
[...]
[...]/>
</target>
<target name="package.war"
depends="compile"
description="Package jarfile">
<war destfile="${target.dir}/jarname.jar"
[...]
[...]/>
</target>
<target name="package"
depends="package.jar"
description="Make the ear">
<ear destfile="${target.dir}/earfile.ear"
[...]/>
</target>
</project>
Basically, it consists of a bunch of targets and each target does one task. You can have targets depend upon other targets. For example, this particular build.xml will automatically run the package task. The package task depends upon the package.jar task which depends upon the compile task. Thus, the build.xml file will first call compile, then package.jar, then package.
The important thing to remember is that you don't specify the order of the events. You let Ant figure that out, and you let Ant figure out what you need to do. Let's say you've modified a java source file. Ant knows that it has to recompile only that one file. It also knows that it might have to rebuild the jarfile that contains that classfile. And, it then knows it has to rebuild the ear. Most tasks can figure it out on their own, and you don't do a clean for each build. (You notice that the clean target isn't called by package or compile. You have to call it manually).
The only other thing I recommend is that you try to keep your work area clean. Any files you create should be put into the ${target.dir} directory. That way, when you do a clean, you only have to delete that one directory.
I hope this answer your question.

Resources