ant + javac + properties - ant

In an ant script, I would like to compile only certain packages e.g.
com.example.some_package.foo
com.example.some_package.bar
This is what I want to do, but it doesn't seem to work, because property substitution doesn't seem to work in the <include> tag:
<property name="ROOT_PKG_PATH" location="com/example/some_package"/>
...
<target name="compile-client" depends="init">
<javac srcdir="${srcDir}"
destdir="${buildDir}"
debug="on"
target="1.5"
classpathref="build.classpath">
<include name="${ROOT_PKG_PATH}/foo/**" />
<include name="${ROOT_PKG_PATH}/bar/**" />
</javac>
</target>
How can I get around this without having to retype the entire package path of each package?

Use the value attribute on the property, instead of location:
<property name="ROOT_PKG_PATH" value="com/example/some_package"/>
Example
I'm able to conditionally compile one of my java classes:
./src/some_package/demo1/Demo.java
./src/some_package/demo2/Demo.java
./build/classes/somepackage/demo1/Demo.class
./build.xml
Using the following ANT file:
<project name="demo" default="compile">
<property name="prop" value="some_package/demo1"/>
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes">
<include name="${prop}/**"/>
</javac>
</target>
</project>

Related

Continuous Integration - Jenkins not invoking WedDriver test

I'm trying to use jenkins to run selenium webdriver test (continuous integration) but so far I've had no success at all. My setup:
- eclipse
- testng
- ant (build.xml files)
- jenkins
- everything is hosted locally
I'm running my test in parallel (1 test, 3 browsers) and this works fine if I run the testng file, if I run the ant file (build.xml) it says 'build successful' but nothing happens if also run this same file in jenkins it says the same thing 'build successful' but again nothing happens. From this I can deduce that jenkins is running the correct file but its just not executing the test. I've even tried to use maven but I don't understand it so the code doesn't even compile when I take this route.
Can someone help me and point me in the right direction because I believe I'm missing something. I've included a photo of my jenkins set and below is a copy of my ant file:
![<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. --><project basedir="." default="build" name="jenkins_run_selenium">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../Program Files (x86)/eclipse-standard-kepler-R-win32-x86_64/Eclipse"/>
<property name="junit.output.dir" value="junit"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.7"/>
<property name="source" value="1.7"/>
<path id="jenkins_run_selenium.classpath">
<pathelement location="bin"/>
<pathelement location="../../../Program Files (x86)/Eclipse/selenium-2.40.0/selenium-java-2.40.0-srcs.jar"/>
<pathelement location="../../../Program Files (x86)/Eclipse/selenium-2.40.0/selenium-server-standalone-2.40.0.jar"/>
<pathelement location="../Desktop/Jar Files and Sources/testng-6.8.5-javadoc.jar"/>
<pathelement location="../Desktop/Jar Files and Sources/testng-6.8.jar"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.launch"/>
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="jenkins_run_selenium.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
<target name="jenkins_run_selenium">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<classpath refid="jenkins_run_selenium.classpath"/>
</junit>
</target>
<target name="junitreport">
<junitreport todir="${junit.output.dir}">
<fileset dir="${junit.output.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${junit.output.dir}"/>
</junitreport>
</target>
</project>][1]
I can explain you the way I have done it in jenkins, maven and code. It should be pretty much similar with ant. This should certainly make jenkins fire your tests.
In code:
Create test suite class like below
#RunWith(Suite.class)
#Suite.SuiteClasses
({
Test1.class,
Test2.class
})
public class UnitTestSuite{}
In maven: use maven-surefire-plugin in pom.xml as below:
<!-- TEST -->
<plugin>
<!-- Runs the unit tests. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire.version}</version>
<configuration>
<includes>
<include>**/UnitTestSuite.java</include>
</includes>
</configuration>
</plugin>
and finally in jenkins build section set goals as
clean install -e -Dmaven.test.failure.ignore=false
Try modifying your ant file by adding in target "jenkins_run_selenium" as below:
<target name="jenkins_run_selenium">
<mkdir dir="${junit.output.dir}"/>
<junit fork="yes" printsummary="withOutAndErr">
<formatter type="xml"/>
<test name="tests.MyUnitTests" todir="${junit.output.dir}"/>
<classpath refid="jenkins_run_selenium.classpath"/>
</junit>
</target>
Refer https://stackoverflow.com/a/4760714/1712272 if you want to run all tests in batch

ant multiple source directories with copied resources

Consider minimal build.xml fragment which builds jar from sources and includes all non-java resources:
<property name="src.dir" value="src" />
<target name="build">
<javac destdir="bin">
<src path="${src.dir}" />
</javac>
<copy includeemptydirs="false" todir="bin">
<fileset dir="${src.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
<jar destfile="dist/foo.jar" basedir="bin"/>
</target>
Now imagine that I need to support a list of source directories:
<property name="src.dirs" value="src;src-gen" />
How can i modify above script to make it happen ?
javac will happily take list of directories but for copy I need to transform string into list of filesets with exclusions or find some other way.
Normally, you simply list them all together:
<javac destdir="bin">
<src path="${src.dir}"/>
<src path="${src2.dir}"/>
<src path="${src3.dir}"/>
</javac>
You can try the <sourcepath/> attribute. I've never used it, but I believe you can use it to define a path of various source files, and use that:
<path id="source.path">
<pathelement path="${src.dir}"/>
<pathelement path="${src2.dir}"/>
<pathelement path="${src4.dir}"/>
</path>
<javac destdir="bin">
srcpathref="source.path"/>
The first will work, but not 100% sure about the second.
I'm not sure of a way to do it with built-in Ant tasks but you could use an ant-contrib <for> task
<path id="src.path">
<pathelement location="src" />
<pathelement location="src-gen" />
</path>
<target name="build">
<javac destdir="bin">
<src refid="src.path" />
</javac>
<for param="dir">
<path refid="src.path" />
<sequential>
<copy includeemptydirs="false" todir="bin">
<fileset dir="#{dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
</sequential>
</for>
<jar destfile="dist/foo.jar" basedir="bin"/>
</target>
The simple solution is to just specify multiple filesets, in the same manner as the javac task supports multiple "src" attributes:
<target name="build" depends="init" description="Create the package">
<javac destdir="${classes.dir}" includeantruntime="false">
<src path="src/main1/java"/>
<src path="src/main2/java"/>
</javac>
<copy todir="${classes.dir}" includeemptydirs="false">
<fileset dir="src/main1" excludes="**/*.java"/>
<fileset dir="src/main2" excludes="**/*.java"/>
<flattenmapper/>
</copy>
</target>
This of course assumes that the number of source code locations is fixed, which is not unreasonable to expect.
If you want to drive this using a list property you must resort to embedding a script within your build to process this list (I can't endorse ant-contrib):
<project name="demo" default="build">
<property name="src.dirs" value="src/main1,src/main2"/>
<property name="build.dir" location="build"/>
<property name="classes.dir" location="${build.dir}/classes"/>
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.6/groovy-all-2.1.6.jar"/>
</target>
<target name="init">
<mkdir dir="${classes.dir}"/>
</target>
<target name="build" depends="init" description="Create the package">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
def srcDirs = properties["src.dirs"].split(",")
ant.javac(destdir:properties["classes.dir"], includeantruntime:false) {
srcDirs.each {
src(path:"${it}/java")
}
}
ant.copy(todir:properties["classes.dir"], includeemptydirs:false) {
srcDirs.each {
fileset(dir:it, excludes:"**/*.java")
}
flattenmapper()
}
</groovy>
</target>
<target name="clean" description="Cleanup build dirs">
<delete dir="${build.dir}"/>
</target>
</project>
Notes:
Compare the "build" targets. You'll notice that the groovy solution calls ANT in the same manner. This is why I really like groovy's integration with ANT.
Example also includes a "bootstrap" target to download the groovy jar dependency from Maven Central. You could alternatively use ivy to manage your build's dependencies.
A simple solution without ant-contrib tasks or embedded scripts:
<property name="src.dirs" value="src,src-gen" />
<path id="src.path">
<multirootfileset type="dir" basedirs="${src.dirs}"/>
</path>
<target name="build">
<javac destdir="bin">
<src refid="src.path"/>
</javac>
<copy todir="bin">
<multirootfileset type="file" basedirs="${src.dirs}">
<exclude name="**/*.java"/>
</multirootfileset>
</copy>
<jar destfile="dist/foo.jar" basedir="bin"/>
</target>
multirootfileset to the rescue! ;-) Needs Ant 1.9.4 or higher.

Ant With Internal Dependencies

I have a a jar right now that uses external dependencies. I'm trying to create a jar that packages all the external dependencies inside, and will just give me one jar. I saw this question asked multiple times, but I still can't figure it out. I'm using Ant, and copied some of the examples I saw on here. I'm using zipgroupfileset to reference the external(now internal) jars. As soon as I added the zipgroupfileset I got a runtime error that said my Runner class could not be found.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. -->
<project basedir="." default="build" name="ExcelDemo">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../../Program Files (x86)/eclipse"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<property name="external-lib-dir" value="lib\poi-3.9" />
<property name="external-lib-dir2" value="lib\poi-3.9\lib" />
<property name="external-lib-dir3" value="lib\poi-3.9\ooxml-lib" />
<path id="ExcelDemo.classpath">
<pathelement location="bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src" excludes="**/*.launch, **/*.java"/>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="ExcelDemo.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects">
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="clean"/>
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="build">
<propertyset>
<propertyref name="build.compiler"/>
</propertyset>
</ant>
</target>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
<target name="RunnerClass">
<java classname="runner.RunnerClass" failonerror="true" fork="yes">
<classpath refid="ExcelDemo.classpath"/>
</java>
</target>
<target name="jar" description="Create a jar for this project">
<manifestclasspath property="lib.list" jarfile="Test.jar">
<classpath refid="ExcelDemo.classpath" />
</manifestclasspath>
<jar jarfile="Test.jar" includes="*.class" basedir="bin">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir2}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir3}" includes="*.jar"/>
<manifest>
<attribute name="Class-Path" value="${lib.list}" />
<attribute name="Main-Class" value="runner.RunnerClass" />
</manifest>
</jar>
</target>
</project>
To make things simpler:
Create a separate sources jar for compilation. Then, have a separate compiled jar without the sources.
Don't include the third party jars. Instead, use Ivy with Ant. Ant will automatically download the required jars. In fact, I've see sources that just include the ivy.jar, so Ivy will automatically be configured when you unjar the sources. You type in ant, and everything just builds.
As an alternative, you can look at Maven which is how many projects are now packaged. In fact, if your jar is an open source project, you can probably host it on the OSS Maven repository. This way, no one even needs to manually download your compiled jar. If they want it, they configure their Maven project to do it for them.
i think the problem is that you use basedir="bin" in the your jar task. then path of your zipgroupfileset convert to bin/${external-lib-dir}

ANT Generated jar: is it a namespace issue?

I have a Eclipse-Java-Project with an ANT-build-file. This build file exports a jar of the project without compiling it. So I only export the sources.
<target name="jar">
<mkdir dir="/jar"/>
<jar destfile="/jar/my_test_jarfile.jar" basedir="/src" />
</target>
I use this generated jar in another eclipse java project and set the path to the jar in the build-path-settings of the project. The problem is that eclipse says it cannot resolve the namespace of the imported classes of the jar.
If I export the jar manually by right clicking on the project and then "Export" and putting the jar to the build path of the other project, everything works fine and there are no errors. So the question is now, what am I doing wrong?
So here is my solution. It seems that you have to compile the source first and then pack it into a jar. I don't give a guarantee that this jar is exactly the same like the one you get from eclipse when you do the right click thing and export etc.
But it works for me, there are no namespace errors any longer. so here is a minimum version of my ant targets:
<project default="run" basedir=".">
<property name="src.dir" value="src" />
<property name="classes.dir" value="bin" />
<property name="build.dir" value="build" />
<path id="libs">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement path="${basedir}\${classes.dir}"/>
</path>
<target name="run">
<antcall target="compile"/>
<antcall target="jar"/>
</target>
<target name="compile">
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="libs" encoding="UTF-8" />
</target>
<target name="jar">
<jar destfile="${build.dir}/my_jar_file.jar" basedir="${classes.dir}">
</target>
</project>

How to compile a .drl file through an ant build script

I am new to Drools. I want to know if it is possible to compile a .drl file using some kind of a command that can be entered in the windows command line (shell/cmd). I looked through the binaries that come with the drools distribution but I am unable to figure out a way to compile a .drl file.
The reason I am interested in such a command is that I want to write an ant build file which will compile my java classes and rules and create a jar. This jar should be self sufficient, i.e running the jar from the command line should run the main program, which passes facts in the session causing the rules that operate on these facts to automatically be executed.
The DroolsCompilerAntTask used to be the way to do this. It would take all your various rule files and compile them into a serialized file. It appears to have some bugs in 5.3 though which I am currently trying to work out. In the meantime, here is an illustrative build file that can be used for creating an executable JAR based on Drools. The build will fail if the rules cannot be compiled.
<project name="DroolsProto" default="dist" basedir=".">
<property name="build.src" location="src"/>
<property name="build.target" location="target"/>
<property name="build.dist" location="dist"/>
<property name="build.artifact" value="droolsproto"/>
<property name="one-jar.dist.dir" value="~/Work/Data/Misc/OneJar"/>
<property name="one-jar.version" value="0.97"/>
<property name="one-jar.ant.jar" value="${one-jar.dist.dir}/one-jar-ant-task-${one-jar.version}.jar"/>
<path id="build.lib.path">
<fileset dir="${build.src}/lib">
<include name="**/*.jar"/>
</fileset>
</path>
<taskdef name="one-jar" classname="com.simontuffs.onejar.ant.OneJarTask"
classpath="${one-jar.ant.jar}" onerror="report"/>
<taskdef name="droolscompiler" classname="org.drools.contrib.DroolsCompilerAntTask">
<classpath refid="build.lib.path"/>
</taskdef>
<target name="clean">
<delete dir="${build.target}"/>
<delete dir="${build.dist}"/>
</target>
<target name="init">
<tstamp/>
<mkdir dir="${build.target}"/>
<mkdir dir="${build.dist}"/>
</target>
<target name="compile" depends="init">
<mkdir dir="${build.target}/classes"/>
<javac srcdir="${build.src}/main/java" destdir="${build.target}/classes">
<classpath refid="build.lib.path"/>
<include name="**/*.java"/>
<exclude name="**/*Test.java"/>
</javac>
</target>
<target name="verify-rules">
<droolscompiler srcDir="${build.src}/main/resources" toFile="${build.target}/classes/foo.foo">
<classpath refid="build.lib.path"/>
</droolscompiler>
</target>
<target name="verify-resources" depends="verify-rules"/>
<target name="bundle-resources" depends="verify-resources">
<copy todir="${build.target}/classes">
<fileset dir="${build.src}/main/resources"/>
</copy>
</target>
<target name="dist" depends="compile, bundle-resources">
<one-jar destfile="${build.dist}/${build.artifact}.jar">
<manifest>
<attribute name="One-Jar-Main-Class" value="org.drools.examples.HelloWorldExample"/>
</manifest>
<main>
<fileset dir="${build.target}/classes"/>
</main>
<lib>
<fileset dir="${build.src}/lib">
<include name="**/*.jar"/>
</fileset>
</lib>
</one-jar>
</target>
</project>
Note that the build uses One-Jar in order to create the self-contained executable, you may wish to substitute this with your 'Super Jar™' tool of choice. There is also a DroolsVerifierAntTask which allegedly can check logical errors in your rules (as opposed to syntactical ones), but I have no hands on experience with it.
You can use something like this:
private static void compile(final String srcFile, final String destFile) throws IOException {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
URL src = FormChecker.class.getResource(srcFile);
Resource r = ResourceFactory.newInputStreamResource(src.openStream());
kbuilder.add(r, ResourceType.DRL);
if (kbuilder.hasErrors()) {
throw new IllegalStateException("Can not initialize Drools: " + kbuilder.getErrors().toString());
}
Collection<KnowledgePackage> kpackages = kbuilder.getKnowledgePackages();
File dest = new File(destFile);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(dest));
out.writeObject(kpackages);
out.close();
}
There's a drools-ant jar in the droolsjbpm-tools zip.

Resources