How to specify location of SQLite db file within Spring Maven WAR - java

I have seen several questions broaching this issue, but I haven't come across a clear answer.
I need to package a SQLite .db file into a WAR and work with that DB file within the WAR or exploded WAR.
My project is Spring, using Spring JDBC.
Everything works fine with the .db file in the classpath for testing of the non-web portion of the code. I can run unit tests against the database without problem using just
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="connectionInitSqls">
<list>
<value>PRAGMA foreign_keys = ON</value>
</list>
</property>
<property name="driverClassName" value="org.sqlite.JDBC" />
<property name="url" value="jdbc:sqlite:app2.db" />
</bean>
When I go to deploy, I'm able to pull the db into the WAR file only if I place it in the WebContent/resources directory. I can't seem to get this working with alternate URIs. (for example, jdbc:sqlite::resource:app2.db, jdbc:sqlite:WebContent:resources:app2.db, jdbc:sqlite:/resources/app2.db, etc.). I've seen answers suggesting that I tie it to tomcat's deployment directory location specifically, but I'd really rather not have the location be dependent on anything outside of the WAR.
Does anyone have a working example (using XML config for the datasource in Spring applicationContext) of a datasource mapping (includig jdbc URI string), and corresponding pom.xml maven-war-plugin specification (if applicable) to achieve the solution of letting the project work with a SQLite .db file stored with the project in its WAR?
Thanks in advance.
--EDIT (additional clarifying information in response to comments) --
I am able to get the .db into the classes subidirectory of the WAR via this directory (or through something in the WebApps subdirectory by a workaround resource mapping in the maven-war-plugin specification), but this is not the main problem.
My issue is: How do I reference the .db via relative URL/URI once it is within the WAR.
I need to point the jdbc driver to this location via a relative path so that it can be accessed regardless of deployment location.
I have options of absolute URL on the filesystem (I've gotten direct location on my computer to work with
or path within Tomcat, but again, by hard-coded URL, or best case, URL tied to CATALINA_BASE with
<property name="url" value="jdbc:sqlite:/var/lib/tomcat7/webapps/APPNAME/WEB-INF/classes/app2db.db" />
I've seen it suggested that I use
<property name="url" value="jdbc:sqlite:${catalina.base}/webapps/APPNAME/WEB-INF/classes/app2db.db" />
though this does not seem to work with my installation (and is still not an optimal solution, as it is tied to the surrounding deployment location).
jdbc:sqlite allows mapping of relative paths using no preceding forward slash, but I can't get this to work within the war with something like
<property name="url" value="jdbc:sqlite:WEB-INF/classes/app2db.db" />
This is what I'm looking for -- the relative path mapping such that I can send the .db off with the WAR and just tell someone to deploy to tomcat -- or any server, within reason, since I have the jars needed to execute mostly packaged up with the app through Maven --(even if their directory structure is unusual or they don't have path variables mapped), and have it still be able to access the database with rw access from within the exploded WAR.

When I go to deploy, I'm able to pull the db into the WAR file only if I place it in the WebContent/resources directory.
If I place my.db in Maven's default for resources <project>/src/main/resources/my.db it is packaged in /my.war/WEB-INF/classes/my.dbhere.

Related

Distributing a java app with database

I have a java application which I will be distributing to Mac and Windows OS systems. The app uses hibernate to communicate with an SQL Lite database to read and write data. I have been able to generate the .jar file and used Lauchj4 to create the .exe. Since I have found out that .jars are not changeable I have included the database inside the .jar and when the application first runs it will make a copy of the database in its root folder. This is the database which the app will be communicating with.
So far that has worked fine. However when It comes to installing the app in the windows /Program Files folder I run into an issue when the app runs. When it comes to reading from the database all is good. The issue happens when I need to write to the database. An exception occurs. I believe this is because of the permissions in the program files folder because if I move that app to another folder all is well.
Is there a way to workaround this problem? I don't feel comfortable changing permissions in the program files folder. I am considering copying the database into a the user's \Application Data folder. However my hibernate configs are specified in an xml file as shown:
<!-- SQLite -->
<beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<beans:property name="driverClassName" value="org.sqlite.JDBC" />
<beans:property name="url"
value="jdbc:sqlite:database.db" />
</beans:bean>
So how can I point this bean's url property to the user's \Application Data folder at runtime?
Another thing I need to consider is... how can create a solution that will be suitable for Windows and Mac?

How to load Spring beans xml configuration from different location in Debug and Release mode

I am using Spring and Hibernate with a non-web application. I am creating the sessionFactory bean in the /src/main/resources/Hibernate.xml
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
....login, password, etc
It is okay, but when I finish some changes I want to create an executable jar file and put it into another server where is different database located. The problem is that I have to open the jar file and change database configuration everytime I create that jar file to make it compatible with external database on the different server.
The solution for this problem would be to load Hibernate.xml from the outside of the jar file.
And here is the question - how to do that?
If all that is different between the two environments is the database address and credentials, I'd recommend putting those into a property file and using placeholders in your XML configuration (docs).
You can then either access the property file as classpath resource (In Spring config, use classpath: prefix for the file path) that you can configure at runtime, or let your build system copy a different version of the file into the JAR depending on target environment (in Maven, this can be done using Assembly plugin).
The solution was to add "file:" prefix.:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:config/hibernate.properties" />
</bean>

How to get Server Home directory path in tomcat in spring bean configuration file

I have a web application running in tomcat. I have some properties in a file.
currently I am using absolute path to file in bean configuration like this.
<bean id="propertyConfigurer"
class="com.RAPropertyUtil">
<property name="location">
<value>file:/home/user/config/application.properties</value>
</property>
</bean>
I want to make it relative to server home directory something like that.
<value>${server.home}/conf/application.properties</value>
Also could I make to server independent, like if I can get home directory of any server Tomcat or JBOSS, I don't have to change this configuration
similar case might help:
file:${user.home}/.conf/${my.app.environment}/application-additional.properties
Also i have application.properties in src/main/resources where hold default value
my.app.environment=dev
and when i need another environment, i just pass VM argument like:
-Dmy.app.environment=prod

Java, Spring, Unable to find /WEB-INF/spring.properties do I need to set it somewhere besides propertyConfigurer?

I am getting an error message that Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [WEB-INF/spring.properties] cannot be opened because it does not exist. The spring.properties files does exist and is in my /WEB-INF directory (I have confirmed that it is in my build directory after building the project). I have it set on my project's .classpath directory like this:
<classpathentry kind="src" path="src/main/webapp/WEB-INF/spring.properties"/>
In my Spring application context, I have it entered like this:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/spring.properties" />
</bean>
I apologize if this is a basic question but I really am perplexed as to what the problem is and how to solve it, I have done a lot of searching on this and can't seem to figure it out. Thanks for any advice
Looking at one of my webapps that uses a PropertyPlaceholderConfigurer, I see that I put the properties in /WEB-INF/classes and then configured the PPC to use it with a Spring classpath: URL; i.e.
/WEB-INF/classes/substitution.properties
accessed as
classpath:substitution.properties
Spring supports a ServletContextResource, which you can use by leaving off the resource prefix entirely. "You will get back a Resource type that is appropriate to that particular application context", and since we are using a web context, that resource will be a ServletContextResource.
The path is from the root of your webapp. Our paths look like
<context:property-placeholder location="/WEB-INF/spring/appServlet/application.properties"/>
Your path ("src/main/webapp") suggests you are using Maven to build the project. If this is the case, put your .properties -file(s) to /src/main/resources and use "classpath:<filename>" to access them, everything under src/main/resources should be accessible through classpath without any further configuration.
Try putting the file under WEB-INF/classes/ and referring to it with value="spring.properties". I think that should do the trick.
Just put the spring.properties file under the directory src/main/webapp (alongside WEB-INF) and referring to it with
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>spring.properties</value>
</list>
</property>
</bean>

Spring WebContent Resources - Access outside ServletContext

I have a Spring Web MVC application that I'd like to serve a large, partially generated file.
I've added that file to my WebContent directory and all works fine there. However, I'd also like to access that file from my various build/deploy scripts, which read and parse the file.
My current approach is to keep a copy of the file under the src directory as well as the WebContent directory. When serving the file from the web, it uses WebContent.
When serving the file for the build scripts, it uses the following spring config:
<bean id="ringCodeData" class="com.myapp.data.RingCodeData">
<property name="rulesInputFile" value="classpath:resources/rules_copy.xml" />
<!-- <property name="rulesInputFile" value="classpath:../WebContent/rules.xml" /> -->
<!-- <property name="rulesInputFile" value="file:/WebContent/rules.xml" /> -->
</bean>
As you can see, I've tried several different approaches to get the two to refer to the same file (without resorting to copies).
File paths don't seem to work since they're based on the current directory, that changes based on whether I call a given utility class from Eclipse or from the build scripts.
How can I get these to refer to the same file?
The only other thought I have at the moment is to try to setup Spring MVC to stream the file from the classpath directory.
Your best bet is likely placing it in /WEB-INF/classes (or, if you're using an IDE, just the project's src/source folder) and use <jsp:include> to include it.
<jsp:include page="/WEB-INF/classes/resources/rules_copy.xml" />

Categories