Building a project in Netbeans. I have a single custom ANT Target in build.xml that copies two library files to dist/lib before the program runs:
<?xml version="1.0" encoding="UTF-8"?>
<project name="ApplicationName" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">
<description>Builds, tests, and runs the project EnrollmentApplication.</description>
<import file="nbproject/build-impl.xml"/>
<target name="-post-jar">
<echo message="Copying dll files..." />
<copy file="lib/file1.dll" todir="${dist.dir}/lib" />
<copy file="lib/file2.dll" todir="${dist.dir}/lib" />
</target>
</project>
However, when I make code changes, build, and run, the code changes aren't reflected in the new run. If I clean, rebuild, and run, I get Error: Unable to access jarfile <file path>\Application1.jar
Modifying build.xml manually at this point lets the project rebuild correctly once, and then the cycle starts over again. What am I misunderstanding about this Ant Target? It seems extremely straightforward.
EDIT:
Apparently copying files has nothing to do with it. Even overriding -post-jar with just the <echo> task yields the same problems
After looking at nbproject/build-impl.xml, it was apparent that the -post-jar target had dependencies that I was not including in my overriding target. They are listed below (note that this is a JavaFX program).
<target depends="-jfx-copylibs,-rebase-libs,jfx-deployment" name="-post-jar">
I assume these other targets are only called because -post-jar lists them as dependencies, i.e. they are not called by any other target.
Related
Is it possible to create an Apache Ant build.xml that can create a task in one target and subsequently use it in another target?
Here is a simple build.xml to illustrate this:
<project name="BuildAndUseTask" default="use-task">
<!-- Define the task -->
<taskdef name="testtask"
classname="org.example.TestTask"/>
<!-- Compile the task -->
<target name="compile-task">
<javac srcdir="task/src" destdir="."/>
</target>
<!-- Use the task -->
<target name="use-task" depends="compile-task">
<testtask option="something"/>
</target>
</project>
The output I get is:
Buildfile: /path/to/build.xml
BUILD FAILED
/path/to/build.xml:5: taskdef class org.example.TestTask cannot be found
using the classloader AntClassLoader[]
Is this possible to do this as a single step without resorting to using nested Ant executions? I am working around this separately by first commenting the <taskdef>, explicitly building the compile-task target, uncommenting the <taskdef>, and finally build the use-task target.
Working with a client who still lives in the ant build environment world (on a Windows box). Want to use google-cloud-translate library in a Java program but if I include all the dependencies of google-cloud-translate that's over 40 jars with everything from guava to threetenbp to joda-time to google-cloud-core and more if I include all the dependencies of the dependencies and the optional ones. Is there an easy way to package up all the dependencies into a single JAR so I only need the one jar file referenced in the build.xml?
If you absolutely need to use Ant, there's a pretty simple option for this, although it uses a package that is no longer maintained: http://maven.apache.org/ant-tasks/index.html
With the Maven Ant Tasks, you can define an artifact in your build with the <artifact:dependencies> task, and that artifact will be resolved to your local repo along with all of its own dependencies. You can also give it a filesetId so you can easily manipulate the files after that point:
<project xmlns:artifact="antlib:org.apache.maven.artifact.ant">
<typedef
classpath="lib/maven-ant-tasks.jar"
resource="org/apache/maven/artifact/ant/antlib.xml"
uri="antlib:org.apache.maven.artifact.ant"
/>
<target name="resolve-google-cloud-translate-artifacts">
<artifact:dependencies filesetId="google-cloud-translate">
<dependency artifactId="google-cloud-translate" groupId="com.google.cloud" version="1.38.0" />
<remoteRepository id="central" url="https://repo.maven.apache.org/maven2/" />
</artifact:dependencies>
<delete dir="google-cloud-translate.libs" />
<mkdir dir="google-cloud-translate.libs" />
<copy todir="google-cloud-translate.libs">
<fileset refid="google-cloud-translate" />
<flattenmapper />
</copy>
</target>
</project>
Note the artifact: namespace definition in the project element. The Maven tasks won't work without it.
My ant has:
<target name="createJava">
<javac ... />
</target>
<target name="build" depends="createJava, compile" />
The createJava task adds a few java files under src root.
However, main build target always compile except them. How can I add java files created in the middle of build?
Looks like the files for "compile" has been set before "createJava" and no updated before "compile".
I have an Android Library project, AndroidLib, that depends on a Java project in my workspace, JavaLib.
In Eclipse this is done by adding the JavaLib project to Java Build Path > Projects for AndroidLib and setting it to be exported in the Order and Export tab, and it builds fine.
However Ant doesn't seem to pick up the dependency on the JavaLib project when building AndroidLib (I have run android update lib-project). What is the best way to add this dependency to my build.xml?
I had the same problem. I ended solving it in a very hackish way.
In AndroidLib/build.xml (or better in AndroidLib/custom_rules.xml), I defined a -pre-build target that builds the JavaLib and copies the resulting jar in libs/. I also defined a -post-package target to remove the copied jar, otherwise Eclipse will get confused.
<property name="lib.javalib.project.dir" location="${basedir}/../JavaLib" />
<target name="-pre-build">
<subant buildpath="${lib.javalib.project.dir}" target="package" failonerror="true" />
<copy todir="${basedir}/libs" failonerror="true" verbose="true">
<fileset dir="${lib.javalib.project.dir}/target">
<filename name="javalib*.jar"/>
</fileset>
</copy>
</target>
<target name="-post-package">
<delete verbose="true">
<fileset dir="${basedir}/libs" includes="javalib*.jar" />
</delete>
</target>
This solution is far from satisfying, but it gets the job done.
You will find a similar question and answer there : Android Ant Include Java Library projects
I'll answer my own question: the only way to do this properly is to not use Ant.
You need a proper dependency management system. Maven is your only real choice here.
You need a build system that supports Maven. I currently use Maven again for this, because at the time it was the only mature build tool that also supported Maven dependency management -- now (albeit for Android Library Projects, since the format for these is not yet final) Gradle should be your build tool of choice.
I changed my build.xml to run the java project's ant file and then copy the jar to the libs folder:
<target name="-pre-compile">
<ant antfile="build.xml" dir="dependencies/JavaUtils" target="clean"/>
<ant antfile="build.xml" dir="dependencies/JavaUtils"/>
<copy todir="${jar.libs.dir}" failonerror="true" file="dependencies/JavaUtils/dist/Java-utils.jar"/>
<sleep seconds="3"/> <!-- Delay for the file to be recognized after the copy -->
</target>
How this helped someone.
BTW, I started reading about Gradle's dependency/build/whatever system and got the creeps from it. Ahhh, what a relief to get back to ant...
I know how to create javadocs for my source file in Apache Ant Build.
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
But I don't know how to create them in Apache Ivy.
Could some one show me a sample example ?
Apache Ivy is a dependency management library for use with (not a replacement for) Apache Ant. Therefore, you will use the same <javadoc> task as always.
Apache Ivy is a dependency manager that works with Ant (a build manager). Apache Ivy is usually (or possible always?) used with Ant to handle builds. Since javadoc creation is a build task not a dependency task, it wouldn't make sense to generate javadocs using Ivy.
It looks like you're going around in a circle here. Ivy works with Ant. You still have a build.xml file that you use for your builds. The ivy.xml file simply contains a list of the third-party jars your project needs in order to build. Thus, the direct answer to your question would be:
Put the following in your build.xml:
<target name="doc" description="generate documentation">
<delete dir="${doc.dir}"/>
<mkdir dir="${doc.dir}"/>
<javadoc sourcepath="${source.dir}" destdir="${doc.dir}"/>
</target>
When you use Ivy, you still use Ant. And, you still have a build.xml file. And, you still write compose your build with various Ant tasks.
Download this project. It's a simple build that contains three class files and a build.xml file. You will notice there's a jar directory with the following two jars:
commons-logging-1.1.1.jar
spring.jar
If you look at lines 36 to 40 of the build.xml file, the project is creating a compile classpath like this:
<path id="java">
<fileset file="jar/spring.jar"/>
<fileset file="jar/commons-logging-1.1.1.jar"/>
</path>
So, when he compiles, he does this:
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Now, let's look at how this may change with Ivy. In Ivy, I create a ivy.xml file that contains a description of what jars I need. However, I only have to specify classes I use directly. In this case, I only need the spring.jar. Here's my ivy.xml:
<ivy-module version="1.0>
<info organisation="com.seantheflexguy"
name="ContextExample"
revision="1.0"/>
<configurations>
<conf="default" visibility="public"/>
<conf="compile" visibility="public"/>
</configurations>
<dependencies>
<dependency org="org.springframework" name="spring"
rev="2.0.4" conf="compile->default"/>
</dependencies>
</ivy-module>
Now, instead, of using the jars in the jar directory, I'll have Ivy construct the classpath:
<ivy:resolve/>
<ivy:cachepath pathid="java"/>
<javac destdir="bin">
<src path="${src}"/>
<classpath refid="java"/>
</javac>
Notice instead of using the <path> task to create a classpath, I use two Ant tasks that Ivy uses. The <ivy:resolve/> looks at my ivy.xml and resolves my dependencies on the jars I request. These jars will be downloaded into my $HOME/.ivy2/cache directory.
The <ivy:cachepath> task creates a classpath I'm calling the classpath java because that's what it was previously called.
With those two Ivy tasks, I've created a classpath that I can use with the <javac> task. In fact, I'm not even bothering to change the <javac> task.
So, in Ivy:
I still need my build.xml. It's how I define the various build tasks I need to do. In fact, Ivy defines even more Ant tasks I need in my build.xml file.
The ivy.xml file simply defines my jar dependencies. When I implement Ivy in this project, I can delete the jar directory.
Does this help you understand how Ivy works?