Where should I place my sqlite database in my java maven project - java

Since putting in resources folder made the database in to read-only. I wanted my database to be in the jar file.

As noted in comments by James_D:
The contents of the resources directory will become part of the jar file. And anything placed in the jar file is necessarily read-only.
How to rectify this depends on what you want to do.
You can install it on another machine and access over the network.
You could create a new database on the local machine.
see System.getProperties() documentation for finding local file locations.
If you want to seed data from an existing database in resources, then copy it out.
If read-only mode is sufficient, you may be able to access the db in read only mode when it is stored in a jar, though I wouldn’t guarantee that it would work as expected.
Beyond these generalities I don’t think there is specific info to be provided without more specifics on your app.
For a tutorial on connecting JavaFX and SQLite:
eden coding JavaFX db tutorial.

Related

How do I change where images are stored with appengine devserver

For local development with appengine, I need to change where uploaded images are stored with the GCS service so that they are persisted across builds. Right now, a new build wipes out the target directory along with the images in the appengine-generated directory.
I had the same problem with the datastore but was able to fix this by setting a property to use a datastore located in my repo outside of the target directory.
-Ddatastore.backing_store=../../local_db.bin
Is there a comparable property for the images/files saved using the GCS service?
With the Python local server, --storage_path=... determines where everything is stored ("Datastore, Blobstore files, Google Cloud Storage Files, logs, etc", to quote the docs) unless explicitly overridden. It doesn't appear that the possible values listed for Java at https://cloud.google.com/appengine/docs/java/tools/localunittesting/javadoc/constant-values encompass a similarly all-inclusive path, however.
As #alex pointed out, there is a parameter to define where all local files are stored for python and it exists for java too.
For java the parameter is --generated_dir=<path> which is a server param not a JVM option.
Also note that this overwrites the usage of -Ddatastore.backing_store=<local_db.bin>.
There documentation on this feature here: https://cloud.google.com/appengine/docs/java/tools/devserver?hl=en

On the resources (classpath) folder and database.

I'm wondering if it is ok to use your resource folder as a database folder. I have a an application that run a small semantic database. Most of the work is done in memory but from time to time i need to commit the data in the database. It also saves the data, for when the program will be restarted again. I'm asking this because it sounds weird to me to have a growing Jar/bundle. Indeed, by default sbt or maven, put your resources in your jar/bundle.
Can someone enlighten me a bit about how to properly use the resources folder. Shall it be read only ?
AFAIK you can't overwrite files that are in .jar from code. But you could create a file in same location to save any data (and use default data if file does not exist).
Resources should be considered read-only, as the entire application could reside in a .jar. Also some resources are cached.
However you may use a database as resource for an initial database template. This you can copy to a subdirectory of the user's home, which also makes this application multi-user / multi-tenant.
InputStream dbIn = SomeClassInJar.class.getResourceAsStream("/data/initial.hdb");
Path dbPath = Paths.get(System.getProperty("user.home"), ".myapp", "db.hdb");
Files.createDirectories(dbPath.getParent()); // .myapp
Files.copy(dbIn, dbPath, StandardCopyAction.REPLACE_EXISTING);
The REPLACE_EXISTING maybe not to use.

Java app connecting to SQLite database

I am developing a very small java application for people on my network. All it does is accept options for user input, grabs data from multiple SQLite databases (no updating to actual database!), and spits out a calculation. It works fine in eclipse but I cannot find a solution for running it as one consolidated application that I can distribute to my coworkers.
I am reading that JDBC is not able to query databases inside jars. I am also reading that it is dangerous and slow to keep the databases on the shared network. Finally, I am told I can create a temporary database when the program runs but I haven't a clue on how get the databases to copy into the temporary ones if the program cannot find them in the first place.
Here is the syntax I am using to access the databases:
Connection con = DriverManager.getConnection ("jdbc:sqlite:src/productLine.db", config.toProperties());
The database is located in the src folder. My questions are:
Is it possible (if advisable) to get the runnable jar to read a database inside of it?
Are there alternative options for this sort of problem?
Am I storing my databases properly or should they have their own source folder?

Saving properties for Java application during setup

I've created a Java application that is basically an interface to a MySQL database. It helps organize and keep track of data. We are using it in my workplace with no problem - I have exported it from Eclipse as a jar file and given everyone a copy of this jar file.
Now we want to make this software available to other workplaces. The problem is that the URL, username, and password for the database are hardcoded in the application. I want to create a setup process for it so that when someone downloads it, they go through a wizard that downloads MySQL and sets up the database wherever they choose. The person can then distribute the jar file to everyone in their workplace without them having to do the setup, because everyone will be accessing the same database.
This process must save the database URL, username, and password somehow so that the people in the workplace can run the jar from whatever computer. This makes me think that they should be saved inside the jar... is a Properties file that I need? Can I put a Properties file inside the jar and allow it to be edited during the setup process?
Any guidance is greatly appreciated, I'm very new to this!
==================================================================================
EDIT: I think what I'm going to do now is let the user install MySQL and set up their database themself. As the answers below suggested, having this automatic might be more trouble than it's worth, as I would have to deal with everyone's different platforms, preferences for setting up the database, security concerns, etc. Once they do this, they will just download my jar file.
I've added a properties file to my jar file to store the database URL, username, and password. This file is initially empty, so when the user runs the jar for the first time, the program will attempt to access the properties file, see that it's empty, and prompt the user to enter this information. It will then extract the properties file from the jar, edit in their information, and stick the properties file back into the jar. Then, the person should be able to distribute the updated jar to their coworkers and they should all be able to open it without having to supply that information. I've got this part almost working. I'm also going to add the ability to "reconfigure" the program - in case the user moves their database - by calling the same method (they would again have to distribute the new version of the program).
Next I want to try securing the properties file somehow by encrypting it or obfuscating the code (although I think that only works for class files and not text files...?). My concern is that anyone in the workplace can unjar it and open the properties file, then use the URL, username, and password to access the database on their own and cause damage. Ideally, no one would be able to unjar it at all except for the program itself.
If anyone has other concerns about my method, please let me know!
First, it would not be trivial to set up a database in a central location in a workplace so that it is accessible by different users. Also, there is the problem of the first user setting it up and then re-distributing the application to others.
Answering the technical questions - the easiest way would be to unjar to a known location, edit the properties file at that location, and then re-jar to a new file, perhaps with a suffix specific to that workplace.
You could save the property file in a subdirectory of the user home directory, obtained by System.getProperty("user.home). Also, have a look at the Apache Commons Configuration library.
How do you deploy your Application?
If you're using Webstart, you could define your properties in your jnlp-File and access them with System.getProperties(...);
Take a look at HSQLDB. It is a lighter weight db that is rely easy to setup. You can configure it to me the db if it doesn't exist and us it if it does. However, if you need something like MySQL and want to have many users connecting to it from different workstations, I would not recommend downloading and configuring it through an install process. There will be a lot of network and security concerns. As a side note a properties file is a good idea.
This is a link that explains some of the security concerns to think about. Also, thinking about this a little more, users might not have the necessary permissions to setup/configure a db server. It is probably safer/easier for you in the long run to allow them to set up the db server and have them put a properties file in your applications classpath.
As a side note, have you considered making this a web application? That could make things even simpler for you, people wouldnt have to download anything, and there would be no setup for most users.

Java OutputStream equivalent to getClass().getClassLoader().getResourceAsStream()

I am attempting to store the change made to my application's properties. The .properties file is located in resources package, which is different from the package that contains my UI and model.
I opened the package using:
this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")
Is there a functional equivalent of this that permits me to persist changes to the Properties Class in the same .Properties file?
In general, you cannot put stuff back into a resource you got from the classloader:
Class loader resources are often read-only; i.e. held in read-only files / read-only directories.
If you got the resource from a JAR file, JAR files are not simply updateable. (To "update" you need to extract the old JAR's contents and create a new JAR with the updated contents. It is all to do with the structure of ZIP files ...)
In some cases, the class loader resource will have been downloaded on-the-fly, and there is no way to push changes back to the place where you downloaded from.
Even if you can update a resource you got from the classloader, it is a bad idea / bad practice.
Doing this "pollutes" the clean application installation with a user's preferences. Among other things, this means that the installation cannot be shared with other users (unless you handle preferences for multiple users ...).
There are security issues with having applications installed as writeable so that embedded preferences can be updated. Think viruses! Think one user who might be inclined to trash another user's preferences!
There are administration issues with having user-specific copies of applications. And if the user has to install his own copy of an app, there are potential security issues with that as well.
There may be technical issues with file locking or caching on some platforms that either get in the way of (safe) updates or make it difficult for an application to load the updated resource without a restart.
Finally, this is NOT the way that system administrators (and educated users) expect software to behave. Java applications should deal with user preferences in the expected way:
You can use the Java Preferences API.
You can write a Properties file containing the preferences to an OS-appropriate user-writable directory.
On Windows, you could use a Windows-specific API to store the preferences in the Windows registry, except that this makes your application Windows dependent. (I can't see any real advantage in doing this, but I am not a Window expert.)
When you wrap your app up as a JAR file, your properties file will be one (possibly compressed) file within that JAR, and it would be a bad idea to try to write to your own JAR.
getResourceAsStream() is meant to open resources for reading, and these can be anywhere on the classpath. You can't write to URLs or inside JARs, you can only write to files, so it doesn't make sense to give you the same API for output.
Find yourself a directory you're allowed to write into, and write your properties there.
It may be a good idea to copy your properties from your installation classpath (possibly inside a JAR) directly out to a file if it doesn't yet exist, as a first operation upon application startup. This will give you a properties file you can write to, yet the master copy of this properties file will come from your project deliverable.
It sounds like you want to store user preferences. Consider using the Java Preferences API for that.
In addition to Carl's answer, if you're going to read and write to this file frequently, and expect that your application will expand in scope, consider whether to go one step (or several steps) further and use a file-based database like SQLite. There are a few JDBC wrappers for SQLite that would allow you to go beyond the basic string key-value lookup that the Java Properties interface provides.
even though writing the file into resources is not good practical, we still need to do it when our application only run in IDEA locally without deployment, then we can do it as below:
URL resource = Thread.currentThread().getContextClassLoader().getResource("settings.properties");
String path= resource.getPath();
OutputStream outputStream = new FileOutputStream(path);
//outputStream write

Categories