Eclipse Ant Builder problem - java

I made a custom ant script to automatically create a jar file each time I do a build.
This is how it looks like:
<?xml version="1.0" encoding="UTF-8"?>
<project name="TestProj" basedir="." default="jar">
<property name="dist" value="dist" />
<property name="build" value="bin/test/testproj" />
<target name="jar">
<jar destfile="${dist}/TestProj.jar">
<manifest>
<attribute name="Main-Class" value="test.testproj.TestProj" />
</manifest>
<fileset dir="${build}" />
</jar>
</target>
</project>
I added it by Right clicking my project > properties > builders > clicked new > Ant builder > then I specified the location of the above xml file.
However, when I run it by doing:
java -jar TestProj.jar
I get a NoClassDefFoundError test/testproj/TestProj
I'm using Eclipse in Ubuntu. TestProj is the name of the class and it's in package test.testproj
I'm pretty sure there's something wrong with the manifest and probably the location of the xml file as well but I'm not sure how to fix this. Any ideas?

Did you try with:
<property name="build" value="bin" /> <!-- instead of bin/test/testproj -->
<target name="jar">
<jar destfile="${dist}/TestProj.jar">
<manifest>
<attribute name="Main-Class" value="test.testproj.TestProj" />
</manifest>
<fileset dir="${build}" />
</jar>
</target>
just to see if it solves the issue?
The Ant Task mentions:
This task forms an implicit FileSet and supports most attributes of <fileset> (dir becomes basedir)
That means you are trying to jar any class within the root bin/test/testproj (so TestProj get included), instead of referencing all classes within root bin (which would include test.testproj.TestProj)

Related

Setting up class path in ANT build

Situation:
I am new to making ant builds and I have managed to write one that builds the JAR and moves necessary files (Such as images and libraries) into an output folder.
Problem:
When I try to run the new JAR it complains that it cant find the main method (I have it specified in the manifest tag in the ANT script). I have done some research and I think its because I need to define a class-path for the compiled class' to go to but I haven't been able to get it working.
build.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project name="formula_manager" default="rebuild">
<property name="out" value="${basedir}/out/FormulaManager"/>
<target name="clean">
<delete dir="${out}"/>
<mkdir dir="${out}"/>
</target>
<target name="build" description="Build all artifacts">
<property name="tmp" value="${out}/temp"/>
<mkdir dir="${tmp}"/>
<property name="tmpJar" value="${tmp}/Formula Manager.jar"/>
<property name="tmpFolder" value="${tmp}/FormulaManager"/>
<jar destfile="${tmpJar}" duplicate="preserve" filesetmanifest="mergewithoutmain">
<zipfileset dir="${out}"/>
<zipfileset src="${basedir}/resources/pdfbox-app-1.8.10.jar"/>
<zipfileset src="${basedir}/resources/ftp4j-1.7.2.jar"/>
<manifest>
<attribute name="Main-Class" value="com.zakscode.FormulaManager.Main"/>
</manifest>
</jar>
<copy file="${tmpJar}" tofile="${tmp}/Formula Manager.jar"/>
<mkdir dir="${out}"/>
<copy todir="${out}">
<fileset dir="${tmp}"/>
</copy>
<copy file="icon.png" todir="${out}" />
<copy file="splash.png" todir="${out}" />
<copy file="logo.png" todir="${out}" />
<copy file="configuration.properties" todir="${out}" />
<mkdir dir="${out}/resources" />
<copydir src="resources" dest="${out}/resources" />
<!-- Delete temporary files -->
<delete dir="${tmp}"/>
</target>
<target name="rebuild" depends="clean, build"/>
</project>
Output:
$ java -jar "Formula Manager.jar"
Error: Could not find or load main class com.zakscode.FormulaManager.Main
Edit:
I opened up the JAR in 7zip and none of the class files are there which is why the main method cant be loaded. So how do I fix this in my build.xml?
Setting
Main-Class = "com.zakscode.FormulaManager.Main"
assumes that you have the following message defined:
public static void main(String[] args)
in a class named com.zakscode.FormulaManager.Main (method has to be "main", not "Main"). When defining Main-Class, you don't include the main method name, you specify the class that contains main, so if your main method is in FormulaManager, then you set Main-Class as follows:
Main-Class = "com.zakscode.FormulaManager"

Deployed jar can't find the main class while using Apache Ant

I built a jar file using the following build.xml below:
<project name="sampleproject">
<!--Source Directory-->
<property name="src.dir" value="src" />
<property name="deploy.name" value="samplejar.jar" />
<property name="lib.dir" value="./lib" />
<property name="deploy.dir" value="target" />
<property name="compile.dir" value="target/classes" />
<!--Define directory name for third party libraries-->
<property name="jar-all" location="${lib.dir}" />
<!--Fileset is a group of files, here **/* matches all jar files across all directory levels-->
<fileset id="jars" dir="${jar-all}">
</fileset>
<!--Setting the classpath-->
<path id="classpath">
<fileset refid="jars" />
<pathelement location="." />
<pathelement location="${src.dir}" />
<pathelement location="${compile.dir}" />
</path>
<path id="cp">
<fileset refid="jars" />
</path>
<pathconvert property="classpath.path" refid="cp" pathsep=" " dirsep="/">
<map from="${jar-all}" to="lib" />
</pathconvert>
<echo>${classpath}</echo>
<!--Clean-->
<target name="clean">
<delete dir="${deploy.dir}" />
</target>
<!--Jar-->
<target name="jar" depends="compile">
<jar destfile="${deploy.dir}/${deploy.name}.jar" basedir="${compile.dir}">
<manifest>
<attribute name="Main-Class" value="main.java.Main" />
<attribute name="Class-Path" value="${classpath.path}" />
</manifest>
<include name="${src.dir}/META-INF/persistence.xml" />
<restrict>
<not>
<or>
<name name="**/*.RSA" />
<name name="**/*.SF" />
<name name="**/*.DSA" />
</or>
</not>
<archives>
<zips>
<fileset dir="lib" includes="**/*.jar" />
</zips>
</archives>
</restrict>
</jar>
</target>
<!--Compile-->
<target name="compile">
<mkdir dir="${compile.dir}" />
<javac includeantruntime="false" srcdir="${src.dir}" destdir="${compile.dir}">
<classpath refid="classpath" />
</javac>
</target>
</project>
My folder structure is like this:
.
./.settings
./bin
./bin/main
./bin/main/java
./bin/META-INF
./lib
./lib/aws
./lib/hibernate
./src
./src/main
./src/main/java
./src/META-INF
./target
./target/classes
./target/classes/main
./target/classes/main/java
My MANIFEST.MF
Created-By: 1.8.0_45-b14 (Oracle Corporation)
Built-Date: ${TODAY}
Main-Class: main.java.Main
Class-Path: lib/activation.jar lib/aws/aws-java-sdk-1.3.2.jar lib/aws/
httpclient-4.1.1.jar lib/aws/httpcore-4.4.1.jar lib/aws/mail-1.4.3.ja
r lib/aws/stax-1.2.0.jar lib/aws/stax-api-1.0.1.jar lib/commons-beanu
tils-1.8.3.jar lib/commons-codec-1.4.jar lib/commons-configuration-1.
8.jar lib/commons-httpclient-3.0.1.jar lib/commons-io-2.1.jar lib/com
mons-lang-2.4.jar lib/commons-logging-1.1.1.jar lib/hibernate/antlr-2
.7.7.jar lib/hibernate/c3p0-0.9.1.jar lib/hibernate/commons-collectio
ns-3.2.1.jar lib/hibernate/dom4j-1.6.1.jar lib/hibernate/hibernate-c3
p0-4.0.1.Final.jar lib/hibernate/hibernate-commons-annotations-4.0.1.
Final.jar lib/hibernate/hibernate-core-4.0.1.Final.jar lib/hibernate/
hibernate-entitymanager-4.0.1.Final.jar lib/hibernate/hibernate-jpa-2
.0-api-1.0.1.Final.jar lib/hibernate/javassist-3.15.0-GA.jar lib/hibe
rnate/jboss-logging-3.1.0.CR2.jar lib/hibernate/jboss-transaction-api
_1.1_spec-1.0.0.Final.jar lib/jackson-all-1.9.5.jar lib/log4j-1.2.16.
jar lib/mail.jar lib/mongo-2.8.0.jar lib/morphia-0.99.jar lib/mysql-c
onnector-java-5.1.12-bin.jar lib/mysql-connector-java-5.1.25-bin.jar
lib/org.json.jar lib/ymmi-utilities-2.0.jar
Whenever I run the jar produced it gives me, Error: Could not find or load main class main.java.Main.
Also, I want to include lib folder & it's subfolders as well since it contains the libraries required to run the jar.
Before it gave me, No Persistence provider for EntityManager named but I solved that by using <include name="${src.dir}/META-INF/persistence.xml" />. Any where I am might wrong?
Your problem is the <include> element in the jar task.
I executed your script and the Main.class file is not added to the jar.
Replace the
<include
by
<fileset dir="${src.dir}" includes="META-INF/persistence.xml" />
This way it will still add all files located in your ${compile.dir}.
Are you new to java ? Normally you put your source files in src/main/java and resources in src/main/resources.
These folders are the root folder of your classpath meaning: If your project classes would be in package org.myproject, than you would put the Main.java file in src/main/java/org/myproject/Main.java
In your build script you than set the property "src.dir" to "src/main/java".
With all resources (=files which do not need to be compiled but must be available in the jar) in src/main/resources the fileset element in the jar task could just be:
<fileset dir="scr/main/resources"/>
This way all resource files you plan to add to your project will automatically added to your jar.
Why do I tell you this ? If one day you would think of using maven instead of ant, maven expects the sources to be in src/main/java and resources in src/main/resources. (https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)
Regarding you other dependant jars:
Now you include all jars twice: you add the content of them using the <archives> element within the jar and you define them in the Class-Path attribute of the manifest.mf file.
If you really like to build a single jar containing all dependant files, you don't need to specify the manifest attribute Class-Path.
If you want your jar file containing only your files and deliver the dependant jars separately: remove the <archives> element within the jar task.

Netbeans 7: Why is my edited manifest not being included?

I have the following target in my build.xml:
<target name="-pre-compile">
<property file="build.properties"/>
<buildnumber file="build.version"/>
<tstamp>
<format property="timestamp" pattern="yyyy-MM-dd HH:mm:ss"/>
</tstamp>
<manifest file="manifest.mf">
<attribute name="MAJOR" value="${version.major}"/>
<attribute name="MINOR" value="${version.minor}"/>
<attribute name="RELEASE" value="${release}"/>
<attribute name="BUILD" value="${build.number}"/>
<attribute name="BUILD-DATE" value="${timestamp}"/>
<attribute name="PROTOCOL" value="${protocol}"/>
<attribute name="APPCODE" value="${appcode}"/>
</manifest>
</target>
It works fine, opening manifest.mf after a Clean and Build within Netbeans shows all my extra attributes that I've added. However, when I open my jar file I see that it just contains the default stuff:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0-b147 (Oracle Corporation)
I had this working fine before when I had two packages in one project. The one package was all library stuff that I'm gonna be taking to other projects, so I decided to split it out into another project so I could build the library jar by itself. Now I have this problem. It occurs both when I compile the library on its own as well as my other project that depends on it.
I've fixed it by opening nbproject/project.properties and adding manifest.file=manifest.mf to the end. Simple as that.
check this answer here: Is it possible to add a custom manifest to a Java library compiled in Netbeans 6.7.1?
I had your same problem, adding this at the end of my build.xml solved the issue:
<target name="-post-jar">
<jar destfile="${dist.jar}" update="true">
<manifest>
<attribute name="Manifest-Version" value="1.0" />
<attribute name="Extension-Name" value="polpol" />
<attribute name="Class-Manager" value="org.nlogo.extensions.polpol.Manager" />
<attribute name="NetLogo-Extension-API-Version" value="5.0" />
</manifest>
</jar>
</target>
I happen to have encountered the same issues youre having here, and luckly enough have fixed it. Unfortunately I dont know what exactly caused the issue, and after comparing your code to mine, the only difference I see really is the name of the manifest file in your build.xml, and the event which triggers the task (I used pre init). I have all in capitals, and supplement the manifest version info with in the Version.txt file which is created in the dist directory -post-jar. You may just want to try to make
manifest file="manifest.mf"
read
manifest file="MANIFEST.MF"
Here is a copy of the important parts of my build.xml:
<property name="project.name" value="VOXManagement" />
<property name="version.num" value="1.1" />
<target name="-pre-init">
<tstamp>
<format property="NOW" pattern="yyyy-MM-dd HH:mm:ss z" />
</tstamp>
<manifest file="MANIFEST.MF">
<attribute name="Bundle-Name" value="${project.name}" />
<attribute name="Bundle-Version" value="${version.num}" />
<attribute name="Bundle-Date" value="${NOW}" />
<!--<attribute name="Bundle-Revision" value="${svna.version}" />-->
<attribute name="Implementation-Title" value="${project.name}" />
<attribute name="Implementation-Version" value="${version.num}" />
</manifest>
<echo file="Version.txt">V${version.num}</echo>
</target>
<target name="-post-jar">
<copy file="Version.txt" todir="dist" overwrite="true"/>
<delete file="dist/README.TXT"/>
</target>
You need to use the "update mode".
<manifest file="${manifest.file}" mode="update">
As Thihara already asked, you may have a task that builds the jar?
are you having manifest="MANIFEST.MF" in your create jar(or something similary ) tag/task?
<target name="jar">
<jar manifest="path-to/MANIFEST.MF" basedir="base dir" destfile="outJarfileName">
</jar>
</target>
While Creating Jars,Wars,Ears a common issue in MANIFEST.MF is
"Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: 1.7.0_40-b43 (Oracle Corporation)"
If you want to Ignore Ant-Version Number and Created by use filesetmanifest="mergewithoutmain" option.
<jar destfile="MyJar.jar" basedir="./bin" filesetmanifest="mergewithoutmain" manifest="./src/META-INF/MANIFEST.MF" update="true" >
In Netbeans 7.3.X
for .war
in the build.xml Use
<manifest file="${build.web.dir}/META-INF/MANIFEST.MF">...</manifest>

Convert to jar while retaining classpath

I have a Java program that uses an external library, whose location is specified through the classpath. I would now like to make the Java program into a standalone jar file (so I can use my IDE for other things whilst the program is running).
How do I turn my existing .java file into an executable jar file?
I am able to make a jar file that includes the class file, manifest file, and the jar file of the library (that was specified in the classpath), but that still appears to be wrong because I get class not found errors.
Ant script for you. What you missed was the classpath generation as a string for the jar task.
<target name="all">
<property name="dir" value="yourProjectDir" />
<property name="name" value="$yourProjectName" />
<!-- clean -->
<delete dir="temp/" />
<mkdir dir="temp/bin/" />
<!-- prepare libs -->
<copy todir="temp/libs/"><fileset dir="${dir}/lbs/" /></copy>
<!-- prepare classpath -->
<pathconvert property="classpath" pathsep=" ">
<path><fileset dir="temp/libs/" /></path>
<chainedmapper><flattenmapper /><globmapper from="*" to="libs/*" /></chainedmapper>
</pathconvert>
<!-- compile -->
<javac destdir="temp/bin/" srcdir="${dir}/src/" target="1.6" source="1.6" includeAntRuntime="false">
<classpath>
<pathelement location="temp/bin/" />
<fileset dir="temp/libs/" />
</classpath>
</javac>
<!-- jar -->
<jar destfile="temp/${name}.jar" basedir="temp/bin/">
<manifest>
<attribute name="Main-Class" value="Main" />
<attribute name="Class-Path" value="${classpath}" />
</manifest>
</jar>
<!-- zip jar + libs -->
<zip destfile="${name}-${version}.zip">
<fileset dir="temp" includes="${name}.jar, libs/" />
</zip>
</target>
The following is the steps, how run stand alone App from command prompt.
1. Create a sample java file then save in particular location(like d:\sample\Hello.java.
2. open command prompt compile that java class, then create jar like Hello.jar file
3. then set classpath in Environment file(like D:\sample\Hello.jar ;
4. Now run your java class , it will work(d:sample>java Hello

Ant Script Example

I would like to make a very simple ant script that does 1 thing, which is to bulid a jar file. But when I try to use a very simple example, it fails due to dependancies on jars that my source depends on. So, How you you specify jars that there are jars that need to be in the class path when building an Ant target.
<project name="project" default="default">
<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="//tomcat/common/lib"/>
<description> description </description>
<!-- =================================
target: default
================================= -->
<target name="default" depends="compile" description="description">
<jar destfile="/path/to/dir/Library.jar">
</jar>
</target>
<target name="compile">
<mkdir dir="${classes.dir}"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}"/>
</target>
</project>
Your question isn't entirely clear - I suspect you mean you want to compile your source (with the javac task) and then build a jar file from the results. If that's not the case, I don't see where your source dependencies come into it. If that is the case, then the jar task is irrelevant.
In the javac task, use the classpath attribute to specify other jar dependencies.
Here's an ANT script generated by using the Eclipse Runnable JAR Export Wizard. This is a project that updates stats on a Google Spreadsheet for a small fantasy baseball league with some friends. It gets the stats by scraping ESPN.com player pages.
Class-Path attribute inside the manifest element is used to set the classpath used by the jar. This defaulted "." but I had to add my src path explicitly so that log4j would pick up log4j.properties.
zipfileset elements are external jars used by my source that I wanted to be included with my jar. I suspect this might be what you're looking for.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_run_jar" name="Create Runnable Jar for Project cob_fantasy_baseball">
<!--this file was created by Eclipse Runnable JAR Export Wizard-->
<!--ANT 1.7 is required -->
<target name="create_run_jar">
<jar destfile="C:/workspace/cob_fantasy_baseball/cob_fantasy_baseball.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="com.me.cob_fantasy_baseball.UpdateCobStats"/>
<attribute name="Class-Path" value=".;src/com/me/cob_fantasy_baseball"/>
</manifest>
<fileset dir="C:/workspace/cob_fantasy_baseball/classes"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/gdata/java/lib/gdata-core-1.0.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/gdata/java/lib/gdata-spreadsheet-2.0.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/jericho-html-2.6/lib/jericho-html-2.6.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/apache-log4j-1.2.15/log4j-1.2.15.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/jaf-1.1.1/activation.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/javamail-1.4.2/mail.jar"/>
<zipfileset excludes="META-INF/*.SF" src="C:/workspace/javamail-1.4.2/lib/smtp.jar"/>
<fileset dir="C:/workspace/cob_fantasy_baseball/src/com/me/cob_fantasy_baseball"/>
</jar>
</target>
</project>
Also, here's a link to the Ant documentation for the jar task: http://ant.apache.org/manual/Tasks/jar.html
Based on your example you can just put libs inside javac:
<javac srcdir="${src.dir}" destdir="${classes.dir}">
<classpath>
<pathelement location="${lib.dir}/lib1.jar"/>
<pathelement location="${lib.dir}/lib2.jar"/>
</classpath>
</javac>
Here is the ant file we use to build the Timeline opensource project. It is pretty straight forward. It doesn't build a jar, but it does use libraries to minimize JS files.
http://simile-widgets.googlecode.com/svn/timeline/trunk/build.xml
Larry

Categories

Resources