Reading JNDI name from external properties file in Spring - spring

I am developing a Spring web application where I am using JMS as well as some datasource connection.
Now Instead of hardcoding the JNDI names of DataSource/Jms Connection Factory,I want to read them from a external properties file.
I used the following configuration::
<bean id="myProps" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath*:myFile"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
`<jee:jndi-lookup` id="dataSource" jndi-name="${DS_JNDI}" expected-type="javax.sql.DataSource"/>
But during deployment time it is throwing an error in weblogic:::
javax.naming.NameNotFoundException: Unable to resolve '${DS_JNDI}'. Resolved ''; remaining name '${DS_JNDI}'
Is it like that I cannot put a property file entry when using <jee:jndi-lookup>???

you should remove the star after classpath, and add properties of file extension
<bean id="myProps" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:myFile.properties"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:myFile.properties</value>
</list>
</property>
</bean>
This is the correct solution of the problem.I think from Spring5.x onwards it has stopped appending ".properties" extension.

Related

spring replace bean name in config file with value from property file

I have a bean config file as follows
<bean id="myFactory" class="com.public.Factory">
<property name="dataSourceAdaptor" ref="${value.from.property file}Adaptor" />
</bean>
How do i achieve this.
I added the following to top of the config file
<util:properties id="myProperties" location="classpath:app.properties"/>
and then tried to refer to the value using ${} but i get an error stating ${value.from.property file}Adaptor is not a valid bean
I cannot put the whole name (xyzAdaptor) in the property file as the value in the property file is an institution and there are multiple adaptors for each institution.
for example xzyDisplayAdaptor, xyzProductAdaptor, xyzDatasourceAdaptor
The xyz client can change to say abc client and i want to be able to change the value in property file to abc and all the abc related beans will be injected.
The util:properties tag is used to create an instance of java.util.Properties. I think what you need is a PropertyPlaceholderConfigurer.
e.g.,
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" scope="singleton">
<property name="searchSystemEnvironment" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:app.properties</value>
</list>
</property>
</bean>
Try this with Spel:
<util:properties id="myProperties" location="classpath:app.properties"/>
<bean id="myFactory" class="com.public.Factory">
<property name="dataSourceAdaptor" ref="#{'${value.from.property file}'+'Adaptor'}" />
</bean>

deployment for different environments with maven and spring

I've got two properties files:
environment.properties:
- project.host.db3.database.name=oracle
application.properties:
- database.name=${project.host.db3.database.name}
The first one represents the environment variables and the second one the properties to be used in a spring project, in this configuration i try to set the environment.properties but of course it doesn't work:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:environment.properties" />
</property>
</bean>
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
<!-- bean using database.name -->
Is it doable?, and if not, how do people have agnostic properties in their projects (like database.name), and only one file (war, jar, etc.) to be deployed?
Well, it seems it's doable for beans xml defined as long as you define your properties it like this:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
depends-on="systemPropertiesLoader">
But if you ever try to access the properties from a servlet:
this.getClass().getClassLoader().getResourceAsStream("application.properties");
chances are you get this:
bad port configuration: ${project.host.db3.database.port}
java.lang.NumberFormatException: For input string: "${project.host.db3.database.port}"
In answer to yorkw, now i can have the same war to be deployed in several environments and configure the host with -Denvironment=development, so i can deploy a properties file for development, production, etc. and simply use:
<bean id="systemPropertiesLoader"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}" />
<property name="targetMethod" value="putAll" />
<property name="arguments">
<util:properties location="classpath:**${environment}/**environment.properties" />
</property>
</bean>
Otherwise i should have the application.properties substituted before deployment for every environment. I'm sure there are better solutions than this.

Java Web Project Class Path

I am using Eclipse Helios. I have a Dynamic Web Project.
I want to load a property file using Spring 3.1.0 for which I use the following configuration
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:resources/dc-config.properties</value>
</property>
</bean>
This folder by name resources is present in WEB-INF/classes directory
But when I try to start my Tomcat 6 Server I get the following error
Caused by: java.util.MissingResourceException: Can't find bundle for base name dc-config, locale en_US
Isin't my resources folder in the classpath as it is in the classes folder which in turn is in the classpath ?
Please let me know if I am missing something here
wrong bean class maybe ?
Try this:
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:resources/dc-config</value>
</list>
</property>
</bean>
Maybe the problem is a small typo. Try either
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"> <!-- not locations -->
<value>classpath:resources/dc-config.properties</value>
</property>
</bean>
or
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:resources/dc-config.properties</value>
</list>
</property>
</bean>

Read property file outside war using spring

enter code hereI have a property file placed in the etc folder. "myapplication.properties" and few other property files in each sub module.. i am try to do the following
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>${config}</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
I am trying to do mvn -Dconfig=~/my.properties jetty:run
The properties are read from application.properties but not for config..
While running application i get the ${jdbc.url} not correct .. This url is present in my.properties ..
How can this be achieved ?
Thanks
This is what I had, to run it
<bean id="placeholderConfigConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName">
<value>SYSTEM_PROPERTIES_MODE_OVERRIDE</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:${config}" />
</bean>
And add -Dconfig=/var//my.properties in the MAVEN_OPTS.. and did mvn jetty:run
Another one line solution I found.. instead of making verbose configuration just do
<context:property-placeholder location="file:${config}"/>
I think this feature becomes available in spring 3.1 via the new Environment abstraction. See the following spring blog for details:
http://blog.springsource.com/2011/02/15/spring-3-1-m1-unified-property-management/.
If spring 3.1 is not an option you can hard-code the filename and path in the spring xml configuration file to some well-known location and then developers can symlink against it.

Loading .properties file in a jar from my web-app

I have created a JAR that I need to use in my WEB-APP. Both are created with spring framework. I would like to load a .properties file outside the JAR file, in the main context of the web-application. And I want to do it with the facilities that Spring offers us.
I've tried to do something like this in my spring.xml file inside the JAR:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/classes/my.properties</value>
</property>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="myJob" />
<property name="cronExpression" value="${my.cronExpression}"/>
</bean>
</property>
</bean>
Trying to load my.cronExpression from my.properties file. But without any success.
I always get this error:
Could not resolve placeholder 'my.cronExpression'.
I've tried to change the location with many variants, using classpath:/WEB-INF/classes/my.properties etc...
But I'm not able to load the configuration file.
Thanks for your help.
Use classpath:my.properties - /WEB-INF/classes is root of your classpath.
Try declaring it as follows:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/WEB-INF/classes/my.properties</value>
</property>
<property name="ignoreUnresolvablePlaceholders">
<value>true</value>
</property>
</bean>
I have gone through your code and want you to try this code snippet
It works well for me :)
<bean id="placeholderProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:/WEB-INF/classes/my.properties" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="order" value="1" />
</bean>

Resources