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
Related
I've requirement to create database once with create/insert statements and then make it available inside javafx runnable jar with read only DB access.
I just gone through H2 database document many time and tried to achieve this using H2 Driver version 1.4.196 and 1.4.192 but I think I'm missing something.
I can connect without including it into runnable jar and read only things works as well. But I need to access it from jar itself to prevent DB access from outsiders.
Can I've connection string or logic to connect read only DB file from jar itself ?
Ofcourse I need more clear practical example from this, this and this.
I've implemented zipping logic as this and it works fine from given path.
But when I've added zip file in runnable jar and accessing it through following code:
DriverManager.getConnection("jdbc:h2:file:split:zip:./test.zip!/test");
Then it throws exception with:
Exception in thread "main" org.h2.jdbc.JdbcSQLException: IO Exception: "java.io.FileNotFoundException: .\jar\res\buzdirectory.zip (The system cannot find the path specified)"; "listFiles zip:./jar/res/buzdirectory.zip!/" [90031-196]
If I put fully qualified path then it works well:
DriverManager.getConnection("jdbc:h2:file:split:zip:C:\\CoreJava\\src\\main\\java\\res\\test.zip!/test");
What I'm missing here to access it from jar file.
I think we cannot open the database file directly from the runnable JAR file. To access it should be a "real" file, so we will need to extract it from the JAR and then open that copy.
For example, to extract the database from the JAR into a temporary file:
File dbFile = File.createTempFile("temp", ".zip");
dbFile.deleteOnExit();
java.nio.file.Files.copy(this.getClass().getResourceAsStream("/db/temp.zip"),
dbFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
StringBuffer connStr = new StringBuffer("jdbc:h2:file:split:zip:")
.append(dbFile.getAbsolutePath()).append("!/temp");
Connection conn = DriverManager.getConnection(connStr.toString());
conn.close();
System.out.println("closed");
By the way this is not preferable approach yet all. But we can use this kind of approach in some special cases.
I have the following question which is keeping me busy for some time now.
I am building a Java project in Netbeans and I have an embedded sqlite DB which I use in this project.
Currently the DB is located in the package src/release/.
I reference the db from the code the following way:
c = DriverManager.getConnection("jdbc:sqlite:src/release/db.db3");
When I run the project from within Netbeans it works without any problem. But when I try to build it and run the created jar-file (in the dist-folder).
I get the following error message (translated from Dutch description):
Opening connection failed: path to
scr/release/db.db3:'C:\users\idxxxxx\Documents\\dist\src'
does not exist
When referencing the DB in the code like this:
c = driverManager.getConnection("jdbc:sqlite:db.db3");
and adding the db-file to the root of the output-dir (so not in the jar itself), the application works partly, but some db-data is missing in my application (empty comboboxes).
So there seems to be an issue also.
My question is:
How can I add an embedded db - sqlite in this case - in netbeans to my project so it will be part of my project?
Where should I put the db-file and how do I reference it from within my project-code?
I don't want the enduser to see any db-file in the file(s) he will receive.
so I would like the db-file to be part of the .jar if possible.
Tnx
SQLite needs separate files, even without the need to update the database.
Need ensures locking and ensures database ACID properties.
SQLite from inside .jar
SQLite is designed to work with direct file access.
SQLite may require additional privileges not available in some environments.
The SQLite data files could be extracted from the JAR to a temporary location at start.
It is not a good choice to write the database url, directly into the program.
getConnection("jdbc:sqlite:src/release/db.db3");
Let your application look for the file. If not found: error: File db.db3 not found message. Then know the user, not the program is going wrong, but it is missing the database file.
Since you are working with java, it is easy to create dynamic url.
e.g. "jdbc:sqlite:"+PathToApp +"/data/db.db3".
Then the application knows where to copy the extracted file (db.db3 from the jar ) .
extract SQlite from .jar
You can let java doing it for you.
Use jdbc:sqlite::resource:
you need the sqlite-jdbc JAR, so extract the JAR file and add into the application JAR.
DB files will be extracted to a temporary folder System.getProperty(“java.io.tmpdir”).
e.g.
[...]
import org.sql.*;
import org.sqlite.*;
[...]
try {
Class.forName("org.sqlite.JDBC");
SQLiteConfig config = new SQLiteConfig();
config.enableFullSync(true);
config.setReadOnly(false);
SQLiteDataSource ds = new SQLiteDataSource(config);
ds.setUrl("jdbc:sqlite::resource:"+
getClass().getResource("db.db3").toString());
conn = ds.getConnection();
}catch(SQLException se)
{
System.out.println("SQLError: "...");
}
Update oct. 2014
org.sqlite SQLiteConfig + SQLiteDataSource
2014 October 8th: sqlite-jdbc-3.8.6.jar Updated to sqlite 3.8.6
I am trying to use an H2 database with Java. I cannot seem to find out where the data is being written.
The database URL I am giving is: jdbc:h2:/db/bh.
I am connecting with the database using Java like so:
dbObj.setDBConnection(DriverManager.getConnection(hObj.getDBUrl(), hObj.getDBUsername(), hObj.getDBPassword()));
where DB URL is given above.
Username: sa
Password: (empty).
I am running the jar from within the following folder:
C:\work\sampleH2\sampleH2.jar
My understanding of the FAQ section of H2 says that the database bh will be found in the folder db/ of the folder sampleH2. But that is not the case. Where can I find it?
according to http://www.h2database.com/html/cheatSheet.html there is a difference between storing in:
relative path (somewhere under current directory): jdbc:h2:test
absolute path (somewhere under root directory): jdbc:h2:/data/test
so i would look for it on your main drive (probably c:) under path you specified
I am using JAVA (with eclipse juno) and try to create an executable JAR file which include sqlite DB file.
I've try to get connection to the DB by this line:
DriverManager.getConnection("jdbc:sqlite:"+DataController.class.getResource("test.sqlite").getPath())
The DataController is a class that located where the sqlite located.
and i keep get an error:
java.sql.SQLException: invalid database address
Does someone can help and give step by step instructions about how to include sqlite DB inside an executable JAR file?
Apparently sqlite-jdbc can open resources on it's own. Per this thread https://groups.google.com/forum/?fromgroups=#!topic/xerial/Oayzj5nrJGk, add :resource to the path. So try the following:
DriverManager.getConnection("jdbc:sqlite::resource:package/test.sqlite");
or depends on version of sqlite
DriverManager.getConnection("jdbc:sqlite::resource:package/test.db");
Replacing package with the '/' separated path to the package this file is in.
Be aware that it will actually copy the file to a tmp directory.-
The ::resource way is right. And these explanations will help if you are using ::resource but still get errors like resource database.db not found: java.net.MalformedURLException: no protocol: database.db like verdana.
Most common anwsers are:
DriverManager.getConnection("jdbc:sqlite::resource:path/to/database.db")
However the path/to/database.db must be the exact path(the Path in Real File System but not in Jar) to your jar file.
I recommend to use getClass().getResource():
DriverManager.getConnection("jdbc:sqlite::resource:" +
getClass().getResource("/path/to/db/in/the/jar/file"))
NOTE:the /path/to/db/in/the/jar/file part must start with /
I'm not sure if this has changed in recent JDBC versions, but after fiddling with it for about an hour and getting various exceptions (MalformedURLException and "Database has been closed"), I found that the following worked for me:
DriverManager.getConnection("jdbc:sqlite::resource:file:/path/to/database.db")
The :file: portion seems to be missing from other answers and I couldn't get it to work without it.
Also, note that the
/path/to/database.db
is the absolute path starting from the root of the .jar file, rather than a normal resource root.
jdbc:sqlite::resource:notes_app.db
worked for me. My database(notes_app.db) was in the root of generated jar file.
public class Database {
public static Connection con () throws SQLException {
String url = "jdbc:sqlite::resource:notes_app.db";
return DriverManager.getConnection(url);
}
}
My notes_app.db is in the root of generated jar. I'm developing with maven and notepadd++
I have the following question which is keeping me busy for some time now.
I am building a Java project in Netbeans and I have an embedded sqlite DB which I use in this project.
Currently the DB is located in the package src/release/.
I reference the db from the code the following way:
c = DriverManager.getConnection("jdbc:sqlite:src/release/db.db3");
When I run the project from within Netbeans it works without any problem. But when I try to build it and run the created jar-file (in the dist-folder).
I get the following error message (translated from Dutch description):
Opening connection failed: path to
scr/release/db.db3:'C:\users\idxxxxx\Documents\\dist\src'
does not exist
When referencing the DB in the code like this:
c = driverManager.getConnection("jdbc:sqlite:db.db3");
and adding the db-file to the root of the output-dir (so not in the jar itself), the application works partly, but some db-data is missing in my application (empty comboboxes).
So there seems to be an issue also.
My question is:
How can I add an embedded db - sqlite in this case - in netbeans to my project so it will be part of my project?
Where should I put the db-file and how do I reference it from within my project-code?
I don't want the enduser to see any db-file in the file(s) he will receive.
so I would like the db-file to be part of the .jar if possible.
Tnx
SQLite needs separate files, even without the need to update the database.
Need ensures locking and ensures database ACID properties.
SQLite from inside .jar
SQLite is designed to work with direct file access.
SQLite may require additional privileges not available in some environments.
The SQLite data files could be extracted from the JAR to a temporary location at start.
It is not a good choice to write the database url, directly into the program.
getConnection("jdbc:sqlite:src/release/db.db3");
Let your application look for the file. If not found: error: File db.db3 not found message. Then know the user, not the program is going wrong, but it is missing the database file.
Since you are working with java, it is easy to create dynamic url.
e.g. "jdbc:sqlite:"+PathToApp +"/data/db.db3".
Then the application knows where to copy the extracted file (db.db3 from the jar ) .
extract SQlite from .jar
You can let java doing it for you.
Use jdbc:sqlite::resource:
you need the sqlite-jdbc JAR, so extract the JAR file and add into the application JAR.
DB files will be extracted to a temporary folder System.getProperty(“java.io.tmpdir”).
e.g.
[...]
import org.sql.*;
import org.sqlite.*;
[...]
try {
Class.forName("org.sqlite.JDBC");
SQLiteConfig config = new SQLiteConfig();
config.enableFullSync(true);
config.setReadOnly(false);
SQLiteDataSource ds = new SQLiteDataSource(config);
ds.setUrl("jdbc:sqlite::resource:"+
getClass().getResource("db.db3").toString());
conn = ds.getConnection();
}catch(SQLException se)
{
System.out.println("SQLError: "...");
}
Update oct. 2014
org.sqlite SQLiteConfig + SQLiteDataSource
2014 October 8th: sqlite-jdbc-3.8.6.jar Updated to sqlite 3.8.6