Resources access problem from JAR - java

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.

Related

ant build missing jar from lib

I have a build.xml and I have a path for the classpath that I set to classpathref="compile.classpath" during compile:
<path id="compile.classpath">
<fileset dir="./lib">
<include name="*" />
</fileset>
</path>
The lib folder contains weblogic.jar but when i try to compile the project, i got many errors because of missing the weblogic.jar
If I modify my path to this:
<path id="compile.classpath">
<fileset dir="./lib">
<include name="*" />
</fileset>
<fileset dir="${env.WL_HOME}/wlserver/server/lib">
<include name="weblogic.jar" />
</fileset>
</path>
So I add the weblogic.jar from my local installed weblogic directory, there are no errors, and it's compiled.
I copied the weblogic.jar to my project lib folder from the local installed weblogic folder, so it must be the same weblogic.jar
What should I try? Thank you!
I would do something like this in your build.xml (probably just before you do the compilation will work).
<property name="echo.classpath" refid="compile.classpath"/>
<echo message="compileClasspath - ${echo.classpath}"/>
What you probably need to do is to be quite explicit about where your lib directory is, relative paths are tricky if you have multiple build.xml files, and nested directories and stuff.
What I have done before is to make sure that you explicitly define a property in the right place for your lib directory, and just use that rather than ./
<project basedir=".">
<target name="init">
<property name="local.lib.dir" value="${basedir}/lib">
</target>
<target name="compile" depends="init">
<path id="compile.classpath">
<fileset dir="${local.lib.dir}">
<include name="*" />
</fileset>
</path>
....
</target>
</project>

build.xml javac is complaining about missing classes from javax.servlet.http during compliation

I've written a build.xml (Updated 8:49 PM) for a netbeans project. And I've found that the tomcat libraries such as serlvet-api.jar are in the directory C:\apache-tomcat-7.0.35\lib. But I'm not sure how I'm meant to connect the target="class_compile" using the fieldset dir to the tomcat directory (without changing the build.xml each time I wish to compile from another computer).
I've read the question error while including external JARs in ant script, with the solution being a missing classpathref attribute within the javac element (although my classpathref attribute seems to be correct).
<path id="build.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="class_compile" depends="prepare" description="Compile the whole project">
<javac destdir="${build.classes}"
debug="${debug}"
deprecation="on"
optimize="off"
srcdir="${src.dir}"
classpathref="build.classpath"
includes="*/**"
/>
<copy todir="${build.classes}">
<fileset dir="${src.dir}" includes="**/*.properties"/>
</copy>
</target>
<target name="prepare">
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes}"/>
<path id="run.classpath" >
<pathelement location="${build.classes}" />
</path>
<mkdir dir="${build.lib}"/>
<mkdir dir="${qa.dir}"/>
</target>
Currently, once the class_compile target is executed multiple errors regarding missing class files are reported..
emma:
Created dir: C:\capstonegroup3\TTTserver\build\emma-instr
Created dir: C:\capstonegroup3\TTTserver\build\emma-reports
prepare:
Created dir: C:\capstonegroup3\TTTserver\build\classes
Created dir: C:\capstonegroup3\TTTserver\build\lib
Created dir: C:\capstonegroup3\TTTserver\build\qa-reports
class_compile:
C:\capstonegroup3\TTTserver\build.xml:152: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
Compiling 21 source files to C:\capstonegroup3\TTTserver\build\classes
C:\capstonegroup3\TTTserver\src\java\AuthServer\AuthenticationInterface.java:8: error: package javax.servlet.http does not exist
import javax.servlet.http.HttpServletRequest;
Is there any way to set a property to the tomcat apache/lib directory, from persay a .property file? I saw in my build_impl.xml (generated by netbeans, that has a property file included during the -init-private target).
<target depends="-pre-init" name="-init-private">
<property file="nbproject/private/private.properties"/>
</target>
But I'm unsure how to gain access to those properties for my build.xml. But basically I'm after a solution that generates a relative path to the apache-tomcat\lib directory, and successfully compiles the class files without missing packages.
You should declare the servlet-api.jar file to build.classpath as below
<path id="build.classpath">
<fileset dir="C:/apache-tomcat-7.0.35/lib">
<include name="servlet-api.jar" />
</fileset>
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
What I like to do is keep a local.properties file that describes my local environment in the parent folder of the project folder (e.g. under NetBeansProjects), e.g.:
NetBeansProjects
+- local.properties
+- MyProject
+- build.xml
+- <other stuff>
The build.xml is like:
tomcat.home=/C:/java/tomcat
gwt.dir=/C:/java/google/gwt-2.5.1
This file is not kept under version control and allows each developer to configure his/her own environment. It is read by Ant using something like:
<property file="../local.properties" />
And used e.g. as (this is only an example, adjust for proper usage):
<path id="project.classpath">
<pathelement path="war/WEB-INF/classes" />
<fileset dir="war/WEB-INF/lib">
<include name="*.jar" />
</fileset>
<fileset dir="${tomcat.home}/lib"><!-- tomcat.home defined in local.properties -->
<include name="**/*.jar" />
</fileset>
</path>

Create jar for android project in eclipse

Hello all how can I create jar file of my project that is created in android using eclipse. I have done in this way project -> right-click->export --> select builder -->antbuilder-->ok then after this process build.xml will be created. On bulid.xml I will create new builder.
Right click on project -> properties --> select new -->give build.xml and your project path and press ok, new builder will be created.
Now select that builder from project properties and press ok.
Now build your project and your jar will be created in bin folder.
I have followed above process but my jar is not found in bin folder. I can see my build.xml is created and all process goes smooth but still jar is not created. Can any one tell me how can I do this?
My build.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- WARNING: Eclipse auto-generated file.
Any modifications will be overwritten.
To include a user specific buildfile here, simply create one in the same
directory with the processing instruction <?eclipse.ant.import?>
as the first entry and export the buildfile again. -->
<project basedir="." default="build" name="testtttttttttt">
<property environment="env"/>
<property name="debuglevel" value="source,lines,vars"/>
<property name="target" value="1.6"/>
<property name="source" value="1.6"/>
<path id="Android 2.2.libraryclasspath">
<pathelement location="C:/Program Files (x86)/Android/android-sdk/platforms/android-8/android.jar"/>
</path>
<path id="com.android.ide.eclipse.adt.LIBRARIES.libraryclasspath"/>
<path id="testtttttttttt.classpath">
<pathelement location="bin/classes"/>
<path refid="Android 2.2.libraryclasspath"/>
<path refid="com.android.ide.eclipse.adt.LIBRARIES.libraryclasspath"/>
</path>
<target name="init">
<mkdir dir="bin/classes"/>
<copy includeemptydirs="false" todir="bin/classes">
<fileset dir="src">
<exclude name="**/*.java"/>
</fileset>
</copy>
<copy includeemptydirs="false" todir="bin/classes">
<fileset dir="gen">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>
<target name="clean">
<delete dir="bin/classes"/>
</target>
<target depends="clean" name="cleanall"/>
<target depends="build-subprojects,build-project" name="build"/>
<target name="build-subprojects"/>
<target depends="init" name="build-project">
<echo message="${ant.project.name}: ${ant.file}"/>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin/classes" source="${source}" target="${target}">
<src path="src"/>
<classpath refid="testtttttttttt.classpath"/>
</javac>
<javac debug="true" debuglevel="${debuglevel}" destdir="bin/classes" source="${source}" target="${target}">
<src path="gen"/>
<classpath refid="testtttttttttt.classpath"/>
</javac>
</target>
<target description="Build all projects which reference this project. Useful to propagate changes." name="build-refprojects"/>
<target description="copy Eclipse compiler jars to ant lib directory" name="init-eclipse-compiler">
<copy todir="${ant.library.dir}">
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</copy>
<unzip dest="${ant.library.dir}">
<patternset includes="jdtCompilerAdapter.jar"/>
<fileset dir="${ECLIPSE_HOME}/plugins" includes="org.eclipse.jdt.core_*.jar"/>
</unzip>
</target>
<target description="compile project with Eclipse compiler" name="build-eclipse-compiler">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
<antcall target="build"/>
</target>
</project>
In Eclipse, select project, right click on the project, Select Export, From that select Jar. Then follow the simple wizard and give the destination where you want to save your jar, and finish. You can find your jar there.
Step 1. Create Android library project as explained here.
Step 2. Now you need to give reference of Android Library project created in step 1 to your client application. There are two ways to do so.
•Give reference of Android Library Project itself by client app
property -> Select 'Android' on left pane -> In Libraty Section, Add
Android Libraty project (This is explained at link given in Step 1
above)
•Give the reference of .jar file of Android Library project
(from Location of Android Library project -> bin -> .jar file).
Client Application -> Properties -> Click 'Java Build Path' in lefe
pane -> Go to 'Libraries' Tab -> Click 'Add External JARs' button and
select the .jar file -> Go to 'Order and Export' tab and select the
added .jar file reference and move it to top.
Hope this will help you

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}" />

How do I include classes in a buildfile for ant?

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>

Categories