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".
Related
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.
I have been researching trying to find a way to combine multiple Jar files into on Jar as a deliverable.
In a directory I have an ant file named Jar_gen.xml that consists of the following code in its entirety
<target name="combine-jars">
<jar destfile="out.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</jar>
</target>
In that same directory I have another directory named lib which contains all of the Jar files I would like to flatten.
I have been running the ant script with
ant -buildfile Jar_gen.xml
making sure that I am running it from the same directory that the Jar_gen.xml file is in.
I am getting no output from my ant script and I have not idea why. Can someone please help me fix my script so I may flatten all of my jars and continue constructing my deliverable package.
NOTE
I have no main class so the Eclipse runnable Jar will not work for me
I have very little experience running Ant scripts so complete answers would be very helpful.
Is your directory structure set up correctly?
I created a quick test using your script and it appears to work, given that you have everything set up in a directory structure as
project_root_dir
- build.xml
- lib
- a.jar
- b.jar
and build.xml looks like:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project name="test">
<target name="combine-jars">
<jar destfile="out.jar">
<zipgroupfileset dir="lib" includes="*.jar"/>
</jar>
</target>
</project>
when I go to the project_root_dir and run "ant combine-jars", I get an out.jar that contains the contents of both a.jar and b.jar.
Typically, to make Ivy tasks available to an Ant build, you need to:
Add ivy.jar to ${ANT_HOME}/lib.
Add an xmlns:ivy="antlib:org.apache.ivy.ant" declaration to your build.xml's <project> element.
Add a <taskdef> declaration inside build.xml that reference's the ivy.jar's antlib.xml file where all other tasks are defined.
I'd like to accomplish all of the above except the first step (adding ivy.jar to ${ANT_HOME}/lib). I'd like to have ivy.jar living somewhere inside my project, say, at lib/buildtime/ivy.jar, and somehow reference lib/buildtime/ivy.jar as where Ivy is located.
Is this possible? If so, how? If not, why? Thanks in advance!
The taskdef (step 3) is not required if the ivy jar is located in a standard ANT library directory.
I would recommend including a special "bootstrap" target that will install the ivy jar. Once this is done all other dependencies (including 3rd party ANT tasks) can be downloaded by ivy as a build dependency.
Here is my default build file that demonstrates the concept:
<project name="demo" default="resolve" xmlns:ivy="antlib:org.apache.ivy.ant">
<target name="bootstrap" description="Install ivy">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
</target>
<target name="resolve" description="Use ivy to resolve classpaths">
<ivy:resolve/>
<ivy:report todir='build/ivy-reports' graph='false' xml='false'/>
<ivy:cachepath pathid="compile.path" conf="compile"/>
<ivy:cachepath pathid="test.path" conf="test"/>
</target>
<target name="clean" description="Cleanup build files">
<delete dir="build"/>
</target>
<target name="clean-all" depends="clean" description="Additionally purge ivy cache">
<ivy:cleancache/>
</target>
</project>
Notes:
The "bootstrap" target only needs to be run once on a new development environment. Once installed the ivy jar is available to all future ANT runs.
This example doesn't use "$ANT_HOME/lib" (which you may not have write permissions for). Instead it uses the lesser known "$HOME/.ant/lib" directory which serves the same purpose.
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?
I'm attempting to add Log4j to my project's classpath in Ant which creates an executable JAR, but it appears that it's not being added properly.
Here is the path component of my Ant build script:
<path id="classpath.compile">
<fileset dir="${dir.myLibs}">
<include name="**/*.jar"/>
</fileset>
<pathelement location="${dir.webContent}/WEB-INF/lib/log4j.jar" />
</path>
The compile target looks like this:
<target name="-compile">
<javac destdir="${dir.binaries}" source="1.6" target="1.6" debug="true" includeantruntime="false">
<src path="${dir.source}"/>
<classpath refid="classpath.compile"/>
</javac>
</target>
Tthe target that creates the JAR:
<target name="-createJar" >
<jar jarfile="${path.jarFile}"
manifest="${dir.source}\META-INF\MANIFEST.MF">
<fileset dir="${dir.binaries}" casesensitive="yes">
<exclude name="**/*.java"/>
</fileset>
</jar>
</target>
Lastly, the MANIFEST.MF:
Manifest-Version: 1.0
Class-Path: ../../../WebContent/WEB-INF/lib/log4j.jar (what is this pathing relative to?)
Main-Class: foo.Bar
The JAR is created, but when I execute it, I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger...
Any thoughts as to what I'm doing wrong?
It looks from the classpath in your MANIFEST that you are trying to reference a jar inside your jar. The only two ways to make that work AFAIK are 1) a special classloader, like #infosec812 mentions, or 2) by exploding the jar dependencies directly into the root of your jar. Either is workable, but I don't see either of them happening in your ant script.
If you're trying to reference a jar outside of your jar, your relative classpath is relative to the location of the jar you are executing. Make sure the referenced jar exists in that location.
I'm guessing that you're running the Java program as follows
java -jar myapp.jar
In this case you'll need to specify the Class-Path attribute in the manifest. I suggest you also check out the manifestclasspath task
Creating the jar does not include the linked libraries in the jar. You would have to have the required jars in your execution classpath in order to run it that way. Or, you could use the solution I use, which is to create a one-jar archive. It adds a specialized class loader for your application into the resulting jar and also packages your required jars in to the final executable jar. It works really well for deploying neat, simple to use packages.