Distributing a java app with database - java

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?

Related

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>

Tomcat properties configuration file location

I'm new to Java (around 2 months Java experience after coming from a .Net background). I've been asked to support a Java application which uses Spring, J2EE, and an Oracle database.
We have an issue with our deployment process which I'm struggling to understand.
The Java application in question has database connection details in an application.properties file. Its location appears to be configured from a Spring configuration file using the following line:
<context:property-placeholder location="classpath:config/application.properties,classpath:config/bookings.properties" ignore-resource-not-found="true" />
On our Development Tomcat server, the application (called Bookings) looks in this location for the application.properties file:
/usr/share/tomcat/webapps/Bookings/WEB-INF/classes/config
Which is what I would expect, looking at the Spring configuration.
However, on Production Tomcat, the application looks in a different location:
/usr/share/tomcat/lib/config
(In this directory, the file is called bookings.properties.
The original developer has left the company and I have no idea why it would look in a different location for the file (and a different filename).
Any ideas what I can look at, or where this could be configured? It should be noted that both files (application.properties and bookings.properties) are present on both Tomcat servers, so I don't understand the discrepancy?
We have re-deployed the same WAR file to both development and production, and the discrepancy still exists, i.e. the servers still look in different places.
classpath is a directory where you could put some resources (to make it simple, further details on the link).
that's a variable and it's added to the launch command, sometimes it's a bit hidden. But that's the way it works.
May be you can watch in $TOMCAT_DIR\bin\catalina.sh to see how the classpath is defined.
In your case, the folders contained in your classpath are different between development server and production server. That's totally normal.
However, you say that in production the file is named bookings.properties.
But with this line :
<context:property-placeholder location="classpath:config/application.properties,classpath:config/buyer-request.properties" ignore-resource-not-found="true" />
we see that you never try to load a file named booking.properties.
So ask yourself why the file is called booking.properties. And rename it application.properties to see what happen.
Hope this help

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

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" />

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

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.

Categories