write to sqlite db packaged inside a jar - java

I'm trying to use a DB for reading and writing that is contained in a JAR.
I can read in it, but can't write throwed exeception :
java.sql.SQLException: path to '/database/scddata.db': 'LocationOfJar/database' does not exist
Is there any way I can bundle the database file inside a JAR?
Thanks in advance.

Jar files does not allows to write.
So :
define a working path (in properties for example). Let's call it : workingPath/file.db.
on init of your program, before opening your db.
check if db exists in working path
if does not exists : copy your jar file.db file to workingPath/file.db .
Then you program will use the db from workingPath/file.db for execution.

Related

Liquibase won't find changelog files

I'm trying to call liquibase programmatically.
For that I use the following code :
val database = DatabaseFactory.getInstance()
.findCorrectDatabaseImplementation(JdbcConnection(connection))
Liquibase(pathToChangelog, ClassLoaderResourceAccessor(), database)
.update(Contexts(), LabelExpression())
Liquibase managed to connect to the database and to acquire the lock, but it fails when parsing the pathToChangelog with a path/to/changelog does not exist error.
Here is my WAR file structure :
WEB-INF
\ changelog
\ db.changelog-master.xml
I tried
"WEB-INF/changelog/db.changelog-master.xml"
"/WEB-INF/changelog/db.changelog-master.xml"
"changelog/db.changelog-master.xml"
System.getProperty("user.dir") + "/WEB-INF/changelog/db.changelog-master.xml"
and certainly some other stuff, to no avail. It keeps on telling me that the file does not exist.
Am I doing something wrong ?
Found the answer by looking at the source code. The files have to be placed inside the WEB-INF/classes directory provided path has to be a relative path starting from there.
For instance, if you put your master file here :
WEB-INF/classes/changelog/db.changelog-master.xml
the pathToChangelog parameter should simply be changelog/db.changelog-master.xml.
In fact, this seems to be the default target location for the resources copied by the maven-war-plugin for instance.

Removing lock file from hive metastore database

I am getting the following error in hive database:
Caused by: ERROR XSDB6: Another instance of Derby may have already booted the database /home/usr/metastore_db
I've heard I can solve it with removing lock file - how safe is this? There's db.lck file inside metastore_db folder, it contains one line containing some ID string.
Yes you can delete that lck file. it just creates id for that derby instance.
also note if you change your local directory and then start hive , you will see another metastore_db directory created with lck file, but all your previous data will be their on your first metastore_db not the new one
Yes you can delete that file. It wont affect your hive. It is just a lock that has been created for that particular instance.
Inside the "metastore_db" folder, there will be 2 ".lck" files. Just delete them. "rm -r *.lck" - You can also start the derby in server mode, to avoid this, or mysql is a better option.
Please check for the metastore_db folder probably in the home folder and delete the dbex.lck
If its not there check the derby.log to see where the metastore_db location is mentioned
It will be created next time when you execute the spark-shell instance

Connect to a SQlite file inside a .jar file with JDBC? [duplicate]

I have created a Swing application that uses SQLite as a local database. The database file is located in project's root directory.
Project/DatabaseFile
The application runs fine on Eclipse, but when I run the packaged executable Jar, I get the following error:
No such table : table1
This means that the database is not reachable. When I examined the contents of the resulting JAR file, the database file was not there anymore.
In the code, I've linked the database as follows:
jdbc:sqlite:DatabaseFile
My question is, how to include the SQLite database in the executable Jar?
EDIT
When I placed the DB file in the source Folder Project/src/DatabaseFile and changed the path to jdbc:sqlite:src/DatabaseFile, it worked on Eclipse but again when running the Jar file as java -jar Project.jar. It said:
path to 'src/DatabaseFile': 'C:\Users\name\src' does not exist
I think I need to specify a relative path for the database.
EDIT
This is how I connect to the database:
public Connection getConnection(){
try{
Class.forName("org.sqlite.JDBC").newInstance();
con = DriverManager.getConnection("jdbc:sqlite:src/DatabaseFile");
} catch (Exception e) {
Log.fatal("Méthode: getConnection() | Class : SQLiteConnection | msg system : " + e.getMessage());
}
return con;
}
What library are you using for SQLite?
I did a search based on the connection URI you indicated and found this one. In the documentation it says:
2009 May 19th: sqlite-jdbc-3.6.14.1 released. This version supports "jdbc:sqlite::resource:" syntax to access read-only DB files contained in JAR archives, or external resources specified via URL, local files address etc. (see also the detailes)
If that is the driver you are using, then I would suggest the following connection URI:
"jdbc:sqlite::resource:DatabaseFile"
The key is that since your database is in a jar file, it can not be access as a file with FileInputStream. Instead it must be accessed through the JVM's support for it (namely with Class.getResource() or Class.getResourceAsStream()). Do note that resources contained within jar files are read-only. You won't be able to save any changes to your database.
I have found two different ways to name the filepath depending on how you are trying to access it. Assuming you are accessing the db is located in /yourproject/resource/ or /yourproject/bin/resource ( havent narrowed it down, mine is in both and I'm happy with it) you should use this as your path:
//Eclipse test path
String url = "jdbc:sqlite:resource/mydb.db";
or
//runnable jar path
String url = "jdbc:sqlite::resource:mydb.db";
then
mysqlitedatasource.setUrl(url);
Your way also works... by putting the db in /src

Package and use embedded database (H2.db file) inside a Jar?

I'm using H2 embedded database for my application. I would like to contain everything the application needs in it's own Jar, including it's database if possible. My app does not need to create temp files or anything, so basically the user just runs the Jar.
Is it possible to embed a database inside a Jar, and be able to INSERT new records as well as just SELECT out?
EDIT: Just to clarify, I'm not looking to embed the H2 driver jar inside my distributable jar, I'm looking to embed the h2 database file (someDatabase.h2.db file) inside a Jar and still be able to write/read from that database.
If you wish to embed the myDatabase.h2.db file inside the .jar, you can do so, but you'll have read-only access to the database. As .jar files are read-only, you can't modify them and therefore can't execute INSERT, DELETE or any DDL command.
That being said, below is an explanation on how to embed it read-only.
According to H2's documentation:
The JDBC URL "jdbc:h2:~/myDatabase" tells the H2 Engine to look for a database file named myDatabase.h2.db in the home directory of the current user.
The JDBC URL "jdbc:h2:file:/myDatabase" tells the H2 Engine to look for a database file named myDatabase.h2.db in the current directory (where the java program was executed).
If you embed the h2.db file inside a .jar, it is not accessible in a plain way. It is only accessible as a file inside a zip file.
In order to make H2 uset it, you have to use a zip as URL:
jdbc:h2:zip:~/data.zip!/test
See more in "Read Only Databases in Zip or Jar File".
When you embed the file as a resource in the jar, you may get it's relative url. Using...
MyClass.class.getClassLoader().getResource("myDatabase.h2.db")
...you'll get something like:
jar:file:/C:/folder1/folder2/myJar.jar!/myDatabase.h2.db
You can then manipulate it as a String and pass as JDBC URL connection to H2.

Problems with loading CLP file from JAR

I am using CLIPSJNI.
What I have is:
Environment clips = new Environment();
clips.load("main.clp");
where main.clp is put in the same level as src and bin folder.
This runs fine in Eclipse. However when I export to JAR. It cannot work.
I understand that there are some problems with the path when we export to JAR.
So I've seen people suggesting using this.getClass().getResourceStream() but this is not the case. Because what I need is the name of the file, not its content.
Any suggestions on how to fix this?
The issue is that the load is being done within the native library on the C side which is being passed a file name as an argument. The C code has no concept of a JAR file or how to extract files embedded within one. I think what you would need to do is always place your .clp files within the JAR file and then have a routine which extracts the data from the JAR file and saves it to a file. You can then load it using the load method and delete the file once done.

Categories