views:

126

answers:

4

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"?

A: 

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.

wsorenson
+1  A: 

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

M. Jessup
+2  A: 

For the image, try this:

URL imageURL = getClass().getResource("/resource/trayicon2.png"); // note leading slash
Image image = Toolkit.getDefaultToolkit().getImage(imageURL);
Thomas
Thank you, this works for the image (though with "resources"). I have tried this before, but I had ommited the slash; obviously this was the problem. If I don't find a method also for accessing the database, I will accept this answer. Thank you once again.
aeter
Accepting this answer. On my Ubuntu Linux, when opening the file with right click/"Open with Sun Java 6 Runtime" it opens the app with an empty database; though when writing "java -jar project.jar" it opens it with a full database. I will try to figure this out, probably going to ask in another question if I find no information in Google. About this question,your answer was correct and punctual and helped me. Thanks.
aeter
A: 

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.

R. Bemrose