Ant script import overriding main path id name - ant

Say I have the following Ant script:
<project name = "imported">
<path id="same.classpath>
<pathelement location="c:\temp\imported"/>
</path>
<target name="imported.echo">
<echo>hell from import</echo>
</target>
</project>
that will be imported into this one:
<project name = "importer">
<path id="same.classpath>
<pathelement location="c:\temp\importer"/>
</path>
<import file="imported.xml" as="i" />
<target name="importer.echo" depends="i.imported.echo">
<echo>hell from import</echo>
</target>
</project>
When I run the second script, it seems as if the path referenced by same.classpath in importer.xml is not used. Instead the one referenced by imported (c:\temp\imported) is being used. If I assign unique names for the path id, I do not run into this problem, hence the guess.
From my understanding of the literature, properties from the main file take precedence. But this is not what I am observing. Did I miss something?

In this case what's being overwritten is not a property but a reference id. Unlike properties the referee - what the reference id is associated with - can be changed during a build, which is what you observe.

Related

Ant Throws Reference Error for Existing Jar File

I want to add task to my build.xml file:
<target name="forbidden-checks" depends="download-forbidden-checks">
<taskdef name="forbidden-apis" classname="de.thetaphi.forbiddenapis.AntTask"
classpathref="lib/forbiddenapis-2.2.jar"/>
<fa:forbiddenapis classpathref="build.classpath" dir="${build.dir}" targetVersion="${jdk.version}">
<bundledsignatures name="jdk-unsafe"/>
<bundledsignatures name="jdk-deprecated"/>
<bundledsignatures name="jdk-non-portable"/>
</fa:forbiddenapis>
</target>
I see that jar is downloaded, there is no problem. However I get an error:
download-forbidden-checks:
setup-maven-url:
download-via-maven:
[get] Getting: https://repo1.maven.org/maven2/de/thetaphi/forbiddenapis/2.2/forbiddenapis-2.2.jar
[get] To: /home/kamaci/pro/lib/forbiddenapis-2.2.jar
forbidden-checks:
BUILD FAILED
/home/kamaci/pro/build.xml:2391: Reference /home/kamaci/pro/lib/forbiddenapis-2.2.jar not found.
I checked if I have a problem with the path of jar. So, I've put forbiddenapis-2.2.jar to another place than the project. I've pointed that jar from my taskef but I got same error.
Any ideas?
EDIT 1:
I've changed it to that:
<target name="forbidden-checks" depends="download-forbidden-checks">
<taskdef name="forbidden-apis" classname="de.thetaphi.forbiddenapis.AntTask">
<classpath>
<pathelement location="/home/kamaci/pro/forbiddenapis-2.2.jar"/>
</classpath>
</taskdef>
<fa:forbiddenapis targetVersion="${jdk.version}">
<classpath>
<pathelement location="lib/forbiddenapis-2.2.jar"/>
</classpath>
<bundledsignatures name="jdk-unsafe"/>
<bundledsignatures name="jdk-deprecated"/>
<bundledsignatures name="jdk-non-portable"/>
</fa:forbiddenapis>
</target>
However, it didn't work:
Problem: failed to create task or type antlib:de.thetaphi.forbiddenapis:forbiddenapis
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.
No types or tasks have been defined in this namespace yet
This appears to be an antlib declaration.
Action: Check that the implementing library exists in one of:
-/usr/share/ant/lib
-/home/kamaci/.ant/lib
-a directory added on the command line with the -lib argument
When I run this:
ant forbidden-checks -lib lib/
it works. My project definition starts with that at build.xml:
Why I should add -lib? Is there any way to avoid it?
Pretty sure the issue is the classpathref as it is using a literal value and not a path element, so the jar may exist just not on the classpath, try creating a path element to use for the taskdef
<path id="lib.path">
<fileset dir="lib" includes="lib/*.jar"/>
</path>
<taskdef name="forbidden-apis" classname="de.thetaphi.forbiddenapis.AntTask"
classpathref="lib.path"/>
or defining the classpath inside the taskdef.
<taskdef name="forbidden-apis" classname="de.thetaphi.forbiddenapis.AntTask">
<classpath>
<pathelement location="lib/forbiddenapis-2.2.jar"/>
</classpath>
</taskdef>

ANT how to execute a JAR or EXE files on a specific folder

I have a POS software (Point Of Sale) runs on ANT, never worked on ant so please if possible provide full code to run either an EXE or a JAR executable file on a specific location.
I have those following codes and no use:
<target name="build">
<java fork="true" failonerror="yes" classname="com.CodeReview">
<classpath>
<pathelement location="xyz"/>
<pathelement path="${C:/xyz.jar}"/>
</classpath>
<arg line="-p"/>
<arg line="D:\Test"/>
</java>
</target>
PS: First code gave this error:
com.openbravo.pos.scripting.ScriptException:
Encountered ":/xyz.jar}\"/>\n \n\n ...
The error is caused by the ${ and } around C:/xyz.jar, which should not be there because C:/xyz.jar is a literal and not the name of a property whose value you want to use.
If you defined a property like this:
<property name="path.to.xyz.jar" value="C:/xyz.jar"/>
...then you could later reference it like this:
<pathelement path="${path.to.xyz.jar}"/>
Otherwise, to insert the value directly without using a property, the ${ and the } must be removed:
<pathelement path="C:/xyz.jar"/>

Ant build script not seeing refid

I have a build.xml file that includes a common.xml file that defines some refid values. However, my task cannot see the refid value. I have not been able to find a solution on the web and am looking for some help.
I call the genbeans target in the build.xml file. It fails on the xmlbean taskdef with the message Reference my_classpath_jars not found.
build.xml
----------------------------
[includes common.xml]
**my_classpath_jars fails to be seen at this point - defined in common.xml**
<taskdef name="xmlbean" classname="org.apache.xmlbeans.impl.tool.XMLBean">
<classpath refid="my_classpath_jars"/>
</taskdef>
<!-- Generate the XMLBeans java code from our source XSD file(s) -->
<target name="genbeans" description="Generate XML Bean files" depends="build_my_jar_cpath">
<mkdir dir="${lib}"/>
<xmlbean destfile="${lib}/${appname}Beans.jar" failonerror="true">
<classpath refid="my_classpath_jars"/>
<fileset dir="src/XSD Files" includes="*.xsd, *.wsdl"/>
</xmlbean>
</target>
common.xml
-----------------------------
<target name="build_my_jar_cpath">
<path id="my_classpath_jars">
<fileset dir="${jardir}" includes="**/*.jar" />
</path>
<pathconvert pathsep="${path.separator}" property="myjar.clpath" refid="my_classpath_jars"/>
</target>
When in doubt, use the ant -d switch when calling your target. You'll see a ton of output. Save it to a file and parse through it.
Do that, and the first thing you'll notice in the output is that it's defining your taskdefbefore you have defined your my_classpath_jars. That my_classpath_jars refid is only set when you call that greenbeans target. Your <taskdef> is executed before any of your targets are called.
Either take the definition of my_classpath_jars out of the target greenbeans, or put your <taskdef> in there.

What does the Ant warning "Reference * has not been set at runtime..." mean?

Since the upgrade from Ant 1.6.5 to 1.7.1, my build output starts off with:
Warning: Reference project.classpath has not been set at runtime, but was found during
build file parsing, attempting to resolve. Future versions of Ant may support
referencing ids defined in non-executed targets.
Warning: Reference project.test.classpath has not been set at runtime, but was found during
build file parsing, attempting to resolve. Future versions of Ant may support
referencing ids defined in non-executed targets.
I have problems understanding this and why it is outputted, let alone trying to get rid of it. Any help would be appreciated!
EDIT:
Classpath is defined:
<path id="project.classpath">
<pathelement path="./${build.dir}" />
<path refid="libs.ant" />
<fileset dir="${lib.dir}/dependencies/bar" includes="compile/*.jar" />
<fileset dir="${lib.dir}/dependencies/foo" includes="provided/*.jar" />
</path>
<!-- The classpath for compiling this projects' tests -->
<path id="project.test.classpath">
<path refid="project.classpath" />
<fileset dir="${lib.dir}/dependencies/bar" includes="test/*.jar" />
<fileset dir="${lib.dir}/dependencies/foo" includes="test/*.jar" />
</path>
<property name="project.classpath" refid="project.classpath" />
It is referenced (e.g. in ) in this way:
<classpath refid="project.classpath"/>
I had the same issue before. Just make sure the "project.classpath" is defined in the beginning of the build file before other targets reference it. Also your "libs.ant" path should be defined before "project.classpath".
In Ant 1.8 this will actually be error instead of warning.
You can set classpath in the build file as following, to get rid of this warning. See reference. http://ant.apache.org/manual/using.html
<project ... >
<path id="project.class.path">
<pathelement location="lib/"/>
<pathelement path="${java.class.path}/"/>
<pathelement path="${additional.path}"/>
</path>
<target ... >
<rmic ...>
<classpath refid="project.class.path"/>
</rmic>
</target>
<target ... >
<javac ...>
<classpath refid="project.class.path"/>
</javac>
</target>
</project>
Unless this is a typo, it looks like trouble. You really should rename one for clarity even if it isn't the cause of the warning. It still sounds like project.classpath is defined in different targets and they are called in the wrong order. You may need to show more code for more help.
<property name="project.classpath" refid="project.classpath" />

Why cannot Ant taskdef cannot load a resource outside ./net

When declaring external ant tasks using taskdef, for instance ant-contrib, the proposed setup is to use the followin taskdef:
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
This works when antcontrib.properties is located in net/sf/antcontrib relative to the build.xml file.
But when I put it in lib/net/sf/antcontrib and changes the taskdef into
<taskdef resource="lib/net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="lib/ant-contrib/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
Ant is not able to find the properties file, it gives the error
[taskdef] Could not load definitions from resource
lib/net/sf/antcontrib/antcontrib.properties. It could not be found.
It seems like ant treats the lib directory separately and fails to load a taskdef resource from there.
As Alex said, you shouldn't need to unzip the jar. The <taskdef> can load antcontrib.properties directly out of the jar.
The error you got is because you changed the resource path, but the path to the file inside the compressed jar/zip is still the same. The taskdef isn't paying attention to the properties file you moved because the <classpath> you provided to <taskdef> tells it to only look in the jar.
Use antlib.xml resource:
Here is the taskdef definition that I use:
<property name="ant-contrib.jar" location="..."/>
<taskdef
resource="net/sf/antcontrib/antlib.xml"
uri="http://ant-contrib.sourceforge.net"
>
<classpath>
<pathelement location="${ant-contrib.jar}"/>
</classpath>
</taskdef>
You do not need to extract anything from the jar file. Also, uri attribute is optional if you do not want to use namespaces with antcontrib tasks.
To handle classpath for tasks definitions, I use a classpath ref in Ant, it's way easier. You can link either a directory containing classes, either a directory containing many .jar, either (of course) a single .jar.
For example :
<!-- Properties -->
<property name="lib" value="lib/" />
<property name="classes" value="bin/" />
<!-- Classpath definition -->
<path id="runtime-classpath" >
<pathelement location="${bin}" />
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
</path>
<!-- Taskdefs definitions -->
<taskdef name="myTask" classname="org.stackoverflow.tasks.MyTask" classpathref="runtime-classpath" />
<!-- Tasks -->
<target name="test" description="Test Action">
<myTask parameter1="value" />
</target>

Resources