2

I want to put path of different directory (which contains jars, presently on d:/ext_jars). After running the build.xml. I want that path should take that runnable jar.

Currently that jar is giving me errors because of classpath is not present (which was previously under c:/project/lib/*.jars, converted into D:/ext_jars).

Please help me, that how can I set that external directory in classpath of build.xml?


My code in : build.xml

<?xml version="1.0"?>
<project name="MyProject" default="deploy" basedir="." >
    <property file="manifest.mf" />
    <property name="dir.src" value="src" />
    <property name="dir.build" value="bin" />
    <property name="dir.dist" value="dist/MyProject" />
    <property name="dir.lib" value="lib" />
<!-- Creates the output directories -->
    <target name="prepare">
        <mkdir dir="${dir.build}" />
        <mkdir dir="${dir.dist}" />

        <mkdir dir="${dir.dist}/${dir.csvdata}" />
        <mkdir dir="${dir.dist}/${dir.MH}" />
    </target>

    <target name="clean" description="Remove all generated files.">
        <delete dir="${dir.build}" />
        <delete dir="${dir.dist}" />
    </target>

    <path id="build.classpath">
        <fileset dir="${dir.lib}">
            <include name="**/*.jar" />
            <include name="**/*.zip" />
        </fileset>
    </path>
    <path id="build.classpath.ref">
        <fileset dir="D:/ext_jars">
            <include name="**/*.jar" />
            <include name="**/*.zip" />
        </fileset>
    </path>

    <target name="compile" depends="prepare" description="Compile all source code.">
        <!--<javac srcdir="${dir.src}" destdir="${dir.build}" debug="true">-->
        <javac  destdir="${dir.build}" debug="true">
            <classpath refid="build.classpath" />
            <classpath refid="build.classpath.ref" />
            <src path="src"/>           
        </javac>        
        <copy todir="${dir.build}">
            <fileset dir="${dir.src}">
                <exclude name="**/*.java" />
            </fileset>
        </copy>     
    </target>

    <pathconvert property="classpath" refid="build.classpath">
    </pathconvert>
    <pathconvert property="classpath" refid="build.classpath.ref">
    </pathconvert>

    <target name="jar" depends="compile" description="Generates ${project.name}.Jar in the 'dist' directory.">
        <jar jarfile="${dir.dist}/${ant.project.name}.jar">
            <fileset dir="${dir.build}" includes="**/*.*" />
            <manifest>
                <attribute name="Class-Path" value="${Class-Path}" />
                <attribute name="Main-Class" value="${Main-Class}" />
            </manifest>
        </jar>
    </target>
    <target name="deploy" depends="clean,jar">
        <copy todir="${dir.dist}/${dir.lib}">
            <fileset dir="${dir.lib}">
                <include name="**/*.jar" />
                <include name="**/*.zip" />
            </fileset>
        </copy>
    </target>

Using this code After runing project it is running well, But after running jar created by this code it is not running it is throughing error as follows:

Exception in thread "main" java.lang.NoClassDefFoundError: dowlibpkg/DowLib
        at mypkg.MainApp.main(MainApp.java:109)
Caused by: java.lang.ClassNotFoundException: dowlibpkg.DowLib
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

SO created Jar is not running../ I want it to be run, can any one please help me

==============================================================

manifest.mf

Manifest-Version: 1.0 Class-Path: lib/org.springframework.asm-3.0.1.RELEASE \ lib/org.springframework.beans-3.0.1.RELEASE \ lib/org.springframework.context-3.0.1.RELEASE \ lib/org.springframework.core-3.0.1.RELEASE \ lib/org.springframework.expression-3.0.1.RELEASE \ lib/org.springframework.oxm-3.0.1.RELEASE \ lib/org.springframework.web-3.0.1.RELEASE Main-Class: myProject.MainApp

Vadzim
  • 24,954
  • 11
  • 143
  • 151
Amit
  • 219
  • 2
  • 7
  • 14
  • Are you refering to Ant task's build.xml? Do you mean the path as in the classpath? – ee. Feb 10 '12 at 06:57
  • @ee yes. I am using Ant build to run. – Amit Feb 10 '12 at 07:07
  • You mean you want to add some ant tasks in an external set of jars? – Guillaume Polet Feb 10 '12 at 07:08
  • The problem is an Ant project base is defined by its `basedir` property which is stated as follows: `the base directory from which all path calculations are done. This attribute might be overridden by setting the "basedir" property beforehand. When this is done, it must be omitted in the project tag. If neither the attribute nor the property have been set, the parent directory of the buildfile will be used.` http://ant.apache.org/manual/using.html Basically, it means the Ant project is always relative to where build.xml is located or relative to its basedir property... – ee. Feb 10 '12 at 07:12
  • Maybe, by setting up `relative=false` attribute in an Ant element can override this relative path behavior to become an absolute path...But, I am not sure...You may need to check the Ant documentation about where `relative` attribute can be found in which Ant element... – ee. Feb 10 '12 at 07:18
  • Maybe, you can also refer to the explanation given http://stackoverflow.com/questions/5066872/ant-create-filesets-dirsets-from-absolute-properties – ee. Feb 10 '12 at 07:29
  • Another possible solution: http://stackoverflow.com/questions/3733029/ant-fileset-dir-attribute-with-a-runtime-expanded-full-path – ee. Feb 10 '12 at 07:31
  • @ee relative=false of which parent tag – Amit Feb 10 '12 at 07:44
  • I would suggest posting your build.xml and exact error message you get. – Nikem Feb 10 '12 at 07:50
  • @Nikem : please see the above code / If you get any idea about how i can set external_library to my project using this code .Please give me some suggestions – Amit Feb 13 '12 at 09:22
  • @GuillaumePolet : No, I have same project. and want to use external jars in my executable jar. So how can I give external path ? – Amit Feb 13 '12 at 11:33

2 Answers2

0

Based on some hints from the links I have provided in my comments, you can try this (which I haven't tried):

<target depends="init" name="build-projects">
    <property name="myproject.root.path" location="d:/ext_jars"/>

    <path id="class.path">
        <fileset dir="${myproject.root.path}">
            <include name="*.jar"/>
            <exclude name="${ant.project.name}.jar"/>
        </fileset>
    </path>

    <manifestclasspath property="jar.classpath" jarfile="${myproject.root.path}/${ant.project.name}.jar">
        <classpath refid="class.path"/>
    </manifestclasspath>

    <jar destfile="${myproject.root.path}/${ant.project.name}.jar" basedir="classes/app" excludes="*.properties">
        <manifest> 
            <attribute name="Main-Class" value="path.to.my.MainClass" />
            <attribute name="Class-Path" value="${jar.classpath}"/>
        </manifest>
    </jar>
</target>

Example MANIFEST.MF generated by Ant task:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.6.0_29-b11 (Sun Microsystems Inc.)
Main-Class: path.to.my.MainClass
Class-Path: Filters.jar RXTXcomm.jar collections-generic-4.01.jar colt
 -1.2.0.jar commons-codec-1.5.jar commons-io-2.0.1.jar commons-validat
 or-1.3.1.jar concurrent-1.3.4.jar forms-1.3.0.jar gdal.jar geotiff-ja
 i.jar jai_imageio-1.1.jar jakarta-oro-2.0.1.jar java-image-scaling-0.
 8.5.jar jcommander-1.7.jar jgroups-2.12.1.Final.jar jna.jar jung-algo
 rithms-2.0.1.jar jung-api-2.0.1.jar jung-graph-impl-2.0.1.jar jung-vi
 sualization-2.0.1.jar nimrodlf-1.2.jar platform.jar stax-api-1.0.1.ja
 r swingx-beaninfo-1.6.2.jar swingx-core-1.6.2.jar vecmath-1.3.1.jar v
 lcj-1.2.0.jar wstx-asl-3.2.6.jar

As you can see all external jar libraries listed in the Class-Path follow the exact name of the jars that the main application will use. All of them must be at the same file path as the main application's jar file path. The main application's class (usually with the main() method) will be called from the Main-Class of the MANIFEST.MF and its jar must not be included in the Class-Path. If everything is correct, the jar will be runnable.

Don't worry about the weird formatting of the MANIFEST.MF; it is generated in 80-column text style by the Ant task.

ee.
  • 947
  • 5
  • 5
  • Thanks @ee it's nice suggestions, but still that errors are happening my current directory is C:/projects/ and I want to give the path of D:/ext_jars for jars, I was used ur code snippets but still this error is coming – Amit Feb 10 '12 at 10:01
  • The above Ant target snippet I've provided expects you to modify something like providing the actual value of your main class path to be tagged for the Main-Class property in the manifest file (not **path.to.my.MainClass**!). If you don't modify it, it won't work. I have checked your build.xml you have recently included but why are you setting the values as `${Main-Class}` and `${Class-Path}` for your element? How do you define them? – ecle Feb 10 '12 at 12:31
  • @eee : I mentioned ${Main-Class} and ${Class-Path} into manifest.mf so, i used it. – Amit Feb 13 '12 at 08:24
  • @Amit Hmm, I usually let Ant task to generate the MANIFEST.MF file to be included into the jar during based on some property variables created in the Ant task itself as you can see in my post rather than the other way around. – ee. Feb 13 '12 at 09:04
  • @Amit Can you post the MANIFEST.MF that you've used? Since anything wrong in that file will not allow a jar to be runnable. – ee. Feb 13 '12 at 09:07
  • @Amit Sorry that I'm too late to mention it but I should also ask you to list all the external jar libraries that you actually use for your application. I notice springframework library names in the MANIFEST.MF but all of them are not proper since they are missing the .jar extension. You should see the generated MANIFEST.MF file as a reference. – ee. Feb 13 '12 at 09:34
  • @ee , at the end of the file, I need to write under class path - d:/ext_jar/jar1.jar d:/ext_jar/jar2.jar like this ? – Amit Feb 13 '12 at 10:11
  • @Amit No, the jars must be relative to the path of the runnable jar. There shall not be any absolute path in a MANIFEST.MF. Again, you should not edit the manifest.mf if you don't know how it works; let the Ant task do this for you. But, for everything to work, the way you organize your Eclipse project files is very crucial for the Ant task especially when changes are made between both. I will try to find a link for a tutorial on how to set up Eclipse project, Ant task and an EXE creation task as a bonus... – ecle Feb 13 '12 at 12:13
  • @Amit [Créer un exécutable et un installateur Windows](http://www.eteks.com/tips/tipCreationExe.html) in French (use Google Translate to translate it) – ee. Feb 15 '12 at 07:42
  • @ee appreciated help ee Thanks a lot – Amit Feb 15 '12 at 09:29
0

There are several ways to fiddle with the java classpath like using classpath command line options or editing the CLASSPATH variable but fundamentally the issue you create for yourself later is that your build becomes dependent upon a certain directory structure.

This makes it hard to share your code and definitely annoys other developers that may work with you. Sometimes its better to go the extra mile and make your dependencies available on a website (or find a website they are already available on) and get ant to download them, unzip them and then add them to the classpath from the same location every time (eg build/lib directory you create).

Of course dependency management is what Maven (http://maven.apache.org) is all about so maybe its also worth a look for you.

Jeff

Jeff
  • 31
  • 5