How do I include classes in a buildfile for ant? - java

I am creating a jar file of a javaagent that I have written. However, that agent depends on another java library.
So, I would like to know, how do I include a whole package that is being used by my program into the jar file so that it can be used when the jar gets executed?

Unzip the jar you want to include and put it the final jar. Here are the ant commands that will do this for you.
<target name="package">
<!-- Staging is simply a temporary directory for exploding the jar files. You
can call the directory whatever you want. -->
<property name="staging.dir" location="staging"/>
<mkdir dir="${staging.dir}"/>
<unjar dest="${staging.dir}">
<fileset dir="lib" >
<include name="*"/>
</fileset>
</unjar>
<mkdir dir="classes"/>
<javac debug="on" srcdir="src" destdir="classes" target="1.5" includes="**/*">
<classpath refid="build.class.path"/>
</javac>
<jar destfile="Product.jar"
basedir="classes"
excludes="**/Test.class">
<fileset dir="${staging.dir}"/>
</jar>
<!-- Delete the temporary staging directory. -->
<delete dir="${staging.dir}" />
</target>

Related

should we delete lib folder when we clean project in java and how to build it again after delete lib folder using apache ant and ivy

I have some problem, in my friend's code there is a clean code using apache ant seems to delete lib folder as well. but when I try to create project, it fails because the lib folder is missing. then how to build the correctly using ant apache ?
this is clean code
<target name="clean" description="--> clean the project">
<delete includeemptydirs="true">
<fileset dir="${basedir}">
<exclude name="src/**" />
<exclude name="build.xml" />
<exclude name="ivy.xml" />
</fileset>
</delete>
</target>
and this build code
<target name="build" description="Compile main source tree java files">
<mkdir dir="${build.dir}" />
<javac srcdir="${java.dir}" destdir="${build.dir}" classpathref="lib.path.id" debug="true" deprecation="true" optimize="true" failonerror="true" />
<!-- class path properties files -->
<copy file="${resource.dir}/log4j.properties" todir="${build.dir}" />
<copy file="${resource.dir}/mncplaymedia.properties" todir="${build.dir}" />
<copy todir="${build.dir}">
<fileset dir="${resource.dir}" />
</copy>
</target>
thank you
I think you have to build this project, then put the war or jar file in webapps on your web server (like jetty, tomcat and etc.)

Ant include external .jar

I want to include external jar to my java project. I'm using ant. External .jar is in folder lib. My build.xml looks something like that:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<path id="classpath">
<fileset dir="lib" includes="**/*.jar"/>
</path>
<target name="clean">
<delete dir="build"/>
</target>
<target name="compile">
<mkdir dir="build"/>
<javac srcdir="src" destdir="build" classpathref="classpath" />
</target>
<target name="jar">
<mkdir dir="trash"/>
<jar destfile="trash/test.jar" basedir="build">
<zipgroupfileset dir="lib" includes="**/*.jar"/>
<manifest>
<attribute name="Main-Class" value="com.Test"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="trash/test.jar" fork="true"/>
</target>
</project>
But it doesn't work. When I want to import something from the external .jar, there is an error after command ant compile: package com.something does not exist.. What should I edit to get it working?
Exact error:
Compiling 23 source files to xy/build
xy/src/com/Test.java:5: package com.thoughtworks.xstream does not exist
import com.thoughtworks.xstream.*;
^
1 error
You should try without the includes attribute:
<fileset dir="lib" />
And in the jar part you include the classes like this:
<zipgroupfileset includes="*.jar" dir="lib"/>
You can't put external libraries into a jar and expect the classloader to use those jars. Unfortunately this is not supported.
There are ant tasks like one jar that help you, to create a jar file, that contains everything you need.
This bit is from the background information of one jar:
Unfortunately this is does not work. The Java Launcher$AppClassLoader
does not know how to load classes from a Jar inside a Jar with this
kind of Class-Path. Trying to use
jar:file:jarname.jar!/commons-logging.jar also leads down a dead-end.
This approach will only work if you install (i.e. scatter) the
supporting Jar files into the directory where the jarname.jar file is
installed.
Another approach is to unpack all dependent Jar files and repack them
inside the jarname.jar file. This approach tends to be fragile and
slow, and can suffer from duplicate resource issues.
Other Alternative:
jarjar: Jar Jar Links is a utility that makes it easy to repackage Java libraries and embed them into your own distribution
I also use ant to include a number of dependency JARs in my JAR. My compile task looks like this. Perhaps something similar will work for you.
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}" includeantruntime="false">
<classpath>
<pathelement path="${classpath}" />
<fileset dir="${deps}">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
<copy todir="${build}">
<fileset dir="${src}" excludes="**/*.java"/>
</copy>
</target>
sometimes u can use jar contents directly, just unzip
<unzip src="/Developer-Java/mysql-connector-java/mysql-connector-java-5.1.22-bin.jar" dest="${build_dir}" />

NoClassDefFound error for a jar created using ant build

I have a java project with class having main method in package com.nik.mypackage. Only one library is referenced which is someLib-5.0.2.jar
This library is in lib folder in eclipse and added to the build path.
I am creating executable jar of the application using the below ant script target:
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<javac srcdir="${src}" destdir="${build}">
<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/someLib-5.0.2.jar"/>
</classpath>
</javac>
</target>
<target name="dist" depends="compile" description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<copy todir="${build}/lib" verbose="true" file="lib/someLib-5.0.2.jar" />
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/myProject-${DSTAMP}.jar" basedir="${build}">
<manifest>
<attribute name="Main-Class" value="com.nik.mypackage.MainClass"/>
<attribute name="Class-Path" value="../lib/someLib.jar"/>
</manifest>
</jar>
</target>
The jar MyProject-20111126.jar is getting created. However, running the below command:
c:>java -jar MyProject-20111126.jar
is throwing a NoClassDefFoundError for a class in someLib.jar
What am I doing wrong ??
Thanks for reading!
When you run where is someLib.jar relative to the MyProject-20111126.jar?
The classpath you are setting up in the MyProject.jar is telling the VM to look for a lib folder in the parent directory of MyProject.jar.
The ClassPath entry in the manifest is interpreted relative to the location of the JAR file. It is used to locate jar files on the File System. The regular class loader in JAVA does not support JAR files bundled inside of JAR files.
As mentioned in the comment by Eric Rosenberg, we can not nest jar files inside other jar files. So we need to deflat the library and bundle individual classes in the app jar.

Ant built does not generate class files

I'm using build.xml to build my src. However it failed to generate class files without any error message. The full script is
<?xml version="1.0"?>
<project name="auxiliary" basedir="." default="dist">
<property name="src.dir" value="../auxiliary-src/com/nextbio/drugbank"/>
<property name="dist.dir" value="dist"/>
<property name="lib.dir" value="../jboss_config/common_app_jars"/>
<property name="temp.dir" value="temp"/>
<property name="foo_dist.dir" value="../foo/dist"/>
<path id="libs-classpath">
<fileset dir="${foo_dist.dir}">
<include name="foo.jar"/>
</fileset>
</path>
<target name="dist" depends="auxiliary-dist" />
<target name="auxiliary-cleanup">
<delete dir="${temp.dir}"/>
<delete dir="${dist.dir}"/>
<echo message="cleaned up. ${temp.dir}, and ${dist.dir} have been deleted."/>
</target>
<target name ="auxiliary-dist">
<delete dir="${temp.dir}"/>
<echo message="delete ${temp.dir}" />
<mkdir dir="${temp.dir}"/>
<javac destdir="${temp.dir}" source="1.6" target="1.6" debug="on" fork="true" memorymaximumsize="1024m">
<src path="${src.dir}"/>
<classpath>
<path refid="libs-classpath"/>
</classpath>
<include name="com/car/**"/> <!-- troubled line -->
</javac>
<!--<copy overwrite="true" todir="${temp.dir}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
<exclude name="**/*.sql"/>
<exclude name="**/*.txt"/>
</fileset>
</copy>
<delete dir="${dist.dir}"/>
<mkdir dir="${dist.dir}"/>
<jar destfile="${dist.dir}/auxiliary.jar" basedir="${temp.dir}"/> -->
</target>
There is no class file in ${temp.dir} after this step, and no error message. I double checked it, and found it is because of the "troubled line". I tried to add some files to the classpath. I don't know why it is wrong.
The source path should point to the root of the package tree. You make it point to a specific package inside the sources : ../auxiliary-src/com/nextbio/drugbank.
And in the javac task, you ask it to compile all the files matching the pattern com/car/**. That means that it will compile the Java source files in ../auxiliary-src/com/nextbio/drugbank/com/car or in a subdirectory. If that's the case, you have very unconventional package names.
I had the same problem.
My project complilated well but the classes there weren't in nowhere and It didn't have any error message.
My problem was the classpath. The eclipse wizard added EclipseLink 2.5.1 jars.
I removed it and the problem is gone.
I suggest make a simple HelloWord and remove all jars
reference from the classpath and try again.
I encountered this "ant, javac, compile" problem related with the classpath to.
No debug or verbose message shown.
This behavior appear because in classpath exists not compatible (superior) version jar packages and that cause no output classes.

Resources access problem from JAR

I have the following directory structure of a project:
Folder "project" in Eclipse:
--folder "src"
--folder "resources"
----trayicon2.png
--folder "db"
----test.db
--folder "bin"
I'm accessing the image with:
Image image = Toolkit.getDefaultToolkit().getImage("resources/trayicon2.png");
and from Eclipse that is not a problem.
Then I generate an "executable jar file", and add the dirs, making a directory structure of:
Folder "project"
--folder "db"
----test.db
--folder "resources"
----trayicon2.png
--project.jar
And now the image is no more accessible. Also, the database is no more accessible; while in Eclipse I used to access it with:
Connection conn = DriverManager.getConnection("jdbc:sqlite:db/test.db");
How can I access the resources (images and db) after generating the jar file "project.jar"?
For the image, try this:
URL imageURL = getClass().getResource("/resource/trayicon2.png"); // note leading slash
Image image = Toolkit.getDefaultToolkit().getImage(imageURL);
When you are in eclipse the filename you pass is relative and it is resolved properly with the classpath that is automatically setup by eclipse. Try using the URL version of the method and pass the URL to your jar file. You can see an example on this page
You may want to switch to ANT to build your jar files.
You can have the image resources built into the jar where they can be found, and any required libraries (like those for sqlite, put into a lib folder inside the jar as well).
Here's a sample build file:
<?xml version="1.0"?>
<project name="test" default="compile" basedir=".">
<description>
Generates jar for project
</description>
<property name="src.dir" value="${basedir}/src"/>
<property name="build.dir" value="${basedir}/build"/>
<property name="build.classes" value="${build.dir}/classes"/>
<property name="build.jars" value="${build.dir}/jars"/>
<target name="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes}"/>
<mkdir dir="${build.jars}"/>
</target>
<path id="core.classpath">
<fileset dir="${build.jars}">
<include name="**/*.jar"/>
</fileset>
</path>
<path id='lib.classpath'>
<fileset dir='lib' />
</path>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${build.classes}" debug="true">
<classpath refid="lib.classpath"/>
</javac>
</target>
<target name="copy-resources">
<copy todir="${build.classes}">
<fileset dir="${src.dir}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="jar" depends="compile, copy-resources">
<jar destfile="${build.jars}/project.jar">
<fileset dir="${build.classes}">
<include name="**/*.class"/>
<include name="**/*.properties"/>
<include name="**/*.png"/>
</fileset>
<fileset dir=".">
<include name="**/*.jar"/>
</fileset>
<manifest>
<attribute name="Built-By" value="${user.name}"/>
<attribute name="Main-Class" value="com.your.path.to.MainClass"/>
</manifest>
</jar>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${build.classes}"/>
<delete dir="${build.jars}"/>
</target>
</project>
This assumes you have some java files in a src directory, and some libraries in a lib folder. So your path would look like this:
Project
----------
-bin
-src
--com...
---MainClass (has a main method, runs your program)
---a.png (will be findable)
-lib
--jar files required by your project
build.xml
-----------
It will also copy any properties or png files you have inside the src folders.
You would then type ANT jar at the level of build.xml to build the jar file.
You can't access resources inside a JAR file directly. Instead, you need to use the Class's URL getResource(String) (or InputStream getReourceAsStream(String)) methods.
I'm not really sure how you'd use that with the SQLite database, though.

Categories