Ant script fails to detect the javafx classes when compiling - ant

I am using the Ant script to compile my source code. previously it was compiling perfectly . recently i added classes which uses javafx specific classes .after this ant is not compiling and it fails to find the javafx classes . i am using jdk 7 update 23 as javafx is inculded in the jdk, i cannot figure out why compilation fails ?.
below is my ant script.
<?xml version="1.0" encoding="UTF-8" ?>
<project name="client" basedir="." default="compile" >
<description>Client</description>
<property file="build.properties" />
<path id="classpath">
<fileset dir="${lib.dir}" includes="*.*"/>
</path>
<!-- Initialization -->
<target name="init" description="Prepare needed directories.">
<mkdir dir="${build.dir}" />
<mkdir dir="${classes.dir}" />
<mkdir dir="${jar.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<!-- Cleanup -->
<target name="clean" description="Remove all files created by the build/test process.">
<delete dir="${classes.dir}" />
<delete dir="${dist.dir}" />
<delete dir="${build.dir}" />
</target>
<!-- Compile application -->
<target name="compile" depends="init" >
<mkdir dir="${classes.dir}"/>
<javac source="1.7" target="1.7" srcdir="${src.dir}" destdir="${classes.dir}" debug="yes" includeantruntime="false" fork="true" memorymaximumsize="1200m" >
<classpath refid="classpath" />
</javac>
</target>
<path id="lib.lib">
<fileset dir="../lib">
<include name="**/*"/>
</fileset>
</path>
<pathconvert property="mf.classpath" pathsep=" lib/">
<path refid="lib.lib"/>
<flattenmapper/>
</pathconvert>
<!-- Java Archive -->
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/Client.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Class-Path" value="lib/${mf.classpath}"/>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
</target>
</project>

Suggested Solution
If you want to use ant with JavaFX, you should use Oracle's JavaFX ant tasks.
The JavaFX runtime is included with Java 7 and the Oracle JavaFX ant tasks are aware of it's location, so when you use the Oracle ant tasks, builds of projects referencing JavaFX work.
Why your current build fails
Compilation fails for your script because the JavaFX runtime (jfxrt.jar) is not on the default class path for Java 7.
For Java 8 the JavaFX runtime is on the class path.
You can still use plain ant without the Oracle JavaFX ant tasks to build your application (just by ensuring jfxrt.jar is on the class path for your build step), however use of the Oracle tasks is recommended as they will also appropriately package your application for distribution.
See also: Compile code using JavaFX 2.0 (using command line)

Related

Build a Jenkins plugin with Ant

My company only uses Ant to build projects. However, Jenkins only suggests Maven as a build tool for plugin development.
How could I package my Jenkins plugin to a .hpi file using Ant and avoiding Maven at all costs?
Here is a way to build a Jenkins plugin using Ant. Let's make a script that builds a plugin skeleton which name is "awesome".
Default plugin arborescence
awesome-plugin/
-- awesome/
-- src/
-- pom.xml
Instructions
Add a lib/ folder which contains the following jars:
to be found in your Jenkins home directory Jenkins\war\WEB-INF\lib (note: you have to use the exact same versions that your current Jenkins use):
access-modifier-annotation-1.4.jar
bridge-method-annotation-1.4.jar
commons-io-1.4.jar
guava-11.0.1.jar
jenkins-core-1.513.jar
json-lib-2.4-jenkins-1.jar
remoting-2.23.jar
sezpoz-1.9.jar
stapler-1.207.jar
to be found on the web (you can choose the last version released):
servlet-api-2.4.jar
Replace the existing pom.xml with the following build.xml.
In the Ant script, you should adapt:
the project name, awesome here,
the plugin version,
the Jenkins version this plugin is made for,
the project group.id (main package), org.jenkinsci.plugins.awesome here.
New plugin arborescence
awesome-plugin/
-- awesome/
-- src/
-- lib/
-- you should have 10 jars here
-- build.xml
build.xml
<!-- Project dependent properties -->
<property name="project_name" value="awesome"/>
<property name="project_version" value="1.0"/>
<property name="jenkins_version" value="1.513"/> <!-- which version of Jenkins is this plugin built against? -->
<property name="project_groupid" value="org.jenkinsci.plugins.awesome"/>
<!-- Build properties -->
<property name="lib_dir" value="./lib"/>
<property name="bin_dir" value="./bin" />
<property name="target_dir" value="./target"/>
<property name="target_bin_dir" value="${target_dir}/${project_name}"/>
<property name="plugin_targetMetaInf_dir" value="${target_bin_dir}/META-INF"/>
<property name="plugin_targetWebInf_dir" value="${target_bin_dir}/WEB-INF"/>
<property name="plugin_targetWebInfBin_dir" value="${plugin_targetWebInf_dir}/classes"/>
<!-- Project paths -->
<path id="project.source.path">
<pathelement path="src/main/java" />
</path>
<path id="project.class.path">
<fileset dir="${lib_dir}" includes="*.jar"/>
</path>
<!-- Build flow -->
<target name="build">
<antcall target="clean" />
<antcall target="compile" />
<antcall target="createTreeDirectory" />
<antcall target="copyBin"/>
<condition property="has_file">
<and>
<available file="${target_dir}/${project_name}.hpi" type="file"/>
</and>
</condition>
<antcall target="createHpi"/>
<condition property="has_dir">
<and>
<available file="${target_bin_dir}" type="dir"/>
</and>
</condition>
<antcall target="cleanTargetDirectory" />
</target>
<!-- Cleans existing binaries -->
<target name="clean">
<delete includeEmptyDirs="true" quiet="true">
<fileset dir="${bin_dir}" />
</delete>
<mkdir dir="${bin_dir}"/>
</target>
<!-- Compiles JAVA code -->
<target name="compile">
<javac includeantruntime="false" destdir="${bin_dir}" debug="false" optimize="${optimize}" deprecation="${deprecation}" classpathref="project.class.path">
<src refid="project.source.path" />
</javac>
</target>
<!-- Creates necessary target folders -->
<target name="createTreeDirectory" >
<mkdir dir="${target_bin_dir}"/>
<mkdir dir="${plugin_targetMetaInf_dir}"/>
<mkdir dir="${plugin_targetWebInf_dir}"/>
<mkdir dir="${plugin_targetWebInfBin_dir}"/>
</target>
<!-- Moves new binaries to the plugin target -->
<target name="copyBin">
<copy todir="${plugin_targetWebInfBin_dir}" >
<fileset dir="${bin_dir}"/>
<fileset dir="src/main/resources"/>
</copy>
</target>
<!-- Cleans the target directory -->
<target name="cleanTargetDirectory" if="has_dir">
<delete dir="${target_bin_dir}"/>
</target>
<!-- Backup previous plugin -->
<target name="saveOldHpiFile" if="has_file">
<move file="${target_dir}/${project_name}.hpi" tofile="${target_dir}/${project_name}.save.hpi"/>
</target>
<!-- Archives the plugin -->
<target name="createHpi">
<antcall target="saveOldHpiFile"/>
<jar destfile="${target_dir}/${project_name}.hpi" basedir="${target_bin_dir}">
<manifest>
<attribute name="Manifest-Version" value="{project_version}"/>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Created-By" value="${user.name}"/>
<attribute name="Build-Jdk" value="${ant.java.version}"/>
<attribute name="Extension-Name" value="${project_name}"/>
<attribute name="Implementation-Title" value="${project_name}"/>
<attribute name="Implementation-Version" value="${version}"/>
<attribute name="Group-Id" value="${project_groupid}"/>
<attribute name="Short-Name" value="${project_name}"/>
<attribute name="Long-Name" value="${project_name}"/>
<attribute name="Plugin-Version" value="${project_version}"/>
<attribute name="Jenkins-Version" value="${jenkins_version}"/>
<attribute name="Hudson-Version" value="${jenkins_version}"/>
</manifest>
</jar>
</target>
To launch the build, cd towards the build.xml and type ant.
I know you stated "at all costs", but a compromise might be less effort, and still give super fast builds. A big reason for me to try to avoid maven is that the compile time is sloooowwwwww. That said, maven is quite good at creating the hpl file, and handling dependencies. The following targets are quite useful for helping to set up a super-fast non-maven build:
use 'mvn hpi:hpl' to generate the hpl file
use 'mvn dependency:copy-dependencies' to download all your dependencies, and put them into target/dependency, where it's easy to reference them from your ant script (you can add a symbolic link if necessary, from lib to target/dependency)

Ant With Internal Dependencies

I have a a jar right now that uses external dependencies. I'm trying to create a jar that packages all the external dependencies inside, and will just give me one jar. I saw this question asked multiple times, but I still can't figure it out. I'm using Ant, and copied some of the examples I saw on here. I'm using zipgroupfileset to reference the external(now internal) jars. As soon as I added the zipgroupfileset I got a runtime error that said my Runner class could not be found.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. -->
<project basedir="." default="build" name="ExcelDemo">
<property environment="env"/>
<property name="ECLIPSE_HOME" value="../../../../Program Files (x86)/eclipse"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<property name="external-lib-dir" value="lib\poi-3.9" />
<property name="external-lib-dir2" value="lib\poi-3.9\lib" />
<property name="external-lib-dir3" value="lib\poi-3.9\ooxml-lib" />
<path id="ExcelDemo.classpath">
<pathelement location="bin"/>
</path>
<target name="init">
<mkdir dir="bin"/>
<copy includeemptydirs="false" todir="bin">
<fileset dir="src" excludes="**/*.launch, **/*.java"/>
</copy>
</target>
<target name="clean">
<delete dir="bin"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="ExcelDemo.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects">
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="clean"/>
<ant antfile="${ExcelSensitize.location}/build.xml" inheritAll="false" target="build">
<propertyset>
<propertyref name="build.compiler"/>
</propertyset>
</ant>
</target>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
<target name="RunnerClass">
<java classname="runner.RunnerClass" failonerror="true" fork="yes">
<classpath refid="ExcelDemo.classpath"/>
</java>
</target>
<target name="jar" description="Create a jar for this project">
<manifestclasspath property="lib.list" jarfile="Test.jar">
<classpath refid="ExcelDemo.classpath" />
</manifestclasspath>
<jar jarfile="Test.jar" includes="*.class" basedir="bin">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir2}" includes="*.jar"/>
<zipgroupfileset dir="${external-lib-dir3}" includes="*.jar"/>
<manifest>
<attribute name="Class-Path" value="${lib.list}" />
<attribute name="Main-Class" value="runner.RunnerClass" />
</manifest>
</jar>
</target>
</project>
To make things simpler:
Create a separate sources jar for compilation. Then, have a separate compiled jar without the sources.
Don't include the third party jars. Instead, use Ivy with Ant. Ant will automatically download the required jars. In fact, I've see sources that just include the ivy.jar, so Ivy will automatically be configured when you unjar the sources. You type in ant, and everything just builds.
As an alternative, you can look at Maven which is how many projects are now packaged. In fact, if your jar is an open source project, you can probably host it on the OSS Maven repository. This way, no one even needs to manually download your compiled jar. If they want it, they configure their Maven project to do it for them.
i think the problem is that you use basedir="bin" in the your jar task. then path of your zipgroupfileset convert to bin/${external-lib-dir}

ant build script don't run on windows using command line

i have written an ant script, which runs ok and generate the .jar file when i use it with eclipse.
But when i use it on command prompt on windows xp, it's shows successfull, but nothing happens. ant is properly configured and also i can run other ant scripts.
here is my build.xml file
<?xml version="1.0"?>
<project name="TaskNodeBundle" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="bundlename" value="task-node-bundle" />
<property name="src.dir" location="../src" />
<property name="lib.dir" location="../lib" />
<property name="build.dir" location="/buildoutput" />
<property name="build.dest" location="build/dest" />
<!--
Create a classpath container which can be later used in the ant task
-->
<path id="classpath">
<fileset dir="${lib.dir}/">
<include name="*.jar" />
</fileset>
</path>
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${build.dest}" />
</target>
<!-- Deletes the existing build directory-->
<target name="mkdir" depends="clean">
<mkdir dir="${build.dest}"/>
</target>
<!-- Compiles the java code -->
<target name="compile" depends="mkdir">
<javac srcdir="${src.dir}" destdir="${build.dest}" classpathref="classpath" />
</target>
<target name="package-bundle" depends="compile" description="Generates the bundle">
<jar destfile="${dist.dir}/${bundlename}.jar">
<fileset dir="${src.dir}">
<include name="**/**.class" />
<include name="**/**.properties"/>
<include name="/META-INF/**.*" />
<include name="/META-INF/spring/**.*" />
</fileset>
</jar>
</target>
</project>
When you execute an ant script from the command line it will execute the first target defined in the build.xml file (in your case clean).
You can specify the target(s) to be executed on the command line
$ ant target1 target2
or define a default target in your build.xml file with the default attribute of the <project> tag:
<project name="TaskNodeBundle" basedir="." default="package-bundle">

ANT Generated jar: is it a namespace issue?

I have a Eclipse-Java-Project with an ANT-build-file. This build file exports a jar of the project without compiling it. So I only export the sources.
<target name="jar">
<mkdir dir="/jar"/>
<jar destfile="/jar/my_test_jarfile.jar" basedir="/src" />
</target>
I use this generated jar in another eclipse java project and set the path to the jar in the build-path-settings of the project. The problem is that eclipse says it cannot resolve the namespace of the imported classes of the jar.
If I export the jar manually by right clicking on the project and then "Export" and putting the jar to the build path of the other project, everything works fine and there are no errors. So the question is now, what am I doing wrong?
So here is my solution. It seems that you have to compile the source first and then pack it into a jar. I don't give a guarantee that this jar is exactly the same like the one you get from eclipse when you do the right click thing and export etc.
But it works for me, there are no namespace errors any longer. so here is a minimum version of my ant targets:
<project default="run" basedir=".">
<property name="src.dir" value="src" />
<property name="classes.dir" value="bin" />
<property name="build.dir" value="build" />
<path id="libs">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement path="${basedir}\${classes.dir}"/>
</path>
<target name="run">
<antcall target="compile"/>
<antcall target="jar"/>
</target>
<target name="compile">
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="libs" encoding="UTF-8" />
</target>
<target name="jar">
<jar destfile="${build.dir}/my_jar_file.jar" basedir="${classes.dir}">
</target>
</project>

Javadoc errors when building Ant project

I am trying to write a build.xml file for my project. When I run build.xml as an Ant project, I get the following error:
D:\workspace\LogAlerter\src\com\j32bit\alerter\launcher\LogAlerter.java:9:
error: package org.apache.log4j does not exist
[javadoc] import org.apache.log4j.Logger;
I have imported log4j in LogAlerter.Java. Here is my build.xml file:
<?xml version="1.0"?>
<project name="LogAlerter" default="main" basedir=".">
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="src.dir" location="src" />
<property name="build.dir" location="build" />
<property name="dist.dir" location="dist" />
<property name="docs.dir" location="docs" />
<property name="libs.dir" location="lib" />
<!--
Create a classpath container which can be later used in the ant task
-->
<path id="build.classpath">
<fileset dir="${libs.dir}">
<include name="**/*.jar" />
</fileset>
</path>
<!-- Deletes the existing build, docs and dist directory-->
<target name="clean">
<delete dir="${build.dir}" />
<delete dir="${docs.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- Creates the build, docs and dist directory-->
<target name="makedir">
<mkdir dir="${build.dir}" />
<mkdir dir="${docs.dir}" />
<mkdir dir="${dist.dir}" />
</target>
<!-- Compiles the java code (including the usage of library for JUnit -->
<target name="compile" depends="clean, makedir" >
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="build.classpath" includeantruntime="false">
</javac>
</target>
<!-- Creates Javadoc -->
<target name="docs" depends="compile">
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}">
<!-- Define which files / directory should get included, we include all -->
<packageset dir="${src.dir}" defaultexcludes="yes">
<include name="**" />
</packageset>
</javadoc>
</target>
<!--Creates the deployable jar file -->
<target name="jar" depends="compile">
<jar destfile="${dist.dir}\LogAlerter.jar" basedir="${build.dir}">
<manifest>
<attribute name="Main-Class" value="LogAlerter.Main" />
</manifest>
</jar>
</target>
<target name="main" depends="compile, jar, docs">
<description>Main target</description>
</target>
</project>
Try adding a classpath ref to your javadoc task:
<javadoc packagenames="src"
sourcepath="${src.dir}"
destdir="${docs.dir}"
classpathref="build.classpath">
What the warning is telling you is that you've not provided the full classpath to the javadoc task. Try adding a similar classpath ref to that in your compile task and see where that leads.
Importing is fine but make sure it is available at run time for the JavaDoc tool. log4j.jar should be present in your build.classpath.
Make use of the classpathref inside the docs target like so:
<javadoc packagenames="src" sourcepath="${src.dir}" destdir="${docs.dir}" classpathref="build.classpath">

Resources