Why are Ant lib folders different - java

I am using Eclipse Helios with Tomcat 7 on Windows and have imported Apache Ant-1.8.4 and works fine but I had to set up the same environment on another machine and when I attempted to build the project using Ant in Eclipse it failed with the following message;
C:\eclipsehelios\workspace\projectname\build.xml:207: Problem: failed to
create task or type emmajava
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken
place
I have had this error before and just required to ensure the build file had the correct path to the Ant folder but this didn't resolve things this time. I found by copying in the following files to the Ant's lib folder solved the problem but these were not required in my own PC and wondered if someone would tell me if this was the correct way to resolve this problem and if so why do I not require these on my own PC?
antlr-2.7.6.jar
commons-beanutils-1.8.3-javadoc.jar
commons-beanutils-1.8.3-sources.jar
commons-beanutils-1.8.3.jar
commons-beanutils-bean-collections-1.8.3.jar
commons-beanutils-core-1.8.3.jar
commons-cli-1.2-javadoc.jar
commons-cli-1.2-sources.jar
commons-cli-1.2.jar
commons-logging.jar
ganymed.jar
guava-13.0.1-sources.jar.sav
guava-13.0.1.jar.sav
guava-gwt-13.0.1-sources.jar.sav
guava-r07-javadoc.jar.sav
guava-r07-sources.jar.sav
guava-r07.jar.sav
jna.jar
svnant-1.3.1.jar
svnant.jar
svnClientAdapter.jar
svnjavahl.jar
svnkit.jar
EDIT:
If I click on the line "C:\eclipsehelios\workspace\projectname\build.xml:207" it goes to the following section of the build file with the top line "
<emmajava enabled="${emma.enabled}" libclasspathref="emma.lib"
fullmetadata="yes" filter="${emma.filter}" sourcepath="src"
classname="the.company.domain.test.EmmaLoginMain">
<classpath>
<pathelement path="test" />
<pathelement path="build/classes" />
<pathelement path="build_tests/classes" />
<pathelement path="test" />
<fileset dir="${libDir}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${tomcat_lib}">
<include name="**/*.jar" />
</fileset>
<fileset dir="${test_lib}">
<include name="**/*.jar" />
</fileset>
</classpath>
<!-- regular <java> options are still available: -->
<!--<arg value="somearg" /> -->
<!-- <emmajava> option extensions [see the reference manual for
complete details]: -->
<xml outfile="${test.reports.dir}/emma/coverage.xml" />
<txt outfile="${test.reports.dir}/emma/coverage.txt" />
<html outfile="${test.reports.dir}/emma/coverage.html" />
</emmajava>

Related

Custom PMD rulset file on Jenkins Ant build not working

Here's how I am trying to load and reference the ruleset.xml file,
<property name="xms3k-build.pmd.rule.url" value="${xms3k-build.url}/${xms3k-build.version}/ruleset.xml" />
<property name="xms3k-build.pmd.rule.file" value="${xms3k-build.dir}/ruleset.xml" />
<!-- PMD static analysis task. -->
<target name="pmd" depends="compile, init-pmd">
<path id="pmd.aux.classpath">
<fileset dir="${lib.dir}/${ivy.conf.test}"/>
</path>
<pmd rulesetfiles="xms3k-build.pmd.rule.file" >
<formatter type="xml" toFile="pmd_report.xml" />
<fileset dir="${source.dir}">
<include name="**/*.java" />
</fileset>
<fileset dir="${source-test.dir}">
<include name="**/*.java" />
</fileset>
</pmd>
The following error occurred while executing this line:
common.xml:481: Can't find resource 'null' for rule 'xms3k-build.pmd.rule.file'.
Make sure the resource is a valid file or URL and is on the CLASSPATH. Here's the current classpath: /usr/share/java/ant.jar:/usr/share/java/ant-launcher.jar:/usr/share/java/jaxp_parser_impl.jar:/usr/share/java/xml-commons-apis.jar:/usr/share/java/junit.jar:/usr/share/java/ant/ant-junit.jar:/usr/share/java/junit.jar:/usr/share/java/ant/ant-junit4.jar:/usr/java/jdk1.7.0_45/lib/tools.jar:/usr/share/ant/lib/ant.jar:/usr/share/ant/lib/ant-launcher.jar:/usr/share/ant/lib/ant-junit4.jar:/usr/share/ant/lib/ant-bootstrap.jar:/usr/share/ant/lib/ant-junit.jar
I have tried many variants of the style.xml file. Here is what I am currently trying:
<?xml version="1.0"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>
This ruleset checks my code for bad stuff
</description>
<rule ref="rulesets/strings.xml"/>
</ruleset>
As adangel has posted in a comment the answer lied in a typo,
As "ms3k-build.pmd.rule.file" is a property, I'd try to use it like this: <pmd rulesetfiles="${xms3k-build.pmd.rule.file}" > – adangel

Issue while creating war using ant with Jenkins

I have a ant build script which creates a war file. The file content are as follows.
<?xml version="1.0" encoding="UTF-8"?>
<project name="TestProj" default="war" basedir=".">
<property name="project-name" value="${ant.project.name}" />
<property name="builder" value="IaasTeam" />
<property name="war-file-name" value="${project-name}.war" />
<property name="source-directory" value="src" />
<property name="classes-directory" value="build/classes" />
<property name="web-directory" value="WebContent" />
<property name="web-xml-file" value="WebContent/WEB-INF/web.xml" />
<property name="lib.dir" value="WebContent/WEB-INF/lib" />
<property name="catalina.home" value="../../outside/project/lib"/>
<tstamp prefix="build-info">
<format property="current-date" pattern="d-MMMM-yyyy" locale="en" />
<format property="current-time" pattern="hh:mm:ss a z" locale="en" />
</tstamp>
<property name="build-directory" value="build" />
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
<fileset dir="${catalina.home}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build/classes"/>
<javac includeantruntime="false" srcdir="src" destdir="build/classes" classpathref="classpath" />
</target>
<target name="war" depends="clean,compile">
<mkdir dir="${build-directory}" />
<delete file="${build-directory}/${war-file-name}" />
<war warfile="${build-directory}/${war-file-name}" webxml="${web-xml-file}">
<classes dir="${classes-directory}" />
<fileset dir="${web-directory}">
<!-- Need to exclude it since webxml is an attribute of the war tag above -->
<exclude name="WEB-INF/web.xml" />
</fileset>
<manifest>
<attribute name="Built-By" value="${builder}" />
<attribute name="Built-On" value="${build-info.current-date}" />
<attribute name="Built-At" value="${build-info.current-time}" />
</manifest>
</war>
</target>
I am using Jenkins as a build server (this is hosted on different machine kind of DEV environment).
I also use Gitlab as a repository and after pushing the latest code I have a hook for Jenkins job which gets triggered automatically and calls this build.xml.
Now the issues here is that when I run this script on my local machine everything works well but when Jenkins execute this it fails during the compilation phase giving me below error.
compile:
[mkdir] Created dir: /app/infra/jenkins/workspace/TestProj/build/classes
[javac] Compiling 49 source files to /app/infra/jenkins/workspace/TestProj/build/classes
BUILD FAILED
/app/infra/jenkins/workspace/TestProj/build.xml:27: /app/infra/jenkins/outside/project/lib does not exist.
The reason for this issue is the build server does not have any directoy called outside/project/lib.
The only reason of adding this directory in my build.xml is to have the container specific jar files ready for compiling.
How can I fix this issue?
Do I need to copy container specific jars on my build server? Or is there any way to tell Jenkins that not to copy this external jars but just use them for compilation.
Where would Jenkins find the jars? They need to be accessible otherwise your build will fail. If you don't want to have the files checked in (which is very sensible), you could use Apache Ivy to download them for you.
This is the most common way of handling the situation you're having. Using a dependency management framework like Ivy (or Maven, or similar) will save you a lot of headaches down the line. I recommend you have a look at their tutorial. After you set it up, your ant build will take care of downloading the files you need.

How can I change the name of the jar file after siging it - Apache ANT

I am signing my jars using following ant commands.
<signjar alias="${alias}" keypass="${keypass}"
storepass="${storepass}"
keystore="${keystorefile}"
signedjar="${dist.dir}/${jar.signed.fileName}"
lazy="true">
<fileset dir="${dist.dir}">
<include name="*.jar" />
<include name="lib/*.jar" />
</fileset>
</signjar>
For single file it is fine that I can change the name of the jars file after signing it,
but when I have multiple jars the above line is not useful, what i am trying to accomplish is ,
for example
If the unsigned jar file name is ab.jar after signing it I want to prependSigned_to it's name likeSigned_ab.jar` and so on for all the jars i have in my fileset.
Can anyone tell me how to do that ?
You can use the ant jar command/task like below in your build script :
<jar basedir="bin" destfile="Signed_${jar-name}.jar">
btw, you missed to type the command you're using, in your question.
The signjar task can take a mapper defining how to translate the input file name into an output file name:
<signjar alias="${alias}" keypass="${keypass}"
storepass="${storepass}"
keystore="${keystorefile}"
destdir="${dist.dir}"
lazy="true">
<fileset dir="${dist.dir}">
<include name="*.jar" />
<include name="lib/*.jar" />
<!-- since we're dumping signed JARs in the same dir as the source
ones, we need to prevent already-signed JARs from being signed
again. A better approach might be to put the Signed_* JARs in
a different directory -->
<exclude name="**/Signed_*" />
</fileset>
<regexpmapper handledirsep="yes"
from="^(.*?)/([^/]*)$$" to="\1/Signed_\2" />
</signjar>
May be you can write couple of macros & call 'signJarsParallel' macro once for every directory for which you want to sign jars.
This is not tested code. You can give it a try. It makes use running tasks parallely & hence increasing speed & signs to temporary-prefixed name you want :
<macrodef name="signMyJars">
<element name="myJar" implicit="true"/>
<sequential>
<signjar alias="${alias}" keypass="${keypass}"
storepass="${storepass}"
keystore="${keystorefile}"
lazy="true">
<myJar/>
</signjar>
</sequential>
</macrodef>
Call only below macro inside your ant target.
<macrodef name="signJarsParallel">
<attribute name="dirName"/>
<sequential>
<for param="file" parallel="true" threadCount="5">
<path>
<fileset dir="#{dirName}">
<include name="*.jar"/>
<include name="lib/*.jar"/>
</fileset>
</path>
<signMyJars>
<fileset file="Signed_#{file}.jar"/>
</signMyJars>
</for>
</sequential>
</macrodef>

Setting javaagent in ant

I am trying to run JUnit tests from an Ant script. The tests use the JMockit mocking framework, which for Java 5 requires specifying it as a javaagent to run correctly. Here is the script I am running:
<!DOCTYPE project>
<project name="junit_test">
<property name="PROJECT_PATH" value="{Path to my eclipse project}" />
<property name="LIB_PATH" value="${PROJECT_PATH}/WebContent/WEB-INF/lib" />
<property name="TEST_PATH" value="WebContent/WEB-INF/classes" />
<target name="run_junit">
<junit fork="yes" forkmode="once" printsummary="true">
<jvmarg value="-javaagent:${LIB_PATH}/jmockit.jar" />
<classpath path="${LIB_PATH}/jmockit.jar" />
<classpath path="${LIB_PATH}/junit-4.8.2.jar" />
<batchtest>
<fileset dir="${TEST_PATH}">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
</junit>
<junitreport todir="/junitOut">
<fileset dir="/junitOut">
<include name="INCOMPLETE-*.xml"/>
<include name="TEST-*.xml"/>
</fileset>
<report todir="/junitOut/html"/>
</junitreport>
</target>
</project>
I have a feeling that I'm not setting the javaagent correctly. The tests error with this exception:
java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance(Constructor.java:515)
at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
Caused by: java.lang.RuntimeException: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
at mockit.internal.startup.JDK6AgentLoader.attachToThisVM(JDK6AgentLoader.java:113)
at mockit.internal.startup.JDK6AgentLoader.loadAgent(JDK6AgentLoader.java:77)
at mockit.internal.startup.AgentInitialization.initializeAccordingToJDKVersion(AgentInitialization.java:41)
at mockit.internal.startup.Startup.initializeIfNeeded(Startup.java:203)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:167)
Caused by: com.sun.tools.attach.AttachNotSupportedException: Unable to enqueue operation: the target VM does not support attach mechanism
at sun.tools.attach.WindowsVirtualMachine.(WindowsVirtualMachine.java:58)
at sun.tools.attach.WindowsAttachProvider.attachVirtualMachine(WindowsAttachProvider.java:58)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
at mockit.internal.startup.JDK6AgentLoader.attachToThisVM(JDK6AgentLoader.java:110)
Is my javaagent setting correct? If it is, what else could be causing this error?
I don't know if that's the solution, but you are not setting the classpath correctly. Try this:
<classpath>
<pathelement location="${LIB_PATH}/jmockit.jar" />
<pathelement location="${LIB_PATH}/junit-4.8.2.jar" />
</classpath>
Your jvmarg to Ant for javaagent looks correct. Are you using Java 6 or a JVM that otherwise supports the Attach API? It looks like you have to also pass -Dcom.sun.management.jmxremote to enable it for older versions of Java. I'm assuming you need it because the exception says "the target VM does not support attach mechanism".
For IBM JDK 6 it appears you need to specify -Dcom.ibm.tools.attach.enable=yes.

Make Ant use a different build class in different situations?

We use Ant to build a Java web application. The application will compile and run on both Tomcat 6 and Tomcat 5.5. However, the build process is slightly different depending on which version of Tomcat you have installed: 5.5 keeps jar files that the build needs in $CATALINA_HOME/common/lib and $CATALINA_HOME/server/lib, while 6.0 keeps them all in $CATALINA_HOME/lib.
How can I set up Ant to choose the correct classpath(s) depending on a setting in build.properties? I'd be ok with even having to list the directories to be included in the classpath in a setting in build.properties, but I haven't been able to make this work.
Any suggestions?
Create 2 different path items:
<path id="path.tomcat55">
<fileset ... (tomcat5.5 files) />
</path>
<path id="path.tomcat6">
<fileset ... (tomcat6 files) />
</path>
Then create separate targets for building for 55, using the tomcat55 path and another for building 6 using tomcat6.
<target name="compile.tomcat55" depends="build">
<echo message="Compiling for Tomcat 5.5" />
<javac srcdir="${project.basedir}/src/test" destdir="${build.dir}" fork="true" source="1.5" classpathref="path.tomcat55" />
</target>
<target name="compile.tomcat6" depends="build">
<echo message="Compiling for Tomcat 6" />
<javac srcdir="${project.basedir}/src/test" destdir="${build.dir}" fork="true" source="1.5" classpathref="path.tomcat6" />
</target>
Then, just call the appropriate target.
Because the directory structure is mutually exclusive for Tomcat 5.5 and Tomcat 6.0, you may be able to specify all 3 of them and then ant will pick up only what's available:
<classpath>
<fileset dir="${catalina.home}/lib"
erroronmissingdir="false"
>
<include name="**/*.jar"/>
</fileset>
<fileset dir="${catalina.home}/common/lib"
erroronmissingdir="false"
>
<include name="**/*.jar"/>
</fileset>
<fileset dir="${catalina.home}/server/lib"
erroronmissingdir="false"
>
<include name="**/*.jar"/>
</fileset>
</classpath>
Specify erroronmissingdir="false", so ant does not complain about missing directories.
I would go the a simpler solution. Just add the 3 directories in the build path. Ant/javac should ignore if a classpath element is not found.

Categories