SQLite database path fixed in JAR? - java

I have an application created in Java which uses a SQLite database. This is stored in both the bin and src folders of my project. When exporting (from Eclipse) the JAR it works fine. The application is able to access the database in the JAR. The code I use for the connectionString is as follows: -
public static String connectionString = "jdbc:sqlite::resource:MAIN_DATABASE.sqlite";
My problem is when I move the JAR to a different folder after it has been exported. It resets to the original database at the time of exporting the JAR. So any changes to the database that the application made are lost. If I move it back again to the original path the changes re-appear.
So it appears there is a "hard-coded" path somewhere in the JAR. Does anyone know where and how this is happening. It's like it is creating a new database for each new location that you put the JAR.
Please let me know if I can provide anymore detail to help you with your answer. Apologies if I have not described my problem correctly, I am both new to this site and Java programming. :)
Many thanks

Problem sorted. It was to do with how I exported the JAR from Eclipse. If I choose "Package required libraries into generated JAR" instead of "Extract required libraries into generated JAR" I can move the JAR around willy nilly and the database stays in tact.
I shall look to not including the database in the JAR on the final release of my application anyway thinking about it. It would be easy to access, back-up and update the application if the database is external.

Related

Access derby database in executable jar

I have been looking for a while now but haven't found exactly what I want. So, I have a project written in Java and have created a small Derby database that I have embedded in the project. Now when creating an executable jar of the project, I cannot access the database anymore unless I put the derby database files in the same directory of where the executable jar is located. However, I do not want this, I really want that the database files are INSIDE the jar.
I have tried to put the database files in a package and reference it like that, without any luck. Could someone point out how I can get this to work please?
Thanks!
EDIT
The goal here is that I want to create more than one executable JAR file and upload them to a Sun Grid Engine and execute each jar with different parameters. However, they all need to be able to access the database and until now I get an error when 1 application already booted the derby database, another application cannot access it. Therefor ALL jar files need to have their own database.
Do you use the jdbc:derby:jar protocol to access your database?
According to the documentation what you're after should be possible.
Inside your app (the one going into the executable jar) you must access the database using the jdbc:derby:jar protocol.
Create the database with the desired content.
When you have built your jar, you can use jar commands to add the database dir to your jar.
All of this could go in your build script, obviously..
There may be issues related to jar sealing and such, YMMV.

Packaging my project in Eclipse

I have a Java swing project which i need to test on other computers. I have some classes and a sqlite db which stores login information. I have some lib jars as well. The application takes information from the user and stores it in the sqlite db and then pushes data to the web. I want to package my project so that whoever uses my project has to just double click on an executable or jar.
I tried to Export to a Runnable Jar file in Eclipse but this does not give desired results. After the runnable jar is created and i run it for the first time it creates the sqlite db beside it and does not connect to the web link and send information.
How can i package my data properly?
This is my folder structure -
root
--src
----default package
----rest package
----images
--lib
--file.fcl
--db.sqlite
Any time you run a program outside eclipse that changes any file within a project folder structure, the file changed is "out of sync". To bring things back in sync, right-click on the project in Package Explorer and choose "Refresh" (you can also select the project in Package Explorer and press F5).
If your code is creating the database instead of using the one that is there, it suggests to me that your database location is set for your eclipse environment but not for the general case. For a java application, you have to know (or set) the "current directory" or "current folder" -- this is a folder that is the default for file operations, and from which relative file paths are set. If your current directory is "aaa", and you open a file or database at "bbb/ccc/ddd/database.db", then the "bbb" directory must be within "aaa" or the program won't find the file.
To run your program without having to set the database location, etc., then you're probably going to want to discover the directory in which your program file is stored and set that as your current directory. This SO answer indicates how you might do that.

How to access Jar file located within source folders?

in my Java project I am using an H2 in-memory database, for which I have to load the JDBC driver when I initialize my application. I want/need to load the H2 .jar file dynamically, so I do the following:
String classname = "org.h2.Driver";
URL u = new URL("jar:file:libs/h2.jar!/");
URLClassLoader ucl = new URLClassLoader(new URL[] { u });
Driver d = (Driver) Class.forName(classname, true, ucl).newInstance();
DriverManager.registerDriver(new DriverShim(d));
When I put the H2 .jar file into a "libs" folder outside my Java source code folder (that is, in Eclipse, this "libs" directory is on the same level as the "src" folder), then this approach works fine. However, unfortunately I have to put this H2 .jar file into a folder within the source code folder tree, but below the main class folder.
For example, my Java package structure looks like this in Eclipse:
<project>/src/my/app/MyApp.java // main class of my application
<project>/src/my/app/sub/package/h2.jar // how to access this?
<project>/libs/h2.jar // loading from here works
I know this is stupid, but unfortunately I have to work with this strange setup. But what I don't know: how can I edit my Java code (listed above) in order to work with this setup?
EDIT: This has to work outside Eclipse as well, so adding the JAR file to the Java Build Path in Eclipse is no option for me.
EDIT2: I already tried to load "jar:file:my/app/sub/package/h2.jar!/", but that did not work for me.
Thanks in advance for all helpful ideas!
Kind regards, Matthias
In some frameworks referring to files inside JARs can be done using the classpath: prefix. I doubt URLClassLoader supports it natively, but it's worth a try (e.g. classpath:/my/app/sub/package/h2.jar). But since that doesn't work with URLClassLoader, here are other ways:
One way to do it would be to write your own ClassLoader which reads the JAR file from classpath (using getResourceAsStream), uncompresses it (using ZipInputStream) to memory (e.g. a map of byte arrays) and loads the classes from there.
Another, slightly easier way, is to read the JAR file from classpath and write it into a temporary file. Then you can use the plain URLClassLoader to load classes from it. This has the disadvantage that the file must be written to a file and the file probably cannot be removed until the JVM exits (unless using Java 7 or higher).
I'm using the second approach (copying to a temp file) in one project, though I'm using it to launch an external process. I would be curious to hear why you have such a requirement. If it's just a matter of having the whole application in one JAR, there are numerous simpler methods for achieving that (Maven Assembly Plugin, Maven Shade Plugin, Jar Jar Links, One-JAR to name a few).
No it's not a homework, but an online build system that uses my classes under my/app/* and several other classes (not from me) to automatically build the whole solution. Anyway, I can't give you more details on the internals of this system, as I don't know them. As said, I simply have to live with it, and that is why I am asking here...
Sounds like you are working in a WTF environment (does it have a name?), so here are some ways to start hacking around it:
Find out more about your environment, especially absolute file paths of the following: directory where the source files are saved, directory where the generated .class files are saved, and the current working directory when the program is run.
If you can get any kind of output of what your program prints during runtime, you can put into your application some debug code where you use File.listFiles() to crawl the machine's directory trees. If you can get output only from what happens when compiling, it might be possible to execute your own code during compile by creating your own annotation processor (apt is part of javac since Java 6), though I'm not sure whether the annotation processor must be compiled first separately.
The working directory can be read from the user.dir system property and the location of class files can be probably gotten from the java.class.path system property (unless custom class loaders are used). There is no guarantee that a JAR file in the source directory would be copied to the classpath, so you might need to do some looking around.
Then when you know the file path of the JAR file, then you can get an URL to it using new File("path/to/h2.jar").toURI().toURL() which you can then pass to URLClassLoader.
If nothing else works, upload the source code of the libraries and compile them together with your project.
In the long run, try to replace the WTF build environment with one that uses a standard build tool (such as Maven) and a common CI server (such as Jenkins). It's normal for projects to have lots of library dependencies, so you shouldn't need to hack around a build environment to use them.

Java resources after export project

I've done a java aplication that have some images as resources like this:
->src
->resources
->images
For accessing this resources i've used getClass().getResource("/resources/images/img.jpg"), this works fine when i am on eclipse, but when i export the project to a jar the path change to something this genre: "jar:C:/path/deployed.jar!/resources/images/img.jpg".
What i am doing wrong? It is possible to export all the project in one jar?
One more question, this resources include a derby db that dont work either when deployed in jar file
Thanks
Try using getResourceAsStream() instead of getResource() to access resources in your jar file.
One more question, this resources include a derby db that dont work either when deployed in jar file
As Hovercraft stated, Derby DB (meaning the data files, not implementation) won't start from a jar. And it doesn't matter you don't insert anything, Derby needs to open these files for writing. They need to be in a directory where you have writing access.

Exporting Images with JAR in Eclipse (Java)

I've been working on a little project that requires external images for display. I'm not all that familiar with how to use Eclipse and this is my first time attempting to export a completed project so I can share it with others. Right now, it seems the only way I can get my images to show up is if I assign a specific folder on my hard drive and have the image paths in the code go to that.
I'm looking for a way to export the images as part of my JAR or as part of the same package so when I go to send this program to other people, I don't have to send them a separate archived folder of images. I'd also be interested in learning what I need to do to have my code reference the images within that package so they'll work without an external folder.
I have read about some kind of package system within Eclipse, but have thus far had no luck in figuring out how to use it. Could use some explicating!
Thanks in advance to anyone willing to give me their two cents.
Something I would have found useful with this answer is the following: make sure you put your images/files in the same eclipse folder (or sub-folder below) as your source code. I created a folder "images_ignored" using eclipse, added it to the build path but still it refused to be included in my JAR file (when creating an executable JAR).
Just drag the images folder into your Eclipse project, then choose to "Copy New Folder" or "Copy File and Folder" depending on Eclipse version, and then right click on the image folder (in Eclipse) and --> build path "use as source folder".
you might need to load them as class path resources if they are within a jar. see: getClass().getClassLoader().getResourceAsStream(...)
Use getResource() to load the images:
ImageIcon qmarkIcon = new ImageIcon(getClass().getResource("images/mark.gif"));
If you're using JDK 1.7 or JDK 1.8, you might want to use the NIO.2 API.
for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
if ("jar".equals(provider.getScheme()))
return provider.newFileSystem((new File(Start.class
.getProtectionDomain().getCodeSource().getLocation().toURI()))
.toPath(), new HashMap<String, Object>());
}
If you enter this code into a method that returns a java.nio.file.FileSystem, you can call the method to get the FileSystem for the JAR file.
To get the path to access the files inside your JAR file, you can use the following method, which then allows you to read the files however you may want.
fileSystem.getPath("/images/image.gif")
If you would like to be able to run this in Eclipse, make sure you surround the call to the method with a try/catch IOException and assign to your FileSystem object the following.
new File(Start.class.getProtectionDomain().getCodeSource().getLocation().toURI())
.toPath().toString();
This will allow you to run your program whether it's compressed into a JAR file or not.
I recommend you get used to using NIO.2, since it is a very powerful API.
If you add a folder to build path you can retrieve the images either in eclipse and when you exported it in jar file, just remember to don't reference the image with the path like img/myImage.gif but only myImage.gif !

Categories

Resources