Spring Application data source configuration from external file - spring

Is it possible to create a data source by reading the values from an external file which is not bundled with WAR in spring application.

You can use the #PropertySource annotation to load your db properties and you can load the properties from file location like below:-
#PropertySource("file:${app.home}/db.properties")
reference link here:-
https://www.mkyong.com/spring/spring-propertysources-example/
For XML based configuration sample code could be like below:-
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>${app.home}/db.properties</value>
</list>
</property>
</bean>

you can setup your datasource in any properties file, and then you have to provide the classpath for that file in your catalina.sh where you are running your war.
don't forget to load that property file in in your application.

Related

Can Spring support multiple messages.properties files in classpath?

There are a JAR A and JAR B, both have messages.properties in classpath /
And there is WAR C, which has dependencies on JAR A and JAR B.
And when I start WAR C I can only get i18n message from JAR A or JAR B.
So, how can Spring support multiple messages.properties files in classpath?
BTW, WAR C is a spring boot project, and spring.messages.basename=messages
Problem solved.
According to this question Does Spring MessageSource Support Multiple Class Path?
have to ditch ResourceBundleMessageSource and write a custom implementation of MessageSource (most likely by subclassing AbstractMessageSource) which uses PathMatchingResourcePatternResolver to locate the various resources and expose them via the MessageSource
I make a copy of ReloadableResourceBundleMessageSource and write the code by this guide and problem solved.
Yes, Spring supports loading multiple Properties. But properties should be unique. If we have same properties in the two Properties Files then the file which will be loaded later will override the previous Properties from previous file.
For example, if the Properties file from JAR A has two properties {USERNAME, PASSWORD} and JAR B Properties file also has the same two properties then you'll get {USERNAME, PASSWORD} from the file which is loading later.
You can use wildcard to import all the Property Files with same name on your classpath.
In Spring you can mention different Properties files in the form of Array as follows:
<context:property-placeholder
location="classpath:war.properties,
classpath*:message.properties"
ignore-unresolvable="true"/>
or
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:war.properties</value>
<value>classpath*:message.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>

Weblogic Spring Dependency Injection from flat-files on the file-system

I have an application deployed into Oracle Weblogic 10.3. In my .ear files, I use spring injection from xml files in the ear files. I would like to also perform dependency injection from xml files placed on the server file-system. We do something similar to this in Karaf, where we place our configuration files for bundles in the conf directory in the server itself. Is there a similar way to do this in weblogic?
You can ask spring to read properties from file systems as below;
<!-- Reads application properties and uses them in the application context -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="locations">
<list>
<value>file:D:\somefolder\application.properties</value>
<value>classpath:com/foo/sp.properties</value>
</list>
</property>
</bean>

Spring application context external properties?

i have a Spring application and its working well so far. Now i want the properties file in an external config folder and not in the packed jar to change things without the need to repack. This is what i got:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- <property name="locations" value="classpath:/springcontext.properties"/> -->
<property name="locations" value ="config/springcontext.properties" />
The outcommented one is working and the other one i dont get to work :/ Can someone help?
Edit:
Thx 4 comments so far.
Maybe my question wasnt clear enough :). I perform a Maven build and everything will be packaged and i want this folder to be NOT in the package nut next to the outcomming jar and in this folder i want the properties file. possible?
You can try something like this:
<context:property-placeholder
location="${ext.properties.dir:classpath:}/servlet.properties" />
And define ext.properties.dir property in your application server / jvm, otherwise the default properties location "classpath:/" (i.e., classes dir of .jar or .war) would be used:
-Dext.properties.dir=file:/usr/local/etc/
BTW, very useful blog post.
You can use file prefix to load the external application context file some thing like this
<context:property-placeholder location="file:///C:/Applications/external/external.properties"/>
<context:property-placeholder location="classpath*:spring/*.properties" />
If you place it somewhere in the classpath in a directory named spring (change names/dirs accordingly), you can access with above
<property name="locations" value ="config/springcontext.properties" />
this will be pointing to web-inf/classes/config/springcontext.properties
This blog can help you. The trick is to use SpEL (spring expression language) to read the system properties like user.home, to read user home directory using SpEL you could use #{ systemProperties['user.home']} expression inside your bean elements. For example to access your properties file stored in your home directory you could use the following in your PropertyPlaceholderConfigurer, it worked for me.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:#{ systemProperties['user.home']}/ur_folder/settings.properties</value>
</property>
</bean>
This question is kind of old, but wanted to share something which worked for me. Hope it will be useful for people who are searching for some information accessing properties in an external location.
This is what has worked for me.
Property file contents:
PROVIDER_URL=t3://localhost:8003,localhost:8004
applicationContext.xml file contents: (Spring 3.2.3)
Note: ${user.home} is a system property from OS.
<context:property-placeholder system-properties-mode="OVERRIDE" location="file:${user.home}/myapp/latest/bin/my-env.properties"/>
<bean id="appsclusterJndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
<prop key="java.naming.provider.url">${PROVIDER_URL}</prop>
</props>
</property>
</bean>
${PROVIDER_URL} got replaced with the value in the properties the file
One way to do it is to add your external config folder to the classpath of the java process. That's how I've often done it in the past.
<context:property-placeholder location="file:/apps/tomcat/ath/ath_conf/pcr.application.properties" />
This works for me.
Local development machine path is C:\apps\tomcat\ath\ath_conf and in server /apps/tomcat/ath/ath_conf
Both works for me

Spring PropertyPlaceholderConfigurer not replacing placeholder

I want to pass the WSDL url for an internal web service into my Spring beans.xml dynamically, using a PropertyPlaceHolderConfigurer.
Here's the scenario:
My web application is deployed in WebLogic 10.3.
The WSDL url is contained in a properties file that is located outside my application (directly under the corresponding domain folder, while my application is inside the autodeploy folder). I set the location of this properties file in my domain's setDomainEnv.cmd file like below:
set JAVA_PROPERTIES=%JAVA_PROPERTIES% %CLUSTER_PROPERTIES% -Dproperty.file.path.config=%DOMAIN_HOME%\Service.properties
This is what my Service.properties file contains:
Service.WSDL.PATH=http://localhost:8088/mockServiceSoap?WSDL
My Spring beans.xml configuration:----
<bean id="file.path" class="java.lang.System" factory-method="getProperty">
<constructor-arg index="0"><value>property.file.path.config</value></constructor-arg>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" ref="file.path"/>
</bean>
<bean id="myServiceId" class="com.test.service.ServiceImpl">
<property name="myServiceSoap">
<ref bean="myService"/>
</property>
</bean>
<bean id="myService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="com.test.service.ServiceSoap"/>
<property name="wsdlDocumentUrl" value="${Service.WSDL.PATH}"/>
</bean>
I enabled DEBUG log specifically for PPC and this is what I saw in my application log:
INFO org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 178 - Loading properties file from URL [file:D:/bea10.3/user_projects/domains/my_domain/Service.properties]
So, it seems that although the Service.properties file is getting loaded by PPC, the ${Service.WSDL.PATH} is NOT getting replaced.
What am I doing wrong here?
Also, how can I find out if PPC tried replacing the value of the placeholder and with what value? I was hoping the log file would contain that info but there was nothing there.
Any help is appreciated.
I've figured out, that PropertyPlaceholderConfigurer needs to be declared first in the application Context file, otherwise there's no guarantee of the load order. It took me a few hours to realize this.
Try moving the "file.path" bean into the PropertyPlaceHolderConfigurer's location property.

Spring's PropertyPlaceholderConfigurer with property in a jar file

I have multiple property files I need to refer to. Below I can refer to two that are on the classpath.
How do I refer to a property file with in a jar file ?
<bean id="placeholderConfig" name="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/my_test.properties</value>
<value>classpath:config/some_other.properties</value>
</list>
</property>
If the JAR is in the classpath, then you can reference the properties file inside just like any other resource. Just specify the location of the properties file within the JAR file.

Resources