Hibernate Config in Properties outside of the WAR without Spring - java

I have this structure in my Jboss 6.4, and I need to access outside of the war to another folder to take the configuration for Hibernate:
/usr/webapps/MYAPP/deployments/MYAPP.war
/usr/webapps/MYAPP/appconfig/hibernate.properties
I have to use this pattern, and I'm using Hibernate 4.2, in my case I need to take the content of the properties file to use it in my hibernate.cfg.xml like here:
<property name="connection.driver_class">${db.driver}</property>
<property name="hibernate.dialect">${db.dialect}</property>
<property name="hibernate.connection.url">${db.url}</property>
<property name="hibernate.connection.username">${db.username}</property>
<property name="hibernate.connection.password">${db.password}</property>
hibernate.properties:
db.username=usernameTest
db.password=passwordTest
db.driver=driverTest
db.url=urlTest
db.dialect=dialectTest
What should be the best practice to do this, I was watching some cases with Spring here, but in my case it's only with JEE

Related

${project.name} lost when using PropertyPlaceholderConfigurer

I'm using Maven to build a Spring (3.0.5.RELEASE) project. In my applicationContext.xml I use PropertyPlaceholderConfigurer (to load properties from the DB) like so:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="configurationConverter"/>
</bean>
The properties I want to access in the DB works fine, but ${project.name} and ${project.version} stops working. Where do these properties come from originally? And most importantly: how can I get them back?
If you use the Maven Resources plugin and set filtering=true, then you can replace Maven variables like 'project.version'. See https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html

Hibernate 3.2.5 with Play Framework 1.2.5

I am trying to use Hibernate 3.2.5 with Play framework 1.2.5
In Hibernate I am having two files:
1) cfg.xml file (containing the db config details along with some additional properties
2) hbm.xml file (containing the mapping between the java bean and the db table
For getting connected to the oracle 10g db, I am providing the db details in the application.config files like this and the connection is successful also when I start the server:
db.url=jdbc:oracle:thin:#localhost:1521/orcl
db.driver=oracle.jdbc.OracleDriver
db.user=system
db.pass=tiger
I want to know Where will I place the hbm.xml file (for mapping details) and the cfg.xml file for the remaining properties other than db connecion details?
Please let me know about this.
Regards,
Starting from the root directory of your application:
the hibernate.cfg.xml must be placed inside the app directory
the mapping files (the hbm files) where your models classes are defined, usually inside the app/models/ directory
Inside your hibernate.cfg.xml the mapping attributes should be something like:
<mapping class="models.yourHmbFile1"/>
<mapping class="models.yourHmbFile2"/>
Btw, I find easy to use the hibernate annotations instead of the hbm - xml mapping. Easier to write and to mantain.
If you prefer to annotate your model classes, you can delete the hbm files and directly map your annotated classes in your hibernate.cfg.xml.
In the application.conf you've to specify the data you have already added:
db.url=jdbc:oracle:thin:#localhost:1521/orcl
db.driver=oracle.jdbc.OracleDriver
db.user=system
db.pass=tiger
Also in the hibernate.cfg.xml you need to specify the connection data:
<property name="hibernate.dialect">...</property>
<property name="hibernate.connection.driver_class">...</property>
<property name="hibernate.connection.url">...</property>
<property name="hibernate.connection.username">...</property>
<property name="hibernate.connection.password">...</property>

how to read properties file in spring project?

Before post this Question, I google to get Properties from Spring project(Its NOT web-based project). I am confused as every one are talking about application-context.xml and have configuration like
However, I am working on normal Java Project with Spring(NO Web-app and stuff like that). But I would like to get some common properties from properties file and that needs to be used in JAVA file. How can achieve this by using Spring/Spring Annotations?
Where I should configure myprops.properties file under my project and how to invoke through spring?
My understanding is application-context.xml is used ONLY for web based projects. If not, how should I configure this application-context.xml as I do NOT have web.xml to define the application-context.xml
You can create an XML based application context like:
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
if the xml file is located on your class path. Alternatively, you can use a file on the file system:
ApplicationContext ctx = new FileSystemXmlApplicationContext("conf/appContext.xml");
More information is available in the Spring reference docs. You should also register a shutdown hook to ensure graceful shutdown:
ctx.registerShutdownHook();
Next, you can use the PropertyPlaceHolderConfigurer to extract the properties from a '.properties' file and inject them into your beans:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:com/foo/jdbc.properties"/>
</bean>
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
Lastly, if you prefer annotation based config, you can use the #Value annotation to inject properties into you beans:
#Component
public class SomeBean {
#Value("${jdbc.url}")
private String jdbcUrl;
}
As of Spring 4, you can use the #PropertySource annotation in a Spring #Configuration class:
#Configuration
#PropertySource("application.properties")
public class ApplicationConfig {
// more config ...
}
If you would like to have your config outside of your classpath, you can use the file: prefix:
#PropertySource("file:/path/to/application.properties")
Alternatively, you can use an environmental variable to define the file
#PropertySource("file:${APP_PROPERTIES}")
Where APP_PROPERTIES is an environmental variable that has the value of the location of the property file, e.g. /path/to/application.properties.
Please read my blog post Spring #PropertySource for more information about #PropertySource, its usage, how property values can be overridden and how optional property sources can be specified.
You don't have to use Spring.
You can read with plain java like this:
Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName));
Can you figure out how your project will be used in the whole app? If your project is used as a build path for a web app and the configuration in your project is achieved through spring annotations, so no doubt you are puzzled about how to add an application.xml file. My suggest is you have to announce the guys who will use your project, tell them what you need and you just need to add #Value("${valuename}") in your code.
Create new property file inside your src/main/resources/ directory and file extension must be .properties e.g. db.properties
Write following context properties in your spring xml configuration file:
<context:property-placeholder location="db.properties"/>
Usage: ${property-key}

Springframework beans

I have not until now had worked with spring framework. I tried reading and reading the spring documentation but could not locate the answer to the following simple question.
The application is ant built to a build directory. So far when I tried to start the JBOSS (or apache) server, the logs says it is unable to build the bean because it could not find
var/config/madagascar.prop.
.
WRT the following snippet in WEB-INF/applicationContext.xml
<bean id="application.home" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass" value="java.lang.System"/>
<property name="targetMethod" value="getProperty"/>
<property name="arguments">
<list>
<value>application.home</value>
</list>
</property>
</bean>
<bean id="propertyFile" class="java.io.File">
<constructor-arg ref="application.home"/>
<constructor-arg value="var/config/madagascar.prop"/>
</bean>
Could you tell me where {application.home} and var/config are expected to be located?
Is it relative to the Eclipse project home or relative to WEB-INF?
What is the bean id="application.home" attempting to do - is it trying to read the value for "application.home" from the system env?
"application.home" is the runtime value of System.getProperty("application.home") and the "propertyFile" bean is a java.io.File object returned from calling new java.io.File(String, String) with the whatever application.home is set to and that second String.
If the bean you wanted was 'propertyFile', the runtime equivalent would be:
File file = new File(System.getProperty("application.home"),"var/config/madagascar.prop");
That config is a very Spring 1.x (read old) way of doing things. XML is a very kludgy way to perform many of these types of initialization, and that's one of the reasons that Spring's #JavaConfig approach became so popular.

Elegant ways to separate configuration from WAR in Tomcat

I am trying to find the best way to pass complex configurations in a Spring webapp running in Tomcat. Currently I use JNDI to pass data sources and strings from the Tomcat context into the webapp, and this works well.
But, lets say I need to select the implementation of a notification service. There is no way that Spring can conditionally select which bean to instantiate (although in the past I have used a JNDI string to import a predefined configuration of beans by setting contextConfigLocation).
I've also seen many webapps which supply a configuration tool which will create a custom WAR file. In my opinion this is bad form, if for no other reason than it prevents the redeployment of WARs from upstream without many checks to ensure all the configuration has been re-applied.
Ideally I would be able to supply a Spring XML file which existed on the filesystem, outside of the webapp. But, the spring import directive does not seem to resolve ${} variables, making it impossible to supply customisations.
Are there any techniques I can employ here to properly separate complex configuration from the webapp?
If I have a specific set of beans that I'd like to configure, and this configuration must be separated from the WAR file, I usually do the following:
In applicationContext.xml:
<!-- here you have a configurer based on a *.properties file -->
<bean id="configurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file://${configDir}/configuration.properties"/>
<property name="ignoreResourceNotFound" value="false" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="searchSystemEnvironment" value="false" />
</bean>
<!-- this is how you can use configuration properties -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${smtp.host}"/>
</bean>
In configuration.properties:
smtp.host=smtp.your-isp.com
You also need to start Tomcat with -DconfigDir=/path/to/configuration/directory
If you are using Spring 3, you can take advantage of the Spring Expression Language. Let's say you have two applications app1.war and app2.war and they require a properties file named config.properties. The applications will be deployed with context paths /app1 and /app2.
Create two directories app1 and app2 in a common directory, eg. C:\myConfig\app1 and C:\myConfig\app2.
Put config.properties inside app1 and another config.properties inside app2.
Then create a file ${CATALINA_HOME}/conf/[enginename]/[hostname]/context.xml.default with the contents:
context.xml.default:
<Context>
<Parameter name="myConfigDirectory" value="C:/myConfig" override="false"/>
</Context>
The parameter myConfigDirectory will be available to all the applications on the host. It is better to create this parameter in context.xml.default rather than in server.xml, because the file can be changed later without restarting tomcat.
In the applicationContext.xml inside war you can access config.properties using the SpEL expression: "#{contextParameters.myConfigDirectory + servletContext.contextPath}/config.properties", so for example you can write:
applicationContext.xml:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:#{contextParameters.myConfigDirectory + servletContext.contextPath}/config.properties" />
</bean>
The expression will get expanded to C:/myConfig/app1 for application with contextPath /app1, and C:/myConfig/app2 for application with contextPath /app2. This will make the applications access the config.properties file based on their contextPath.
If you want to be fully portable between web containers you cannot rely on anything outside your WAR-file. In Tomcat the SecurityManager allows you to discover the physical location on disk where your code is deployed, and you can then use that knowledge to navigate the disk to a location where your configuration file is placed.
See e.g. Determine location of a java class loaded by Matlab

Categories