How to build jar-file with ant? - java

According to the training task, I need to create .jar-file with ant. There are no problems with the Assembly of ordinary classes that are in src .
But I have in project present logger, libraries to him and .properties file.
because of this, errors fly out:
[javac] error: package org.apache.logging.log4j does not exist
and
error: cannot find symbol
[javac] error: private static final Logger logger = LogManager.getLogger(Hello.class);
I have build.xml
<?xml version="1.0"?>
<project name="Runner" default="run">
<!-- define names of directories -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="classes" location="${build}/classes"/>
<!-- define all targets -->
<target name="compile">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}" includeAntRuntime="false"/>
</target>
<target name="run" depends="compile">
<java classname="${ant.project.name}" classpath="${classes}"/>
</target>
<target name="clean">
<delete dir="${build}"/>
</target>
<target name="package" depends="compile">
<jar destfile="${build}/${ant.project.name}.jar" basedir="${classes}">
<manifest>
<attribute name="Main–Class" value="${ant.project.name}"/>
</manifest>
</jar>
</target>
</project>
and this stracture
How and where to gather library and property in Java file to jar-file was executable?

I figured it out.
<path id="classpath">
<fileset dir="${lib}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="init" depends="clean" description="starts">
<tstamp/>
</target>
<target name="clean" depends="package-to-jar" description="clean up">
<delete dir="${classes}"/>
<delete file="${external-lib}"/>
</target>
<target name="package-to-jar" depends="package-external-lib" description="packing all project into a jar-file">
<jar destfile="${jar}/${ant.project.name}.jar" basedir="${classes}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<zipfileset src="${external-lib}"/>
</jar>
<delete dir="${classes}"/>
<delete file="${external-lib}"/>
</target>
<target name="package-external-lib" depends="compile" description="packing external libraries into a jar-file">
<jar destfile="${external-lib}">
<zipgroupfileset dir="${lib}">
<include name="**/*.jar"/>
</zipgroupfileset>
</jar>
</target>
<target name="compile" description="compile the source">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}" classpathref="classpath"/>
<copy todir="${classes}">
<fileset dir="${src}" excludes="**/*.java"/>
</copy>
</target>

Firstly you need include required library folders to class path
<path id="class.path">
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</path>
and add reference to javac task in compile target
<target name="compile">
<mkdir dir="${classes}"/>
<javac srcdir="${src}" destdir="${classes}" includeAntRuntime="false">
<classpath refid="class.path" />
</javac>
</target>
aftewards include all properties file to jar
<target name="package" depends="compile">
<jar destfile="${build}/${ant.project.name}.jar" basedir="${classes}">
<include name="*.properties"/>
<manifest>
<attribute name="Main–Class" value="${ant.project.name}"/>
</manifest>
</jar>
</target>

Related

jar and manifest file is not created during ant build

I am new to Ant and just followed a tutorial on how to do this. My goal is to create a .jar with manifest. But during build, the .jar is not created inside the "lib" folder. There are no errors during build so I'm kinda lost.
here's what inside the build.xml:
<?xml version="1.0"?>
<project name="converter" default="main" basedir=".">
<property name="projectName" value="Converter" />
<property name="src.dir" value="src"/>
<property name="web.dir" value="war"/>
<property name="lib.dir" location="lib"/>
<property name="build.dir" value="${web.dir}/WEB-INF/classes"/>
<property name="name" value="converter"/>
<property name="main-class" value="com.ouc.mv90.conversion.CSVtoMV90Converter" />
<!-- external libraries classpath, we don't need sources and javadoc -->
<path id="classpath">
<fileset dir="${basedir}/">
<include name="${lib.dir}/*.jar" />
<exclude name="${lib.dir}/*sources.jar"/>
<exclude name="${lib.dir}/*javadoc.jar"/>
</fileset>
</path>
<path id="master-classpath">
<fileset dir="${web.dir}/WEB-INF/lib">
<include name="${lib.dir}/*.jar" />
<include name="*.jar"/>
</fileset>
<pathelement path="${build.dir}"/>
</path>
<target name="build" description="Compile source tree java files">
<mkdir dir="${build.dir}"/>
<javac destdir="${build.dir}" source="1.5" target="1.5">
<src path="${src.dir}"/>
<classpath refid="master-classpath"/>
</javac>
</target>
<target name="init">
<mkdir dir="${build.dir}" />
</target>
<target name="compile" depends="init" description="compile the source ">
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath" />
</target>
<target name="clean" description="Clean output directories">
<delete>
<fileset dir="${build.dir}">
<include name="**/*.class"/>
</fileset>
</delete>
</target>
<path id="master-classpath">
<fileset dir="${web.dir}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<pathelement path="${build.dir}"/>
</path>
<target name="jar" depends="compile" description="package, output to JAR">
<jar jarfile="${lib.dir}/${projectName}.jar" basedir="${build.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}" />
<attribute name="Class-Path" value="${classpath.name}" />
</manifest>
</jar>
</target>
<!-- Default, run this -->
<target name="main" depends="clean, compile, jar" />
</project>

Adding jar with Ant

My Eclipse project has the following structure:
-- | My project
|-src
|-build
|-doc
|-lib
In lib are placed my jar files. These files have been added to the Build path with "Add to Buildpath command". The project successfully compiles.
I want to build the project with Ant, to this aim I wrote the following xml file
<project name="ABTestConnector" basedir=".">
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="main-class" value="test.Prova"/>
<property name="lib.dir" value="/lib"/>
<property name="doc.dir" value="/doc"/>
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<path id="class-path">
<fileset dir="${lib.dir}">
<include name="*.jar" />
</fileset>
</path>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}">
<classpath refid="class-path"/>
</javac>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
<fileset dir="${classes.dir}" includes="**/*.class" />
<zipgroupfileset dir="${lib.dir}" includes="**/*.jar" />
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
</target>
<target name="clean-build" depends="clean,jar"/>
<target name="main" depends="clean,run"/>
<target name="doc" depends="clean-build" description="generate javadoc">
<javadoc sourcepath="${src.dir}" destdir="${doc.dir}"/>
</target>
I have also tried in the fileset: include name="**/*.jar"/>
But I still get the errors
[javac] /home/bruno/Documenti/TestingEnvironment/EclipseWorkspace/SeleniumABTestConnector_0.0.1/src/driversTod/TodSelenium.java:10: package org.openqa.selenium does not exist
[javac] import org.openqa.selenium.By;
Thank you in advance.

How to get rid of lib from classpath ANT TESTNG ECLIPSE

I am trying to configure the ANT for TEstNG but with problems
<project basedir="." default="build" name="Ant Play">
<property name="classes.dir" value="bin" />
<property name="report.dir" value="test-output" />
<path id="classpath">
<fileset dir=".">
<include name="**/*.jar"/>
</fileset>
<pathelement path="${basedir}\${classes.dir}"/>
</path>
<target name="init">
<mkdir dir="${classes.dir}"/>
<copy includeemptydirs="false" todir="${classes.dir}">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="${classes.dir}"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-project" name="build"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" includeantruntime="false" destdir="${classes.dir}">
<src path="src"/>
<classpath refid="classpath"/>
</javac>
</target>
<target depends="build" name="runTests" description="Running tests" >
<echo>Running Tests...</echo>
<taskdef resource="testngtasks" classpathref="classpath"/>
<testng outputDir="${report.dir}"
haltonfailure="true"
useDefaultListeners="false"
listeners="org.uncommons.reportng.HTMLReporter"
classpathref="classpath">
<xmlfileset dir="${basedir}" includes="testng.xml"/>
<!--<classfileset dir="${classes.dir}" includes="**/*.class" />-->
</testng>
</target>
</project>
But it refuse to get classpath
I get ................../.../.../lib does not exist.
I do not have lib in my project at all
How to change the classpath? And which folder it should be?
Thanks!
I found the solution
Created manually lib folder>>>Copied to lib all needed Jars>>> added these jars to path
and it worked

java build ant file with external jar files

I created an ant build file to compile my java src into a .jar file. It uses external jar files.
My files dir:
+src
----android
------------Address.java
------------HelloServer.java
------------HelloServerResource.java
+lib
------------org.codehaus.jackson.core.jar
------------org.codehaus.jackson.mapper.jar
------------org.json.jar
------------org.restlet.ext.jackson.jar
------------org.restlet.jar
build.xml
The external libraries are in lib folder.
The main class is in HelloServer.java
Here is my ant build file:
<project name="helloworld">
<property name="src-dir" location="src"/>
<property name="build-dir" location="build"/>
<property name="classes-dir" value="${build-dir}/classes"/>
<property name="dist-dir" location="dist"/>
<property name="lib-dir" value="lib"/>
<property name="jar-dir" value="${build-dir}/jar"/>
<property name="main-class" value="android.HelloServer"/>
<path id="classpath">
<fileset dir="${lib-dir}" includes="**/*.jar"/>
</path>
<target name="clean" description="compile the source">
<delete dir="${build-dir}" />
<delete dir="${dist-dir}" />
</target>
<target name="cleanall" depends="clean"/>
<target name="init">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build-dir}"/>
<mkdir dir="${classes-dir}"/>
<mkdir dir="${jar-dir}"/>
<!--<mkdir dir="${dist-dir}"/>-->
</target>
<target name="compile" depends="init" description="compile the source " >
<javac srcdir="${src-dir}" destdir="${classes-dir}" classpathref="classpath" includeantruntime="false" />
<!--<javac srcdir="${src-dir}" destdir="${build-dir}"/>-->
</target>
<target name="jar" depends="compile">
<jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java fork="true" classname="${main-class}">
<classpath>
<path refid="classpath"/>
<path location="${jar-dir}/${ant.project.name}.jar"/>
</classpath>
</java>
</target>
</project>
I execute run and all the dirs were created successfully, the .jar file was created and it was able to be executed.
I open terminal and go to the jar dir. I tried to execute through command line like this and it gave me the following error:
$java -jar helloworld.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/restlet/Server
at android.HelloServer.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.restlet.Server
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 1 more
Why does it say class file not found? I thought by creating the helloworld jar file, i actually included the external libraries.
You'll need to combine all the jars together using zipgroupfileset:
<target name="jar" depends="compile">
<jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
<zipgroupfileset dir="${lib-dir}" includes="*.jar"/>
</jar>
</target>
See: Creating a bundle jar with ant
i found a solution. basically i compile my jar file and point it to the external jar files using manifest file.
here is my build file:
<project name="helloworld">
<property name="src-dir" location="src"/>
<property name="build-dir" location="build"/>
<property name="classes-dir" value="${build-dir}/classes"/>
<property name="dist-dir" location="dist"/>
<property name="lib-dir" value="lib"/>
<property name="jar-dir" value="${build-dir}/jar"/>
<property name="main-class" value="android.HelloServer"/>
<path id="classpath">
<fileset dir="${lib-dir}" includes="**/*.jar"/>
</path>
<target name="clean" description="compile the source">
<delete dir="${build-dir}" />
<delete dir="${dist-dir}" />
</target>
<target name="cleanall" depends="clean"/>
<target name="init">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build-dir}"/>
<mkdir dir="${classes-dir}"/>
<mkdir dir="${jar-dir}"/>
<!--<mkdir dir="${dist-dir}"/>-->
</target>
<target name="compile" depends="init" description="compile the source " >
<javac srcdir="${src-dir}" destdir="${classes-dir}"
classpathref="classpath" includeantruntime="false" />
<!--<javac srcdir="${src-dir}" destdir="${build-dir}"/>-->
</target>
<target name="jar" depends="compile">
<manifestclasspath property="jar.classpath" jarfile="${jar-dir}/${ant.project.name}.jar">
<classpath refid="classpath"/>
</manifestclasspath>
<jar destfile="${jar-dir}/${ant.project.name}.jar" basedir="${classes-dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java fork="true" classname="${main-class}">
<classpath>
<path refid="classpath"/>
<path location="${jar-dir}/${ant.project.name}.jar"/>
</classpath>
</java>
</target>
</project>
The main difference is that i added the following into targer "jar":
<manifestclasspath property="jar.classpath" jarfile="${jar-dir}/${ant.project.name}.jar">
<classpath refid="classpath"/>
</manifestclasspath>
<attribute name="Class-Path" value="${jar.classpath}"/>

How do I run JUnit tests during my Ant build script while omitting test classes from my resulting jar?

I'm using the Hello World with Ant tutorial from the Ant manual to learn about Ant.
The last part of the tutorial involves adding JUnit tests to the project.
I've got everything working as described in the tutorial and am now going on to make some minor changes.
One of the changes I would like to make is to run the tests during a typical build but not have the *Test.class files end up in the final .jar file for the application. This is because the eventual project I will be working on will be for a device with limited hard drive space and support for only a subset of the Java SDK so I would prefer to just omit these test files entirely from the jar.
How do I do this?
It would be easy enough to create two separate jars, one for testing and one for deployment, but this seems less than ideal.
My current build.xml file is below.
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="lib.dir" value="lib"/>
<property name="report.dir" value="${build.dir}/junitreport"/>
<property name="main-class" value="oata.HelloWorld"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
<path location="[LocalPath]/junit-4.8.2.jar"/>
</path>
<path id="application" location="${jar.dir}/${ant.project.name}.jar"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}" excludes="**/*.java"/>
</copy>
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="junit" depends="jar">
<mkdir dir="${report.dir}"/>
<junit printsummary="yes" haltonfailure="yes" showoutput="yes">
<classpath>
<path refid="classpath"/>
<path refid="application"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes">
<fileset dir="${src.dir}" includes="*Test.java"/>
</batchtest>
</junit>
</target>
<target name="junitreport" depends="junit">
<junitreport todir="${report.dir}">
<fileset dir="${report.dir}" includes="TEST-*.xml"/>
<report todir="${report.dir}"/>
</junitreport>
</target>
<target name="run" depends="junit">
<java fork="true" classname="${main-class}">
<classpath>
<path refid="classpath"/>
<path refid="application"/>
</classpath>
</java>
</target>
<target name="clean-build" depends="clean,junit"/>
<target name="main" depends="clean,run"/>
One thing I have tried is modifying the jar command to exclude the *Test.class files
...
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" excludes="**/*Test.class">
...
which successfully excludes the test classes but then when the tests are run via the junit target it fails with the following stack trace when run with -v:
[LocalPath]\build.xml:44: Test HelloWorldTest failed
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.actOnTestResult(JUnitTask.java:1863)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:814)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.executeOrQueue(JUnitTask.java:1808)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTask.execute(JUnitTask.java:760)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:390)
at org.apache.tools.ant.Target.performTasks(Target.java:411)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1397)
at org.apache.tools.ant.Project.executeTarget(Project.java:1366)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1249)
at org.apache.tools.ant.Main.runBuild(Main.java:801)
at org.apache.tools.ant.Main.startAnt(Main.java:218)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Can you change:
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
to:
<target name="jar" depends="junit">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar">
<fileset dir="${classes.dir}" excludes="**/*Test.class"/>
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="junit" depends="compile">
<mkdir dir="${report.dir}"/>
<junit printsummary="yes" haltonfailure="yes" showoutput="yes">
<classpath>
<path refid="classpath"/>
<path refid="application"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes">
<fileset dir="${src.dir}" includes="*Test.java"/>
</batchtest>
</junit>
</target>
That should exclude the Test classes I believe from the final JAR file.
n.b The change in dependencies for each of the tasks.
Based on #Jon's advice I changed the junit target to run against the build/classes folder instead of the jar and updated the dependencies appropriately.
My updated build.xml file is below:
<project name="HelloWorld" basedir="." default="main">
<property name="src.dir" value="src"/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="jar.dir" value="${build.dir}/jar"/>
<property name="lib.dir" value="lib"/>
<property name="report.dir" value="${build.dir}/junitreport"/>
<property name="main-class" value="oata.HelloWorld"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
<path location="[LocalPath]/junit-4.8.2.jar"/>
</path>
<path id="application" location="${jar.dir}/${ant.project.name}.jar"/>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}" excludes="**/*.java"/>
</copy>
</target>
<target name="jar" depends="junit">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" excludes="**/*Test.class">
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
</manifest>
</jar>
</target>
<target name="junit" depends="compile">
<mkdir dir="${report.dir}"/>
<junit printsummary="yes" haltonfailure="yes" showoutput="yes">
<classpath>
<path refid="classpath"/>
<path location="${classes.dir}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes">
<fileset dir="${src.dir}" includes="*Test.java"/>
</batchtest>
</junit>
</target>
<target name="junitreport" depends="junit">
<junitreport todir="${report.dir}">
<fileset dir="${report.dir}" includes="TEST-*.xml"/>
<report todir="${report.dir}"/>
</junitreport>
</target>
<target name="run" depends="jar">
<java fork="true" classname="${main-class}">
<classpath>
<path refid="classpath"/>
<path refid="application"/>
</classpath>
</java>
</target>
<target name="clean-build" depends="clean,jar"/>
<target name="main" depends="clean,run"/>
</project>

Categories