I need to compile a jar file using ant (1.7.0) to run under a specific version of Java (1.5). I currently have Java 1.6 on my machine. I have tried setting:
<target name="compile">
<javac compiler="javac1.5" target="1.5" srcdir=.../>
</target>
I have also removed
<property name="build.compiler" value="modern"/>
and there is no properties file. I am running Java 1.6 on Linux/SUSE
Also is there a simple way of determining which version of Java is expected in the jar file.
Use "target" attribute and remove the 'compiler' attribute. See here. So it should go something like this:
<target name="compile">
<javac target="1.5" srcdir=.../>
</target>
Both source and target should be specified. I recommend providing ant defaults, that way you do not need to specify source/target attribute for every javac task:
<property name="ant.build.javac.source" value="1.5"/>
<property name="ant.build.javac.target" value="1.5"/>
See Java cross-compiling notes for more information.
To find the version of the java in the classfiles I used:
javap -verbose <classname>
which announces the version at the start as
minor version: 0
major version: 49
which corresponds to Java 1.5
You may also set {{ant.build.javac.target=1.5}} ant property to update default target version of task.
See http://ant.apache.org/manual/javacprops.html#target
Related
Does anybody have an example of using JDK 6 style - only defining the directory and not list of each and every jar in the directory - classpath with an ANT javac compile task?
We tried it like this
compile.classpath=c:....\WEB-INF\lib*;...websphere...\a.jar;...websphere...\b.jar; etc. and used this classpath in the javac task, but the libraries from WEB-INF\lib were not being recognised.
So, I am wondering if it is possible to use this type of construct with ANT. The ANT version is 1.8.4.
Typically we use path like structures .
<path id="project.classpath">
<fileset dir="${libdirectory}">
<include name="*.jar"/>
</fileset>
</path>
The the project.classpath is used in javac task. See more at ant examples
I do not yet know, why this works vs. why it doesn't work without these attributes, but I was able to get the wildcard part to work by using the fork="yes" and executable="path-to-my-executable" attributes in the javac task.
I have several build files which all import the same base build file, like this:
base.xml:
<project name="base">
<!-- does not define a 'build' target -->
</project>
buildA.xml:
<project name="buildA">
<import file="base.xml" />
<target name="build">
<ant antfile="buildB.xml" target="build"
inheritall="false" inheritrefs="false" />
</target>
</project>
buildB.xml:
<project name="buildB">
<import file="base.xml" />
<target name="build">
...snip...
</target>
</project>
(Module A depends on module B.)
Now, the above calling of B's build target from buildA.xml gives the following error:
Duplicated project name in import. Project base defined first in buildA.xml and again in buildB.xml
Since both buildA.xml and buildB.xml inherit the same base.xml, this seems unavoidable.
How could I get rid of this error?
Based on sudocode's answer, I solved the problem. Because the absolute path to base.xml is different in both cases, Ant does not recognize it as the same file. Even though inheritAll is set to false, the context of the calling task is preserved and this causes the name clash.
To solve this, one can omit the name attribute from base.xml. Since Ant 1.8, the import task has an attribute as, which can be used to reference base targets when the base project is nameless. If you don't override any targets, you can use include instead of import. I'm on 1.7, so that does not help me.
For previous versions of Ant, you can go through an exec call to prevent proliferation of the Ant context entirely (then you get two running Ant instances). Better yet, find a way to import the exact same base.xml (with the same absolute path) in both files.
Are you using Ant 1.6? This resolved Ant bug looks like the same issue.
EDIT
I tried to reproduce the dir structure you refer to in your recent comment.
./base.xml
./buildA
./buildA/buildA.xml
./buildB
./buildB/buildB.xml
And amended the build files accordingly, e.g.
<project name="buildA">
<import file="../base.xml"/>
<target name="build">
<ant antfile="../buildB/buildB.xml" target="build" inheritall="false" inheritrefs="false"/>
</target>
</project>
I still get no build error for the following with ant 1.8.2 or 1.7.1:
ant -f buildA/buildA.xml build
I use Ant to build my Android application. I want to be able to do this:
ant debug android-market; //build the debug version for android-market;
ant debug motorola-market; //Builds debug version for motorola-market;
ant release android-market; //etc.
Is there a way to detect that "android-market" parameter from within my custom ant debug/release task?
I would prefer not to use Dparam=value, since that is less clean looking.
This syntax is used to invoke multiple targets at once. So you could perhaps use
ant android-market debug
and make the android-market target set a property used in the debug target to identify which version to build:
<project basedir="." default="debug">
<target name="android-market">
<property name="market" value="android"/>
</target>
<target name="debug">
<echo message="debugging for the following market : ${market}"/>
</target>
</project>
> ant android-market debug
> android-market:
> debug:
> [echo] debugging for the following market : android
I would prefer not to use -Dparam=value, since that is less clean looking.
I think you should get over your preferences. But add a 'help' target that describes the parameters accepted by the other targets.
JB's answer totally worked but I wanted to find a way to have a default. I found an answer to that here by someone named Mike Schilling: http://www.velocityreviews.com/forums/t137033-is-it-possible-to-alter-ant-properties-after-theyve-been-initialized.html
So I ended up having something like this:
<project basedir="." default="debug">
<target name="set-defaults">
<property name="market" value="android"/>
</target>
<target name="motorola-market">
<property name="market" value="motorola/>
</target>
<target name="debug" depends="set-defaults">
<echo message="debugging for the following market : ${market}"/>
</target>
</project>
So you could do ant debug for android or ant motorola-market debug for motorola.
I wanted to have a look which system properties are set here (and to which values), so the easiest way (if not writing a new Java program here) would be adding some lines to my ant build script:
<target name="properties">
<echoproperties/>
</target>
But running ant gives my this error message:
/u/ebermann/projektoj/stackoverflow-examples/build.xml:19: Problem: failed to create task or type echoproperties
Cause: the class org.apache.tools.ant.taskdefs.optional.EchoProperties was not found.
This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
-/usr/share/ant/lib
-/u/ebermann/.ant/lib
-a directory added on the command line with the -lib argument
Do not panic, this is a common problem.
The commonest cause is a missing JAR.
This is not a bug; it is a configuration problem
Okay, so I don't panic, but wonder what to do.
I have Ant 1.7.1 here (an OpenSUSE system), and sadly no documentation for this version, and I'm not root to install either a current ant version or the documentation for the old version (I just downloaded it and it still does not say which jar file is needed here). Of the directories listed above, only /usr/share/ant/lib exists, but it contains nothing like optional.
I would want to download the necessary jar file and put it in my home directory, but where to find it? The ant download archive contains nothing like that, and I have no idea where else to search. (I did google a bit, but did not find anything.
So, can someone give me some pointers where to find the right jar file?
(I suppose the solution is quite easy, and something is just blocking my view.)
After vahapt's answer, I downloaded the file from the apache repository, and put it into the directory /u/ebermann/.ant/lib mentioned by the error message. Running ant properties again - the same result as above.
$ jar -tf /u/ebermann/.ant/lib/ant-nodeps-1.7.1.jar | grep 'EchoProperties.class'
org/apache/tools/ant/taskdefs/optional/EchoProperties.class
This looks like it should work - is the error message simply wrong?
If I put it directly into the CLASSPATH, it works:
$ CLASSPATH=/u/ebermann/.ant/lib/ant-nodeps-1.7.1.jar ant properties
Buildfile: build.xml
properties:
[echoproperties] #Ant properties
[echoproperties] #Thu Mar 10 00:46:22 CET 2011
...
[echoproperties] user.name=ebermann
[echoproperties] user.timezone=
BUILD SUCCESSFUL
Total time: 0 seconds
I don't want to change my normal CLASSPATH variable, and it should work by putting it into this directory, or did I understand something wrong?
Any ideas, or is this an ant bug?
(Also, why is this file nowhere mentioned in the ant documentation?)
Edit:
After the answer from vahapt, my ant build-file looks like this:
<project name="stackoverflow-examples" basedir=".">
<target name="echoproperties.prepare">
<available property="echoproperties.works"
classname="org.apache.tools.ant.taskdefs.optional.EchoProperties"
/>
</target>
<target name="echoproperties.init"
depends="echoproperties.prepare"
unless="echoproperties.works">
<taskdef name="echoproperties" classname="org.apache.tools.ant.taskdefs.optional.EchoProperties">
<classpath>
<fileset dir="${user.home}/.ant/lib">
<include name="ant-nodeps.jar" />
</fileset>
</classpath>
</taskdef>
</target>
<target name="properties" depends="echoproperties.init">
<echoproperties/>
</target>
</project>
This re-registers the task only if it is not already in the ant classpath. (Thus it should also work for complete ant installations which do not have this file in the home directory).
I would still say that This is not a bug; it is a configuration problem is not totally right, even more as putting the file in the indicated directory does not help.
One more interesting observation: The nodeps.jar in ${user.home}/.ant/lib (i.e. now /u/ebermann/.ant/lib/ant-nodeps.jar) is already in the class path (the one shown by ${java.class.path}, but this seems not to help for <echoproperties> to work without this taskdef.
So, this works too:
<target name="echoproperties.init"
depends="echoproperties.prepare"
unless="echoproperties.works">
<taskdef name="echoproperties"
classname="org.apache.tools.ant.taskdefs.optional.EchoProperties"
classpath="${java.class.path}" />
</target>
When you make a google search, results point to ant-nodeps-1.7.1.jar
Make sure that jar exists and you've added it into the classpath
For the second part of your question:
SOLUTION 1. You do not need to modify your CLASSPATH variable. Instead you might add it by adding the parameter -cp [JAR FILE LOCATION] (-cp is for "java" executable)
SOLUTION 2. Jar files are simply zip files, open ant-nodeps.jar copy its content to ant.jar throw away ant-nodeps.jar
SOLUTION 3. See the sample below. taskdef is a ant feature that loads a jar or a class into ClassLoader hierarchy. (You load the class before using it, works like a charm)
<?xml version="1.0" encoding="ASCII"?>
<project name="Test" default="properties" basedir=".">
<target name="properties" depends="init">
<echoproperties/>
</target>
<target name="init">
<taskdef name="echoproperties" classname="org.apache.tools.ant.taskdefs.optional.EchoProperties">
<classpath>
<fileset dir="${ant.library.dir}">
<include name="ant-nodeps.jar" />
</fileset>
</classpath>
</taskdef>
</target>
</project>
I downloaded Ant 1.7.1 and looked in the documentation that came with it. There it described echoproperties as an optional task, but didn't mention where to get the jarfile for this optional task.
Looking inside the lib folder, I discovered the ant-nodeps.jar. Apparently, it was included with Ant 1.7.1.
I would recommend that you download and install Ant 1.8. Since Ant is a Java jar file, it's not really all that difficult to install the latest and greatest version.
I looked on my Mac, and /usr/bin/ant is a link to /usr/share/ant/bin and /usr/share/ant/ is a link to /usr/share/java/ant-1.8.2. So, all I have to do is point /usr/share/ant/bin/ to the correct version of Ant.
In Ant 1.8.2, echoproperties is now a standard task.
I'm trying to call an Antlr task in my Ant build.xml as follows:
<path id="classpath.build">
<fileset dir="${dir.lib.build}" includes="**/*.jar" />
</path>
...
<target name="generate-lexer" depends="init">
<antlr target="${file.antlr.lexer}">
<classpath refid="classpath.build"/>
</antlr>
</target>
But Ant can't find the task definition. I've put all of the following in that dir.lib.build:
antlr-3.1.jar
antlr-2.7.7.jar
antlr-runtime-3.1.jar
stringtemplate-3.2.jar
But none of those seems to have the task definition. (I've also tried putting those jars in my Ant classpath; same problem.)
The current Antlr-task jar is available at http://www.antlr.org/share/1169924912745/antlr3-task.zip
It can be found on the antlr.org website under the "File Sharing" heading.
You should use the antlrall.jar jar. You can go ahead and just drop it into your Ant installation but that does mean that it will only work for that one install. We check the jar in and use taskdef to load the jar file so that it doesn't become another step for developers when they start on the team or move to a new computer.
Antlr http://ant.apache.org/manual/Tasks/antlr.html
Using taskdef http://www.onjava.com/pub/a/onjava/2004/06/02/anttask.html
I just got this working for myself. Took me an hour. ugh. anyway,
Step 1: download ant-antlr3 task from
http://www.antlr.org/share/1169924912745/antlr3-task.zip
Step 2: copy to where ant can see it. My mac:
sudo cp /usr/local/lib/ant-antlr3.jar /usr/share/ant/lib/
my linux box:
sudo cp /tmp/ant-antlr3.jar /usr/local/apache-ant-1.8.1/lib/
Step 3: make sure antlr2, antlr3, ST are in classpath. All in one is here:
http://antlr.org/download/antlr-3.3-complete.jar
Step 4: use in build.xml
<path id="classpath">
<pathelement location="${antlr3.jar}"/>
<pathelement location="${ant-antlr3.jar}"/>
</path>
<target name="antlr" depends="init">
<antlr:ant-antlr3 xmlns:antlr="antlib:org/apache/tools/ant/antlr"
target="src/T.g"
outputdirectory="build">
<classpath refid="classpath"/>
</antlr:ant-antlr3>
</target>
Just added a faq entry:
http://www.antlr.org/wiki/pages/viewpage.action?pageId=24805671
The most basic way to run Antlr is to execute the Antlr JAR:
<project default="antlr">
<target name="antlr">
<java jar="antlr-4.1-complete.jar" fork="true">
<arg value="grammar.g4"/>
</java>
</target>
</project>
This is a bit slower, because it forks the JVM and it runs Antlr even if the grammar did not change. But it works in the same way with every Antlr version and does not need any special targets.
On Ubuntu this should make it available:
sudo apt-get install ant-optional
Additional info on top of what everybody else contributed so far:
The ant-optional package in Ubuntu includes the task shipped with Ant 1.8.2 which is a task for ANTLR 2.7.2 so this will fail with an error as described in this post. The method described by Terence is the best way to use the ANTLR3 task.
If you do not have root access on a Linux machine, you can install the ant-antlr3.jar file in the Ant user directory: ~/.ant/lib. Check with ant -diagnostics whether ant-antlr3.jar is visible to Ant, as explained in this other post.
If you are using Eclipse, you will need to restart the IDE before it recognises the new task and you will also need to include antlr3.jar and stringtemplate.jar in your classpath (but ant-antlr3.jar is not necessary).