Ant gets stuck while building runnable jar - java

it's me again.
I've been trying to create java project into a runnable jar using ant script.
This is my build.xml
<project name="simple-app" 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="main-class" value="app.App" />
<path id="classpath">
<fileset dir="${lib.dir}">
<include name="*.jar" />
</fileset>
<dirset dir="${build.dir}">
<include name="classes"/>
</dirset>
</path>
<target name="clean">
<delete dir="${build.dir}" />
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac source="1.7" target="1.7" includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" />
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}" />
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}" includes="*.class">
<manifest>
<attribute name="Main-Class" value="${main-class}" />
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java classname="${main-class}">
<classpath>
<path refid="classpath" />
<path location="${jar.dir}/${ant.project.name}.jar" />
</classpath>
</java>
</target>
<target name="main" depends="clean,run"/>
</project>
All goes well, but when it gets to "run" it gets stuck. Terminal says run: and nothing happens. Waited for 30 minutes, nothing. I tried many other options I found around the internet but those resulted either in the same lag, or threw ClassNotFoundException.
I seriously don't know what, to do. When I make the file with Eclipse, all works fine. Anyone can help me? It's propably something totally stupid, but I just don't see it.
Thank you very much.

To fix the ClassNotFoundException exception you need to include the classpath in the jar's manifest. The manifestclasspath task comes in very useful:
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}" />
<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}" includes="*.class">
<manifest>
<attribute name="Main-Class" value="${main-class}" />
<attribute name="Class-Path" value="${jar-classpath}" />
</manifest>
</jar>
</target>
This enables you to invoke the jar as follows:
<java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
or from the command-line:
java -jar /path/to/myproject.jar
In the end this may not explain why your build is hanging.... Is it possible the code is going into a waiting state?

Related

Javadoc task in Ant build fails

I'm receiving an error message from Ant when I try to run the Javadoc ant task.
"BUILD FAILED
/data/data/com.termux/files/home/LearnJava/Observer/build.xml:39: No source files, no packages and no modules have been specified."
The build files reside at:
https://github.com/Fernal73/LearnJava/blob/master/Observer/build.properties
version=1.0.0
main.class=com.javacodegeeks.patterns.observerpattern.TestObserver
main.class1=com.javacodegeeks.patterns.observerpattern.Test
cs.properties=../checkstyle.properties
gformat.properties=../gformat.properties
ant.build.javac.source=1.7
ant.build.javac.target=1.7
packages=com.javacodegeeks.patterns.observerpatern.*
and
https://github.com/Fernal73/LearnJava/blob/master/Observer/build.xml
<?xml version="1.0"?>
<project name="Observer" default="main"
basedir=".">
<property file = "build.properties"/>
<property file = "${cs.properties}"/>
<property file = "${gformat.properties}"/>
<!-- Sets variables which can later be used. -->
<!-- The value of a property is accessed via ${} -->
<property name="src.dir" location="." />
<property name="build.dir" location="." />
<property name="dist.dir" location="dist" />
<property name="docs.dir" location="docs" />
<taskdef resource="${cs.taskdef.resource}"
classpath="../${cs.jar}"/>
<!-- Deletes the existing build, docs and dist directory-->
<target name="clean">
<delete>
<fileset dir="." includes="**/*.class"/>
</delete>
<delete dir="${docs.dir}" />
<delete dir="${dist.dir}" />
</target>
<!-- Creates the build, docs and dist directory-->
<target name="makedir">
<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,gformat,checkstyle">
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${build.dir}">
<compilerarg value="-Xlint:-options"/>
</javac>
</target>
<!-- Creates Javadoc -->
<target name="docs" depends="compile">
<javadoc packagenames="${packages}" additionalparam="-Xdoclint:none"
sourcepath="${src.dir}"
destdir="${docs.dir}">
<!-- Define which files / directory should get included, we include all -->
<fileset dir="${src.dir}">
<include name="*.java" />
</fileset>
</javadoc>
</target>
<target name="manifest">
<tstamp/>
<manifest file="manifest.mf">
<attribute name="Built-By" value="${user.name}"/>
<section name="common">
<attribute name="Specification-Title" value="${ant.project.name}"/>
<attribute name="Specification-Version" value="${version}"/>
<attribute name="Specification-Vendor" value=""/>
<attribute name="Implementation-Title" value=""/>
<attribute name="Implementation-Version" value="${build} ${TODAY}"/>
<attribute name="Implementation-Vendor" value=""/>
</section>
<attribute name="Main-Class" value="${main.class}" />
</manifest>
</target>
<!--Creates the deployable jar file -->
<target name="jar" depends="compile,manifest">
<jar destfile="${dist.dir}\${ant.project.name}.jar" basedir="${build.dir}" includes="**/*.class"
manifest="manifest.mf">
</jar>
</target>
<target name="run" >
<description>Run target</description>
<java classname="${main.class}">
<classpath>
<pathelement location="${dist.dir}\${ant.project.name}.jar"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
</target>
<target name="gformat">
<exec executable="find" dir="${basedir}"
failonerror="true" outputproperty="sources">
<arg line=" . -type f -name '*.java'"/>
</exec>
<echo message="About to format ...: ${sources}"/>
<java classname="${gformat.main.class}">
<arg line=" -i ${sources}"/>
<classpath>
<pathelement location="../${gformat.jar}"/>
<pathelement path="${java.class.path}"/>
</classpath>
</java>
</target>
<target name="checkstyle">
<first id="checkstylefile">
<fileset dir=".." includes="${cs.config}"/>
</first>
<checkstyle config="${toString:checkstylefile}"
classpath="../${cs.jar}"
failOnViolation="false" properties="${cs.properties}">
<fileset dir="${src.dir}" includes="**/*.java"/>
<formatter type="plain"/>
<formatter type="plain" toFile="${cs.output}"/>
</checkstyle>
</target>
<target name="main" depends="compile, jar, docs">
<description>Main target</description>
</target>
</project>
respectively.
My other projects on the repository have similar configurations.
They work as expected.
Am I missing something obvious?
I did miss something obvious. An extra 't' in the property packages. Evidently, I'm going to need two sets of eyes for this or a fresh set, a few hours later!
NOW, how do I close this?
I think the problem is in following part:
<fileset dir="${src.dir}">
<include name="*.java" />
</fileset>
In Ant "*.java" means all files with names matching *.java. This does not search in subdirectories.
To include all subdirectories you must specify:
<fileset dir="${src.dir}">
<include name="**/*.java" />
</fileset>
But since you already specified the sourcePath attribute I'm wondering if you can't just remove the fileset element as ant will add **/*.java by default.

Configuration required for ant xml to build correct jar using java 1.8.0_40 and ant 1.9.0

I am trying to build jar for my project using jdk 1.8.0_40 and ant version 1.9.0, jar is getting build but while converting this jar to .exe, it is not able to find main class as I have correctly mentioned my main class.I am using eclipse Mar Version: Mars.2 Release (4.5.2).
Earlier I was using jdk 1.7.0_79 version and ant 1.8.4 and everything was working fine.
I am facing issue while upgrading from jdk 1.7.0_79 to jdk 1.8.0_40.
Below is my ant xml which are using to build my jar.Let me know if any configuration is required for java 1.8 to build proper jar.
<property name="jar.name" value="SAFAL.jar" />
<property name="source.root" value="src" />
<property name="class.root" value="bin" />
<property name="lib.dir" value="lib" />
<property name="jar.dir" value="C:\D\SAFAL-Exe" />
<property name="Main-Class" value="com.sungard.ktt.main.SAFALEval" />
<property name="conf.pkj" value="com/sungard/ktt/business/configurations" />
<property name="img.pkj" value="com/sungard/ktt/business/images" />
<path id="project.class.path">
<pathelement location="${class.root}" />
<fileset dir="${lib.dir}">
<include name="*.jar" />
</fileset>
</path>
<target name="clean" description="cleans up build structures">
<delete dir="${class.root}" />
<delete file="${jar.dir}/${jar.name}" />
</target>
<target name="prepare" description="sets up build structures">
<mkdir dir="${class.root}" />
</target>
<target name="compile" depends="prepare" description="Compiles all java classes">
<javac srcdir="${source.root}" destdir="${class.root}" debug="on" optimize="off" deprecation="on" source="1.8" target="1.8" includeantruntime = "false">
<classpath refid="project.class.path" />
</javac>
<mkdir dir="${class.root}/${conf.pkj}" />
<mkdir dir="${class.root}/${img.pkj}" />
<copy todir="${class.root}/${conf.pkj}">
<fileset dir="${source.root}/${conf.pkj}" />
</copy>
<copy todir="${class.root}/${img.pkj}">
<fileset dir="${source.root}/${img.pkj}" />
</copy>
</target>
<target name="jar" depends="compile">
<delete file="${jar.dir}/${jar.name}" quiet="true" failonerror="false" />
<jar destfile="${jar.dir}/${jar.name}">
<fileset dir="${class.root}" includes="**/*.*" />
<fileset dir="${source.root}" includes="**/api/*.java,**/api/vo/*.java"/>
<zipgroupfileset dir="${lib.dir}" />
<manifest>
<attribute name="Main-Class" value="${Main-Class}" />
<attribute name="Class-Path" value="." />
</manifest>
</jar>
</target>
<target name="run">
<java fork="true" classname="${Main-Class}">
<classpath>
<path location="./${jar.name}" />
</classpath>
</java>
</target>
In your java task you are using ./${jar.name} as the location of your jar - this is relying on the current directory being set correctly. All the rest of your code uses ${jar.dir}/${jar.name} as the path for the jar, so change the java task to do the same:
<target name="run">
<java fork="true" classname="${Main-Class}">
<classpath>
<path location="${jar.dir}/${jar.name}" />
</classpath>
</java>
</target>

Error creating jar archive contains more than 65535 entries

I am trying to build a jar file and getting error Build Failed.
Problem creating jar: archive contains more than 65535 entries. (and the archive is probably corrupt but I could not delete it)
I am using Eclipse Neon Release 1 with JDK 1.8.0_101 and Ant version in eclipse is 1.9.6.
below is my ant build file :-
<property name="jar.name" value="ABC.jar" />
<property name="source.root" value="src" />
<property name="class.root" value="bin" />
<property name="lib.dir" value="lib" />
<property name="jar.dir" value="C:\D\ABC-Exe" />
<property name="Main-Class" value="com.abc.xxx.main.ABCEval" />
<property name="conf.pkj" value="com/abc/xxx/business/configurations" />
<property name="img.pkj" value="com/abc/xxx/business/images" />
<path id="project.class.path">
<pathelement location="${class.root}" />
<fileset dir="${lib.dir}">
<include name="*.jar" />
</fileset>
</path>
<target name="clean" description="cleans up build structures">
<delete dir="${class.root}" />
<delete file="${jar.dir}/${jar.name}" />
</target>
<target name="prepare" description="sets up build structures">
<mkdir dir="${class.root}" />
</target>
<target name="compile" depends="prepare" description="Compiles all java classes">
<javac srcdir="${source.root}" destdir="${class.root}" debug="on" optimize="off" deprecation="on" source="1.8" target="1.8" includeantruntime = "false">
<classpath refid="project.class.path" />
</javac>
<mkdir dir="${class.root}/${conf.pkj}" />
<mkdir dir="${class.root}/${imwg.pkj}" />
<copy todir="${class.root}/${conf.pkj}">
<fileset dir="${source.root}/${conf.pkj}" />
</copy>
<copy todir="${class.root}/${img.pkj}">
<fileset dir="${source.root}/${img.pkj}" />
</copy>
</target>
<target name="jar" depends="compile">
<delete file="${jar.dir}/${jar.name}" quiet="true" failonerror="false" />
<jar destfile="${jar.dir}/${jar.name}">
<fileset dir="${class.root}" includes="**/*.*" />
<fileset dir="${source.root}" includes="**/api/*.java,**/api/vo/*.java"/>
<zipgroupfileset dir="${lib.dir}" />
<manifest>
<attribute name="Main-Class" value="${Main-Class}" />
<attribute name="Class-Path" value="." />
</manifest>
</jar>
</target>
<target name="run">
<java fork="true" classname="${Main-Class}">
<classpath>
<path location="./${jar.name}" />
</classpath>
</java>
</target>
Specify the zip64Mode argument on your jar task to say that you need to use the large 'zip64' format:
<jar destfile="${jar.dir}/${jar.name}" zip64Mode="always">

My jar file built with ant doesn't run when double click

I've been trying to follow this tutorial over at http://ant.apache.org/manual/tutorial-HelloWorldWithAnt.html.
I've got to the part entitled using external libraries, and I was trying to use the log4j2 libraries. When I do ant clean and ant compile jar run in terminal, it launches just fine, however, if I go to the the build/jar folder in my filesystem and double click the jar file, it doesn't open.
Currently, my build file looks like this:
<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="main-class" value="hlw.HelloWorld"/>
<property name="lib.dir" value="lib"/>
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false"/>
<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}"/>
<attribute name="Class-Path" value="config/ properties/ ${manifest.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>
<target name="clean-build" depends="clean,jar"/>
<target name="main" depends="clean,run"/>
<target name="test" depends="jar">
<junit printsummary="yes">
<classpath>
<path refid="classpath"/>
<path refid="application"/>
</classpath>
<batchtest fork="yes">
<fileset dir="${src.dir}" includes="*Test.java"/>
</batchtest>
</junit>
</target>
Is there something wrong with this build file that prevents the jar from working when being double clicked?
Edit: when typing jar -jar HelloWorld.jar in Terminal I get the following response:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at hlw.HelloWorld.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
When running your application from ant, you explicitly add jars from lib/ directory to your class-path. When running the jar directly, java has no way of knowing where those jars are.
The simplest way to fix this is to bundle all those dependencies inside single jar:
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}"/>
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<zipgroupfileset dir="${lib.dir}" includes="**/*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main-class}"/>
<attribute name="Class-Path" value="config/ properties/ ${manifest.classpath}" />
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java fork="true" jar="${jar.dir}/${ant.project.name}.jar" />
</target>
If you don't want to repackage those libraries, you can add paths to them in your manifest:
https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html

ant: the generated JAR cannot be executed

I've written/copied a simple ant example and am trying to deploy a Java progamm with it. My build file bsp0201.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="bsp0201" default="main" basedir=".">
<property name="dir.src" value="./source" />
<property name="dir.build" value="./classes" />
<property name="dir.lib" value="./lib" />
<path id="cp">
<pathelement path="${classpath}" />
<pathelement location="${dir.build}" />
</path>
<target name="main" depends="prepare, compile, run" />
<target name="prepare">
<mkdir dir="${dir.build}" />
<delete>
<fileset dir="${dir.build}" includes="**/*" />
</delete>
</target>
<target name="compile">
<javac classpathref="cp" destdir="${dir.build}" srcdir="${dir.src}" includes="**/*.java" includeantruntime="false" />
<mkdir dir="${dir.lib}" />
<jar destfile="${dir.lib}/ae.jar">
<fileset dir="${dir.build}" includes="**/*.class" />
</jar>
</target>
<target name="run" if="test">
<java classname="main.GeoAnalyzerMain" classpath="${dir.lib}/ae.jar">
<arg line="${test}" />
</java>
</target>
</project>
My ant commando & the result output:
# ant -f bsp0201.xml run -Dtest=Echo
Buildfile: /var/www/sandbox/ant/bsp0201/bsp0201.xml
run:
BUILD SUCCESSFUL
Total time: 1 second
Ant generates the folders, the class files and a JAR file ae.jar. But the size of this JAR file is only 19.1 KB (instead of 297 KB of the JAR file, when I generate it with eclipse) and I cannot execute it. What do I do wrong?
Thx
Yes, was a good idea to compare the JARs. :) Here you can see the comparsion result:
The folder /img and the /.classpath are missing in the Ant-JAR. Why has Ant not included them? How can I make Ant to include the missing files/folders?
I edited the build XML:
<?xml version="1.0" encoding="UTF-8" ?>
<project name="bsp0201" default="main" basedir=".">
<property name="dir.src" value="./source" />
<property name="dir.build" value="./classes" />
<property name="dir.lib" value="./lib" />
<path id="cp">
<pathelement path="${classpath}" />
<pathelement location="${dir.build}" />
</path>
<target name="main" depends="prepare, compile, run" />
<target name="prepare">
<mkdir dir="${dir.build}" />
<delete>
<fileset dir="${dir.build}" includes="**/*" />
</delete>
</target>
<target name="compile">
<javac classpathref="cp" destdir="${dir.build}" srcdir="${dir.src}" includes="**/*.java" includeantruntime="false" />
<mkdir dir="${dir.lib}" />
<jar destfile="${dir.lib}/AntExample.jar">
<fileset dir="${dir.build}" includes="**/*.class" />
<fileset dir=".">
<include name="img/*.*" />
</fileset>
</jar>
</target>
<target name="run" if="test">
<java classname="main.GeoAnalyzerMain" classpath="${dir.lib}/AntExample.jar">
<arg line="${test}" />
</java>
</target>
</project>
Now the image folder is copied into the result archive. But the JAR still cannot be executed.
EDIT:
It works!
<?xml version="1.0" encoding="UTF-8" ?>
<project name="bsp0201" default="main" basedir=".">
<property name="dir.src" value="./source" />
<property name="dir.build" value="./classes" />
<property name="dir.lib" value="./lib" />
<path id="cp">
<pathelement path="${classpath}" />
<pathelement location="${dir.build}" />
</path>
<target name="main" depends="prepare, compile, run" />
<target name="prepare">
<mkdir dir="${dir.build}" />
<delete>
<fileset dir="${dir.build}" includes="**/*" />
</delete>
</target>
<target name="compile">
<javac classpathref="cp" destdir="${dir.build}" srcdir="${dir.src}" includes="**/*.java" includeantruntime="false" />
<mkdir dir="${dir.lib}" />
<jar destfile="${dir.lib}/AntExample.jar">
<fileset dir="${dir.build}" includes="**/*.class" />
<fileset dir=".">
<include name="img/*.*" />
</fileset>
<manifest>
<attribute name="Main-Class" value="main.GeoAnalyzerMain" />
</manifest>
</jar>
</target>
<target name="run" if="test">
<java classname="main.GeoAnalyzerMain" classpath="${dir.lib}/AntExample.jar">
<arg line="${test}" />
</java>
</target>
</project>

Categories