using xjc with ant - java

I am trying to use xjc compiler from ant. Builds successfully but nothing gets generated.
My ant script is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<project name="AutomateWithAnt" basedir=".">
<property file="build.properties"/>
<path id="compile.classpath">
<fileset dir="${lib.includes}" includes="*.jar"></fileset>
</path>
<target name="init" description="create java class">
</target>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask" classpathref="compile.classpath"/>
<!-- Generates the source code from the test.xsd schema using jaxb -->
<target name="option-generate" description="Generates the source code" depends="init">
<xjc schema="test.xsd" destdir="${generated-src.dir}" package="${generated-src.dir}">
<arg value="-Xcommons-lang" />
<arg value="-Xcommons-lang:ToStringStyle=SHORT_PREFIX_STYLE" />
<produces dir="${generated-src.dir}" includes="**/*.java" />
</xjc>
</target>
</project>
my build.properties is:
lib.includes=lib/
generated-src.dir=/
I am using java 1.6 and I have used jaxb-sjc.jar.

You've defined 2 Ant targets (init and option-generate), but neither of them will be invoked unless you specify which one to run.
You either need to specify it on the command line, e.g.
ant option-generate
or add a default target to the <project> element, e.g.
<project name="AutomateWithAnt" basedir="." default="option-generate">
Incidentally, your init target is empty, and therefore pointless.

Related

Ant javac task not compiling. Its 'srcdir' parameter not behaving as documented. Is this a bug?

I have written the Ant script pasted below. It uses the javac task. The Apache documentation states that scrdir parameter is used to point to the source (.java) files. But it also explains that the javac task can use patternsets.
I believe there may be a bug in the javac task or at least, perhaps a poor implementation of the javac Ant task.
In my code, the compile target fails because the source files cannot be found. Can anyone please explain why?
Background:
Directory structure of my project is as follows:
My ant scripts are in the ant directory.
Source files are inside wm-adapter/src
<?xml version="1.0" encoding="UTF-8"?>
<project name="wm-adapter" default="dev" basedir=".">
<property file="Build.properties"/>
<property name="build.compiler" value="javac1.5"/>
<target name="compile" depends="prepare">
<!-- Define required FileSets and PatternSets... -->
<patternset id="patternset.wm.adapter.sources">
<include name="${source.dir}/*.java"/>
<exclude name=""/>
</patternset>
<fileset id="fileset.wm.adapter.sources" dir="${proj.dir}">
<patternset refid="patternset.wm.adapter.sources"/>
</fileset>
<!-- Compile... -->
<javac srcdir="${basedir}"
destdir="${classes.dir}"
classpath="${compile.classpath}"
debug="${javac.debug}"
verbose="true"
fork="true"
source="1.5"
target="1.5">
<patternset refid="patternset.wm.adapter.sources"/>
</javac>
<echo message=" Compilation completed successfully!"/>
</target>
Here is a snippet from the properties file:
# DEFINE DIRECTORY STRUCTURE...
proj.dir=../wm-adapter
source.dir=${proj.dir}/src
build.dir=${proj.dir}/build
classes.dir=${build.dir}/classes
dist.dir=${proj.dir}/dist
lib.dir=../lib
docs.dir=${proj.dir}/documentation
resources.dir=${proj.dir}/www
config.dir=${proj.dir}/config
# DECLARE ANY OTHER WORKING DIRECTORIES...
tmp.jar.dir=C:\\Temp
tmp.app.dir=${tmp.jar.dir}/FATCA_WM_Adapter
# Name the jar file...
jar.file=FATCA_WM_Adapter.jar
# IMPORT EXTERNAL JARS INTO OUR CLASSPATH...
compile.classpath=${g11nutils.jar};${javax.ejb_3.0.jar};${middleware_UTILS.jar};${wmbrokerclient.jar};${classes.dir}
compile.classpath=${classes.dir};${lib.dir}
basedir has been defined as '.'
I know how to make it work: The target will compile if:
I make changes to the patternset as shown below:
<patternset id="patternset.wm.adapter.sources">
<include name="src/*.java"/>
<exclude name=""/>
</patternset>
Within the javac task I ammend srcdir to:
srcdir="${proj.dir}"
But this is a fix! Why do my original settings not work?
basedir here is equal to your 'ant' subdir, which is probably why it doesn't work. Perhaps you want <project basedir=".."> at the top.

Problems with Ant build.xml configuration to work with external Libraries and Java property files

I have a problem with Ant Build Tool.
First, below you can see my project structure:
and the content of my build.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<project name="addonGenerator" default="main" basedir=".">
<property name="projectName" value="addonGenerator"/>
<property name="src.dir" location="src"/>
<property name="build.dir" location="bin"/>
<property name="dist.dir" location="dist"/>
<target name="compile" description="compile the source ">
<mkdir dir="${build.dir}"/>
<javac srcdir="${src.dir}" destdir="${build.dir}">
<classpath>
<pathelement path="lib/velocity-1.7.jar"/>
<pathelement path="lib/log4j-1.2.16.jar"/>
</classpath>
</javac>
</target>
<target name="dist" description="package, output to JAR">
<mkdir dir="${dist.dir}"/>
<jar jarfile="${dist.dir}/${projectName}.jar" basedir="${build.dir}">
<zipgroupfileset dir="lib" includes="velocity-1.7.jar" />
<zipgroupfileset dir="lib" includes="log4j-1.2.16.jar" />
<manifest>
<attribute name="${projectName}" value="main"/>
<attribute name="Main-Class" value="main.java.AddonGenerator"/>
</manifest>
</jar>
</target>
<target name="clean" description="clean up">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="main" depends="clean, compile, dist"/>
</project>
I don't know how setup the Ant build.xml to build and run my project with external libraries and the java property file generator.properties
To include your generator.properties file in the .jar file, add your resources directory when building the .jar:
<jar jarfile="${dist.dir}/${projectName}.jar" basedir="${build.dir}">
<fileset dir="src/main/java/resources"/>
Since you are currently building a “fat jar” (by directly including the contents of your library .jars in your application .jar), you can run by simply invoking your .jar file. Such a target obviously requires the .jar file to be built, so it makes sense to depend on the "dist" target:
<target name="run" depends="dist">
<java jar="${dist.dir}/${projectName}.jar"/>
</target>
On another note, I don’t think you want to pass src as your source directory, unless your classes actually declare themselves with ‘package main.java;’ (which they shouldn’t). You should pass the actual root of your packages to the javac task:
<property name="src.dir" location="src/main/java"/>
You should also make the "dist" target depend on "compile", since, well, it depends on having compiled classes available.
I also would suggest that your default target, "main", avoid calling the "clean" target. You should not clean before every single build; that defeats one of the most useful benefits of Ant, namely the ability to update only the things that need to be updated. You should only clean when you need to, with a command like ant clean compile or simply ant clean.
Note that once "dist" depends on "compile", and once "main" no longer calls "clean", you can simply remove the "main" target and change your project’s default target to "dist". When you think about it, this makes sense: the default action is to build and package the application.

Using Ant's classpath in Eclipse

I have an Ant build.xml file that works just fine on the command line: it compiles, builds the JAR, and I am able to execute the main method from the JAR just fine. The build.xml file references several thirdparty libraries that are scattered here and there. When building the JAR, the script doesn't include all the thirdparty libraries into the JAR itself. Instead, it puts their path into the JAR's manifest. This helps to keep my JAR slim and tidy.
I'd like to be able to edit and debug my project in Eclipse, but I can't find an easy way to do so. I can have my project use the Ant file to build the project, and that seems to work. However, Eclipse is having trouble finding the thirdparty libaries, and thus Eclipse is having two problems:
it shows (in the text editor) lots of compile errors, because
lots of classes are undefined, and
it can't execute the JAR.
I can solve both of the above problems by specifying by hand, in two difference places (i.e., the build path via Properties->Java Build Path->Libraries, and the execution classpath via Run Configurations->Classpath), all the third party libraries. But it seems like I shouldn't have to do this manually, since all the third party libraries are already listed in my JAR's manifest. What am I doing wrong?
Here's my build.xml file:
<!-- Set global properties for this build -->
<property name="src" location="./src" />
<property name="build" location="./build"/>
<property name="dist" location="./dist"/>
<property name="logs" location="./logs"/>
<property name="docs" location="./docs"/>
<property name="jar" location="${dist}/dynamic_analyzer.jar"/>
<property name="lib" location="../../thirdparty/lib"/>
<property name="hive-util" location="../../hive-utils/dist"/>
<property name="hpdb" location="../../hive-db/hpdb/dist"/>
<property name="static" location="../../hive-backend/static_analyzer/dist"/>
<property name="mainclass" value="com.datawarellc.main.DynamicMain"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${docs}"/>
<delete dir="${logs}"/>
</target>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${dist}"/>
<mkdir dir="${logs}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<!-- Debug output of classpath -->
<property name="myclasspath" refid="dep.runtime"/>
<echo message="Classpath = ${myclasspath}"/>
</target>
<target name="jar" depends="compile">
<!-- Put the classpath in the manifest -->
<manifestclasspath property="manifest_cp" jarfile="${jar}" maxParentLevels="10">
<classpath refid="dep.runtime" />
</manifestclasspath>
<jar jarfile="${jar}" basedir="${build}">
<manifest>
<attribute name="Main-Class" value="${mainclass}"/>
<attribute name="Class-Path" value="${manifest_cp}"/>
</manifest>
<zipfileset dir="${src}" includes="**/*.xml" />
</jar>
</target>
You can see that I have third-party libraries in several directories (${lib}, ${hive-util}, ${hpdb}, and ${static}). I use these to create a path called dep.runtime. I then include dep.runtime in the manifest when building my jar. How can I get Eclipse to use the same dep.runtime for the build path and the classpath when executing?
An alternative to perl is to use an embedded groovy task:
<project name="demo" default="eclipse-files">
<property name="src.dir" location="src"/>
<property name="classes.dir" location="build/classes"/>
<path id="dep.runtime">
<fileset dir="${lib}" includes="**/*.jar"/>
<fileset dir="${hive-util}" includes="**/*.jar"/>
<fileset dir="${hpdb}" includes="**/*.jar"/>
<fileset dir="${static}" includes="**/*.jar"/>
</path>
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.4/groovy-all-2.1.4.jar"/>
</target>
<target name="eclipse-files">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
import groovy.xml.MarkupBuilder
project.log "Creating .classpath"
new File(".classpath").withWriter { writer ->
def xml = new MarkupBuilder(writer)
xml.classpath() {
classpathentry(kind:"src", path:properties["src.dir"])
classpathentry(kind:"output", path:properties["classes.dir"])
classpathentry(kind:"con", path:"org.eclipse.jdt.launching.JRE_CONTAINER")
project.references."dep.runtime".each {
classpathentry(kind:"lib", path:it)
}
}
}
</groovy>
</target>
<target name="clean">
<delete file=".classpath"/>
</target>
</project>
Notes:
The bootstrap target will download the 3rd party groovy jar (No dependency on perl)
Groovy can access the "dep.runtime" ANT path directly and iterate over its contents
Groovy has excellent support for writing XML files.
The following answer is similar and additionally generates the Eclipse .project file.
Using Apache Ivy with netbeans
I came up with the following workaround, inspired by the link provided by #leeand00.
First, I wrote a simple Perl script (called genClasspath.pl) that generates the .classpath file that Eclipse uses.
#!/usr/bin/perl
use strict;
if (#ARGV != 2) {
print STDERR "Usage: $0 OUTFILE CLASSPATHSTRING\n";
print STDERR "e.g., $0 .classpath path1:path2:path3\n";
exit 1;
}
my $OUTFILE = $ARGV[0];
my $CLASSPATHSTRING = $ARGV[1];
open my $out_fh, '>', $OUTFILE or die "Couldn't open output file: $!";
print $out_fh q{<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="build"/>
};
my #libs = split(":", $CLASSPATHSTRING);
foreach my $thisLib (#libs){
print $out_fh " <classpathentry kind=\"lib\" path=\"$thisLib\"/>\n";
}
print $out_fh "</classpath>\n";
Then, I have my build.xml file call this script with the content of dep.runtime:
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" debug="on" includeantruntime="false">
<classpath refid="dep.runtime" />
</javac>
<property name="myclasspath" refid="dep.runtime"/>
<exec dir="." executable="../../scripts/genClasspath.pl" os="Linux">
<arg value=".classpath"/>
<arg value="${myclasspath}"/>
</exec>
</target>
The only catch is that I need to run Ant on the command line at least once before I open the project in Eclipse. But when I do, Eclipse is able to compile and execute my project just fine, since the classpath is exactly the same as Ant's.

ANT JAR file for JavaFX Application

I have successfully complied the JavaFX code using Build Script with the previous help. Now I can not able to create JAR file uisng ANT for my application. I am adding sample script in build.xml. My requirement is to create a simple JAR file of my JavaFx XYZ application.
<project name="XYZ" basedir=".">
<property name="WorkingFolder" location="XYZSourceData"/>
<property name="ClassPath" location="C:\Program Files\Oracle\JavaFX 2.2 Runtime\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_09\lib\ant-javafx.jar;"/>
<target name="init">
<echo message="Java installation directory: ${java.home}"/>
<!-- Create the time stamp -->
<tstamp/>
<delete dir="${WorkingFolder}/build"/>
<delete dir="${dist}"/>
<mkdir dir="${WorkingFolder}/CustomJars"/>
</target>
<target name="Compilingxyz" depends="init">
<mkdir dir="${WorkingFolder}/build"/>
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant" classpath=".;C:\Program Files\Oracle\JavaFX 2.2 Runtime\lib\jfxrt.jar"/>
<javac classpath="${ClassPath};${WorkingFolder}/CustomJars/*.jar;" srcdir="${WorkingFolder}/src/com/xyz" destdir="${WorkingFolder}/build"/>
</target>
<target name="CreatingxyzJars" depends="Compilingxyz" description="generate the distribution" >
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant" classpath="C:\Program Files\Java\jdk1.7.0_09\lib\ant-javafx.jar"/>
<fx:jar destfile="${WorkingFolder}/CustomJars/XYZ.jar">
<fx:application name="XYZ"
mainClass="com.xyz.main.XYZEntryFX"/>
<fx:resources>
<fx:fileset dir="${WorkingFolder}/build" includes="${WorkingFolder}/libs/*.jar"/>
</fx:resources>
<fileset dir="${WorkingFolder}/resources"/>
</fx:jar>
</target>
I am getting following error -
BUILD FAILED
C:\Users\JavaUser4\Desktop\2012.12FX\build.xml:83: The prefix "fx" for element "
fx:jar" is not bound.
Total time: 0 seconds
What is the missing part? I have Java Desktop application. How can I create a ANT JAR for Java Fx Application. Please Help.
I am taking reference of following example -
Example
You're missing the fx: namespace declaration in your project. Rather than
<project name="XYZ" basedir=".">
you need something like:
<project name="XYZ" basedir="."
xmlns:fx="javafx:com.sun.javafx.tools.ant">
(This is from the documentation you linked to, prior page, §12.3 Using JavaFX Ant Tasks.)

How can I build multiple projects in Ant with one build file?

Can I build multiple projects from one build-file. Example:
<project basedir="." default="all" name="app1">
...
</project>
<project basedir="." default="all" name="app2">
...
</project>
Currently I type ant -f build1.xml compile and it builds my application and I have to use two separate build files. Is there some way to get it running in a way that i have both the projects defined a common build-file and I can type something like ant app1 compile or ant app2 compile?
Here's what my build-file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<project name="azebooster" default="dist" basedir=".">
<!-- Globals -->
<property name="src" location="src/com/aelitis"/>
<property name="build" location="build/azebooster"/>
<property name="jar" location="jar/azebooster"/>
<property name="resources" location="res/azebooster"/>
<!-- Paths -->
<path id="classpath">
<fileset dir="." includes="**/*.jar"/>
</path>
<!-- Start it -->
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
<mkdir dir="${jar}"/>
</target>
<!-- Build it -->
<target name="compile" depends="init" description="compile the source" >
<javac srcdir="${src}" destdir="${build}">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Jar it -->
<target name="jar" depends="compile">
<jar destfile="${jar}/${ant.project.name}.jar">
<fileset dir="${build}"/>
<fileset dir="${resources}" />
</jar>
</target>
<!-- Clean it -->
<target name="clean" description="clean up" >
<tstamp/>
<delete dir="${build}"/>
<delete dir="${jar}"/>
</target>
</project>
Thank you.
Yes you can create a default.build file (in this way you don't need to specify the file, because it's used by default). On it you can create the following targets:
<target name="all" depends="app1, app2" />
<target name="app1">
<ant antfile=<app1file> target="compile" />
</target>
<target name="app2">
<ant antfile=<app2file> target="compile" />
</target>
On this way you can use both ant file from one unique file.
And you can do all in only one file, if you replace the app1 and app2 targets, with the needed targets to compile them that you have in the separate files.
EDITED:
You have different ways to include both of them in only one file, maybe the easiest one is include a suffix for each project on each target. And you can call the specific project target or the target for both.
I put you an example with the compile target (and for init target too).
You can use compile for compile both projects (I call the other project other), and compileazeboster to compile the azeboster project.
You can search the common things to avoid the innecesary duplicated code (common paths, targets and so on)
<property name="srcazebooster" location="src/com/aelitis"/>
<property name="buildazebooster" location="build/azebooster"/>
<property name="jarazebooster" location="jar/azebooster"/>
<property name="srcother" location="src/other"/>
<property name="buildother" location="build/other"/>
<property name="jarother" location="jar/other"/>
<!-- Start it -->
<target name="init" depends="initazebooster, initother"/>
<!-- Build it -->
<target name="compile" depends="compileazebooster, compileother" description="compile the source for all" />
<!-- Start azebooster-->
<target name="initazebooster">
<tstamp/>
<mkdir dir="${buildazebooster}"/>
<mkdir dir="${jarazebooster}"/>
</target>
<!-- Build azeboster-->
<target name="compileazebooster" depends="initazebooster" description="compile the source for azebooster" >
<javac srcdir="${srcazebooster}" destdir="${buildazebooster}">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
<!-- Start other-->
<target name="initother">
<tstamp/>
<mkdir dir="${buildotherr}"/>
<mkdir dir="${jarother}"/>
</target>
<!-- Build other-->
<target name="compileother" depends="initother" description="compile the source for other" >
<javac srcdir="${srcother}" destdir="${buildother}">
<classpath>
<path refid="classpath"/>
</classpath>
</javac>
</target>
You will probably be able to do what you want using macros (though it depends precisely on what is common between your two projects), though your command is more likely to be
ant compile app1
or
ant compile app2
where compile is a target which calls a macro, using app1/app2 as a parameter to either decide which macro to call or to pass into the macro itself.
I would like to add to the excellent answer of Borja some important steps.
How to organize the common ant files?
Let's say we have some big Project consisting of many Eclipse projects. All of them are in a worspace folder. Thus, the workspace itself makes the global Project. (Notice P/p difference). Very often you already have an Ant build file in the workspace folder. Or you have created the common ant files (build and properties) in it by yourself.
Later you want to launch that global build file. How? Do you want to go into the workspace folder, change to the command line or shell window and run the ant from there, having the output in the external console and switching from Eclipse to that window and back? And the same problem for editing? Having two additional windows? No, surely you want to have all windows, editing and output, in Eclipse. But how can we reference those global build files from inside the Eclipse?
Go to Package Explorer.
Make an empty project(not Java one), let's name it _Global (we want to see it always on the top).
Right click on its name. Choose Import -> General -> File System.
Press Advanced. Check Create links in Workspace, Create virtual folders, create link locations. The last choose for WORKSPACE_LOC.
In From Directory go to the workspace or where you have created the common build. After all, it could be even the common one for several workspaces.
You will see a dialogue with file names on the right with checkfields. Check the files you need. (You will need to import every new common file you created thereafter).
Finish.
Now you see your project with references to the global files. As for properties files, you are ready. But for build files you need some more steps:
Right click your global build file, -> Run -> Run Configurations. You are in the Ant Build group of configurations.
Press the New Launch Configuration button with plus on it (above the launch configurations list). Now you have the run configuration for that global build.
Set its parameters and run/debug it.

Categories