My Ant code
<?xml version="1.0" encoding="UTF-8"?>
<project default="plugin_export" name="build">
<target name="plugin_export">
<pde.exportPlugins destination="C:\" exportSource="false" exportType="directory" plugins="MyPlugin" useJARFormat="true" allowbinarycycles="true" filename="MyPlugin.jar" qualifier="X" />
<waitfor maxwait="15" maxwaitunit="minute">
<copy todir="j:\eclipse-rcp-juno-SR1-win32\dropins\">
<fileset dir="c:\plugins\">
<include name="*" />
</fileset>
</copy>
</waitfor>
</target>
</project>
it doesn't work, because I get
windows_build.xml:8: waitfor doesn't support the nested "copy" element.
pde.exportPlugins part is auto-generated by eclipse and it runs background process that creates jar with a plugin.
I would like to copy that plugin into 3 instances of eclpse I do use and put it in the dropins folder.
How to do it ?
To get things done after your build has finished, you may use a buildlistener.Kev Jackson implemented a very useful exec-listener in his presentation =http://people.apache.org/~kevj/ossummit/extending-ant.html (sources are included in the presentation).
For each build result ( BUILD SUCCESSFUL | BUILD FAILED ) it provides a taskcontainer
you can put all your stuff in that should run AFTER Build has finished :
<exec-listener onSuccess="true">
<echo>Executing after BUILD SUCCESSFUL...</echo>
<exec executable="..">
<arg value="..."/>
</exec>
<mail ... />
..other tasks
</exec-listener>
<exec-listener onSuccess="false">
<echo>Executing after BUILD FAILED...</echo>
<exec executable="..">
<arg value="..."/>
</exec>
<mail ... />
..other tasks
</exec-listener>
Related
Say I have a library and a binary target, let's call them MyLib and MyBin,
MyBin depends on MyLib.
I'm trying to create an Ant buildfile for MyBin that first builds MyLib and then includes it in the classpath when building MyBin.
I've tried using Ant tasks as in Building other, dependent projects with Ant .
However, it's not working, and from ant -v I think the MyBin build-deps target is not even building MyLib. Seems like it's confusing MyBin and MyLib properties? I'm not sure how to prevent this though.
I'm dumping only MyBin/build.xml below, but the MyLib is almost identical, except it does not have the build-deps target.
<project name="MyBin" default="main" basedir=".">
<property name="projectName" value="MyBin" />
<property name="src.dir" location="src" />
<property name="build.dir" location="bin" />
<property name="dist.dir" location="dist" />
<property name="dist.lib.dir" location="dist/lib" />
<property name="lib.dir" value="lib" />
<target name="build-deps" depends="init">
<!-- MyLib main target does clean -> build -> jar to dist folder -->
<!-- Its build.xml uses many of the same property values as above -->
<ant antfile="../MyLib/build.xml" target="main"/>
</target>
<path id="classpath">
<fileset dir="${basedir}/">
<include name="../MyLib/dist/**/*.jar" />
</fileset>
</path>
<!-- Need classpath to run this -->
<target name="compile" depends="build-deps" description="compile the source ">
<javac includeantruntime="false" srcdir="${src.dir}"
destdir="${build.dir}" classpathref="classpath" />
</target>
<!-- Group all dependencies into a big dependency-all.jar -->
<target name="copy-dependencies">
<mkdir dir="${dist.lib.dir}" />
<jar jarfile="${dist.lib.dir}/dependencies-all.jar">
<zipgroupfileset dir="${lib.dir}">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
</target>
<!-- jar it, extract above dependency-all.jar and zip it with project files -->
<target name="jar" depends="compile, copy-dependencies"
description="package, output to JAR">
<mkdir dir="${dist.dir}" />
<mkdir dir="${dist.lib.dir}" />
<jar jarfile="${dist.dir}/${projectName}.jar" basedir="${build.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}" />
</manifest>
<zipfileset src="${dist.lib.dir}/dependencies-all.jar"
excludes="META-INF/*.SF" />
</jar>
</target>
<target name="clean" description="clean up">
<delete dir="${build.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- Default, run this -->
<target name="main" depends="clean, compile, jar" />
</project>
What I see with ant -v in MyBin is something along the lines of:
build-deps:
Project base dir set to: /MyBin
[ant] calling target(s) [main] in build file /MyLib/build.xml
parsing buildfile /MyLib/build.xml with URI = file:/MyLib/build.xml
Project base dir set to: /MyBin
Override ignored for property "projectName"
Override ignored for property "build.dir"
Override ignored for property "dist.dir"
Override ignored for property "dist.lib.dir"
Override ignored for property "lib.dir"
[pathconvert] Set property classpath.name =
[ant] Entering /MyLib/build.xml...
Build sequence for target(s) `main' is [clean, init, copy-dependencies, jar, main]
Complete build sequence is [clean, init, copy-dependencies, jar, main, ]
clean:
[delete] Deleting directory /MyBin/bin
[delete] Deleting directory /MyBin/bin
init:
[mkdir] Created dir: /MyBin/bin
copy-dependencies:
[ant] Exiting /MyLib/build.xml.
On your specific question:
seems like it's confusing MyBin and MyLib properties? I'm not sure how
to prevent this though.
You are using this to invoke the MyLib build:
<ant antfile="../MyLib/build.xml" target="main" />
A build invoked via the <ant> task this way by default inherits all properties from the caller, including basedir, hence the build is run in the wrong place.
Instead you could use, for example:
<ant dir="../MyLib" />
That will run build.xml in the specified directory, set the basedir property, and call the default target, which should be main if you are using a very similar buildfile for the library as you say. If you don't want to inherit properties from MyBin when executing the MyLib task, specify inheritAll=false in the task.
From the <ant> task docs for the dir attribute:
the directory to use as a basedir for the new Ant project (unless
useNativeBasedir is set to true). Defaults to the current project's
basedir, unless inheritall has been set to false, in which case it
doesn't have a default value. This will override the basedir setting
of the called project. Also serves as the directory to resolve the
antfile and output attribute's values (if any).
I am creating a java agent that will be used to to do some bytecode modification to some classes org.eclipse.jdt.core.JDTCompilerAdapter is one of them. I am using javassit to modify some the execute() method of org.eclipse.jdt.core.JDTCompilerAdapter. So I have included ecj as in my agent project (using gradle)
compile group: 'org.eclipse.jdt.core.compiler' ,name: 'ecj', version :'4.3.1'
As I need to use some classes from ecj.
The goal of the agent is to intercept the calls to execute method, modify the execute method to add some calls to some of my classes in the aim of triggering some processing.
I am testing the agent against a Simple java project with 2 classes. the project is builded with ant and uses JDTCompilerAdapter as a compiler.
Here is the build.xml file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="build" name="TestProject">
<property file="build.properties" />
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.7"/>
<property name="source" value="1.7"/>
<path id="PClasspath">
<pathelement location="bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="init" name="build">
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" includeantruntime="false" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="PClasspath"/>
</javac>
</target>
<!--
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_JDT_CORE}" includes="*.jar"/>
</copy>
</target>-->
<target name="build-e" >
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
The agent is to be used when building a project.
So for testing the agent I use this command:
java -jar agent-wrapper.jar --outdir ./out --exec ./build_wrapper.sh
build_wrapper.sh contains this (I have added ecj dependency so I could compile the project with JDTCompilerAdapter as I have in bulid.xml <property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/> :
../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e
The idea is that the agent-wrapper will parse the argument (outdir is used to generate some stuff and exec is a script used to launch a the build of my test project) get the command to be executed from build_wrapper.sh (in this case ../ant/bin/ant -lib ../eclipse/plugins/ecj-4.3.1.jar build-e) and add it self as java agent to the command.
The problem occurs during the execution of the agent. Here is the output:
java -jar custom-agent.jar --outdir ./out --exec ./build_wrapper.sh [10:18:53]
Picked up JAVA_TOOL_OPTIONS: -javaagent:/Users/dev/TestAgent/project/custom-agent.jar=OUTDIR=/Users/dev/TestAgent/project/./out
objc[30474]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/bin/java and /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/libinstrument.dylib. One of the two will be used. Which one is undefined.
Buildfile: /Users/dev/TestAgent/project/build.xml
build-e:
init:
[mkdir] Created dir: /Users/dev/TestAgent/project/bin
build:
BUILD FAILED
/Users/dev/TestAgent/project/build.xml:47: The following error occurred while executing this line:
/Users/dev/TestAgent/project/build.xml:32: Class org.eclipse.jdt.core.JDTCompilerAdapter could not be loaded because of an invalid dependency.
Total time: 2 seconds
abnormal termination, exit code: 1
When I don't use ecj-4.3.1.jar inside my agent project, the build runs well I intercept the call to execute() method but I can't use the other classes from ecj jar.
The show stopper error is "Class org.eclipse.jdt.core.JDTCompilerAdapter could not be loaded because of an invalid dependency."
First hint at the fault might be found from reading this link
http://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftask-ant_javac_adapter.htm
The second hint might be that one of the jars required for running the JDTCompilerAdapter is missing.
To get the JDTCompilerAdapter to work I copied both the JDTCompilerAdapter.jar and org.eclipse.jdt.core.jar into the ant/lib folder.
There are differences based on version of eclipse and the version of java which are documented in the link mentioned above.
I am struggling with maven-ant build with eclipse.
I did work like below steps.
[GUI] new java project
add build.xml in project top folder
run ant file and SUCCEED!
trying to code, but somehow auto completion does not work.(guessing eclipse can not read maven-ant dependency.path)
So I tried.
add ~/.m2/repository in build path as a External class folder - does not work - It looks weird to me to include whole this folder. My current project, I need little libraries, but it has whole libraries that I uses in other projects.
add builders with build.xml like Want an eclipse java project to run ant build files automatically - does not work neither.
How can I add this maven-ant libraries properly? Thanks for sharing your experiences and answers XD
=========== Extra Information ====================
This is my build.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project name="HibernateEx2" default="db" basedir="."
xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<property name="source.root" value="src"/>
<property name="class.root" value="classes"/>
<property name="data.dir" value="data"/>
<artifact:dependencies pathId="dependency.classpath">
<dependency groupId="hsqldb" artifactId="hsqldb" version="1.8.0.10"/>
<dependency groupId="org.hibernate" artifactId="hibernate-core" version="4.3.10.Final">
<exclusion groupId="javax.transaction" artifactId="jta"/>
</dependency>
<!-- 3.2.4.GA - After hibernate4 need upgrade hibernate-tools -->
<dependency groupId="org.hibernate" artifactId="hibernate-tools" version="4.3.1.CR1"/>
<dependency groupId="org.apache.geronimo.specs" artifactId="geronimo-jta_1.1_spec" version="1.1.1"/>
<!-- java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory -->
<dependency groupId="commons-logging" artifactId="commons-logging" version="1.2"/>
<dependency groupId="log4j" artifactId="log4j" version="1.2.17"/>
<!-- java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder -->
<dependency groupId="org.slf4j" artifactId="slf4j-log4j12" version="1.7.12"/>
</artifact:dependencies>
<path id="project.class.path">
<pathelement location="${class.root}"/>
<path refid="dependency.classpath" />
</path>
<!-- Explaining how to use hibernate -->
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="project.class.path"/>
<target name="db" description="Run HSQLDB database management UI against the database file -- use when application is not running">
<java classname="org.hsqldb.util.DatabaseManager" fork="yes">
<classpath refid="project.class.path"/>
<arg value="-driver"/>
<arg value="org.hsqldb.jdbcDriver"/>
<arg value="-url"/>
<arg value="jdbc:hsqldb:${data.dir}/music/"/>
<arg value="-user"/>
<arg value="sa"/>
</java>
</target>
<target name="print-classpath" description="Show the dependency class path">
<property name="class.path" refid="dependency.classpath"/>
<echo>${class.path}</echo>
</target>
<!-- Generate java code -->
<target name="codegen" description="Generate Java source from the OR mapping files">
<hibernatetool destdir="${source.root}">
<configuration configurationfile="${source.root}/hibernate.cfg.xml"/>
<hbm2java/>
</hibernatetool>
</target>
<!-- Creating Sub drectories -->
<target name="prepare" description="Set up build structures">
<mkdir dir="${class.root}"/>
<copy todir="${class.root}">
<fileset dir="${source.root}">
<include name="**/*.properties"/>
<include name="**/*.xml"/>
</fileset>
</copy>
</target>
<!-- Creating Schema for mapping files -->
<target name="schema" depends="prepare" description="Generate DB schema from the OR mappinf files">
<hibernatetool destdir="${source.root}">
<configuration configurationfile="${source.root}/hibernate.cfg.xml"/>
<hbm2ddl drop="yes"/>
</hibernatetool>
</target>
<!-- Compile Java -->
<!-- added includeantruntime="false" to javac, since terminal compile warning -->
<target name="compile" depends="prepare">
<javac srcdir="${source.root}" destdir="${class.root}"
debug="on" optimize="off" deprecation="on" includeantruntime="false">
<classpath refid="project.class.path"/>
</javac>
</target>
<target name="ctest" depends="compile">
<java classname="org.owls.ht.CreateTest" fork="true">
<classpath refid="project.class.path"/>
</java>
</target>
</project>
and This is what my project looks like.
src
-- source codes (includes hibernate.cfg.xml)
classes
-- compiled classes
data
-- logs and queries
build.xml
FYI, I am doing this with a book named [[Harness Hibernate]] written by James Elliot from O'reilly.
Thanks again b
For what you are trying to do, you need the filesetId and versionsId="dependency.versions" in your declaration of:
<artifact:dependencies filesetId="dependency.fileset" versionsId="dependency.versions"
Then add a copy task like so:
<copy todir="${lib.dir}">
<fileset refid="dependency.fileset" />
<mapper classpathref="maven-ant-tasks.classpath"
classname="org.apache.maven.artifact.ant.VersionMapper"
from="${dependency.versions}" to="flatten" />
</copy>
The to="flatten" will flaten your dependencies into a single folder, then you can include that folder on the classpath of eclipse project or wherever you need it.
I run a script that generates some java code based on definition files. I want to avoid running this task if the definition files have not changed.
<target name="generate" depends="init">
<exec executable="${codeGenTool-path}">
<arg value="${definitionFolder}" />
<arg value="${generatedFolder}" />
</exec>
</target>
I looked at http://ant.apache.org/manual/Tasks/uptodate.html but It seems like I must have a single target file to compare to. The code generation tool creates a folder containing many source files.
This is a good use case for the outofdate task from ant-contrib:
<outofdate>
<sourcefiles>
<fileset dir="${definitionFolder}" />
</sourcefiles>
<targetfiles>
<fileset dir="${generatedFolder}" />
</targetfiles>
<sequential>
<exec executable="${codeGenTool-path}">
<arg value="${definitionFolder}" />
<arg value="${generatedFolder}" />
</exec>
</sequential>
</outofdate>
This will check every file under the definitionFolder against every file under the generatedFolder - you might want to constrain the filesets more tightly, e.g. with includes="**/*.def" or whatever is the relevant file extension.
Alternatively, if you want to avoid "third party" tasks then you could use a dependset task to check the target files against the source ones.
<target name="generate" depends="check.generate, do.generate" />
<target name="check.generate">
<dependset>
<srcfileset dir="${definitionFolder}" />
<targetfileset dir="${generatedFolder}" />
</dependset>
<condition property="gen.required">
<resourcecount count="0" when="equal">
<fileset dir="${generatedFolder}" />
</resourcecount>
</condition>
</target>
<target name="do.generate" if="gen.required">
<exec ....>
</target>
The dependset task deletes all the target files if any of them are older than any of the source files, so we can make do.generate conditional - it will run if there are no files in the generatedFolder, which will be the case when either it's never been run before, or the generated files were out of date.
I am using the following demonstration script:
<?xml version="1.0" encoding="UTF-8"?>
<project name="test" basedir="." xmlns:deploy="antlib:net.sf.antcontrib">
<target name="default">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<deploy:if>
<isset property="defaultprop"/>
<then>
<echo message="it's set!"/>
</then>
</deploy:if>
</target>
</project>
When I run this build script (with target default), the error is
build.xml:9: Problem: failed to create task or type antlib:net.sf.antcontrib:if
The pathelement lib/ant-contrib-1.0b3.jar exists, and ant is picking it up. I'm thinking the problem is how I'm using the xmlns. I'm taking this from another example that I have that also doesn't work for me (it works on a particular server, though!), and trying to figure out what the magic sauce is.
Your taskdef where you're adding ant-contrib needs to declare a URI the same as the namespace you're defining and prefixing in the project. Similar to how the taskdef over here works.
<project name="test" basedir="." xmlns:deploy="antlib:net.sf.antcontrib">
<target name="default">
<taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml">
<classpath>
<pathelement location="lib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<deploy:if>
<isset property="defaultprop"/>
<then>
<echo message="it's set!"/>
</then>
</deploy:if>
</target>
</project>
Well, the error has if on the end, and it's talking about line 9. I think it's a problem with the syntax of this tag:
<deploy:if>
I can't find any documentation on a "deploy:if" tag, or even a "deploy" tag. I think there is no 'deploy' task in Ant - you need to make a 'deploy' target.
How about trying this:
<if>
<isset property="defaultprop"/>
<then>
<antcall target="deploy" />
</then>
</if>
As I read it, this will check the isset, then call the "deploy" target if it's set.
Of course, you need to make the 'deploy' target now :)