I am developing a Java desktop application and I am using Spring with it. Now I want to inject log4j to my classes using applicationContext.xml. My log4j properties file is placed in a source folder Resources/log4j.properties
During my search I found out that there are many way to it when its a web application but I found out no help regarding a desktop application.
I am using Apache commons interfaces in my source code and now I want to inject log4j dependency.
Kindly, help me out..
By default, Log4J will simply read its configuration from a "log4j.properties" file in the root of the class path. Since you placed your log4.properties file in the resources source folder, this should work.
If you do not want to store your log4j configuration in your class path then you can use something like this :
<bean id="log4jInitialization"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>myPropertiesFolder/log4j.xml</value>
</list>
</property>
</bean>
Related
One of our team has implemented loading properties this way (see pseudo code below) and advises this approach is right as the client application using this is free to keep the properties in any file. Contrary to the widely used propertyplaceholderconfigurer.
application-context.xml
<bean class="com.mypackage.Myclass">
<property name="xml" value="classpath:"{com.myapp.myproperty1}"> </property>
</bean>
config.properties
com.myapp.myproperty1=data.xml
edit: I should have added it is data.properties and not data.xml. We want to load a property file (this property file is given in the config.properties as a "property".
com.myapp.myproperty1=data.properties
java class
import org.springframework.core.io.Resource;
public class Myclass {
private Resource xmlField;
// setter & getter methods..
}
Is it right to use spring core.io.Resource?
Another reason is the client application wants to load a environment specific configuration. I suggested use the propertyconfigurer and use maven profiles to generate the environment specific build
Can you please advise which one suits which case? and if it differs in different scenarios, please help me point out them?
thanks
You can put the properties in any file and still use PropertyPlaceholderConfigurer. Here's an example that satisfies both your coworker's concerns and your desire for environment specific stuff:
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- default settings -->
<value>classpath:MyCompany.properties</value>
<!-- environment-specific settings -->
<value>classpath:MyCompany.${mycompany.env:dev}.properties</value>
<!-- keep your coworker happy -->
<value>classpath:${mycoworker}</value>
<!-- allows emergency reconfiguration via the local file system -->
<value>file:///${user.home}/MyCompany.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true" />
<!-- should be validated separately, in case users of the library load additional properties -->
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
If you pass in no -D arguments, then you'll pick up the following properties files, where properties in the later files overwrite previously determined values.
MyCompany.properties off the classpath
MyCompany.dev.properties off the classpath
$HOME/MyCompany.properties if it exists
To swap in a production config for #2, just pass -Dmycompany.env=prod to java. Similarly your coworker can pass -Dmycoworker=/some/path/config.properties if he/she wants.
I'm not sure why a PropertyPlaceholderConfigurator wouldn't have been the correct choice.
I've almost always handled environment-specific configs via a customized PPC that can either (a) get a -D parameter on startup, and/or (b) use the machine name, to decide which property file to load.
For me, this is more convenient than bundling the information in via Maven, since I can more easily test arbitrary configurations from whatever machine I'm on (using a -D property).
+1 for Dave's suggestion. You should be using PropertyPlaceholderConfigurer for loading\reading properties. Here is the example i just pulled out from my previous project if you wonder how to use this. This example is for loading multiple properties files but the concept is same. Good luck.
<bean id="projectProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="projectProperties" />
</bean>
<bean id="uniqueAssetIdRetriever" class="com.mypackage.Myclass">
<property name="xml" value="${com.myapp.myproperty1}" />
</bean>
I am trying to do internationalization in Spring-MVC for the first time and I'm having what I assume to be a configuration issue. I have a NLS file that I named NLS_en.properties which I placed in my application's WEB-INF\classes directory. The file contains the following NLS string:
MSG_HELLO = Hello to the Internationalized World
In my application's servlet.xml file I've defined the following beans:
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="WEB-INF/classes/NLS"/>
</bean>
In my JSP file I have the following tag:
<p><spring:message code="MSG_HELLO" text="You should not be seeing this text" />
When the JSP displays, of course, the message I see is the one I should not be seeing, so how do I have to configure my application so that I do see my HELLO message?
ResourceBundleMessageSource basename (as opposed to ReloadableResourceBundleMessageSource) refers by default to the classpath, so you should have it like :
<property name="basename" value="NLS" />
Now, depending on how you build, even if configuring correctly the message source, it may have been erased at the time you run the application.
Do not place resources directly into classes (or any target directory in general). If you use maven place it directly into resources. If you dont use any build framework put it in the root of the source directory.
I have a standalone jar that uses spring. The config in my spring xml uses placeholders of which I've been replacing when compiling with maven. Example spring config:
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
Instead of replacing ${db.host} using maven I'd like to pass in a properties file at runtime, e.g.
java -jar Application.jar productionDB.properties
This would allow me to switch the db host at runtime by passing in the production db properties file or the testing db properties file.
Is it possible to do this or are there any better ways of achieving the same goal?
You could specify your property file as a System Property, e.g.:
java -jar Application.jar -DappConfig=/path/to/productionDB.properties
Then you should be able to reference that in your application context:
<context:property-placeholder location="file:${appConfig}"/>
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
You could use a PropertyPlaceholderConfigurer to use a .properties file to pass in the required variables.
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:productionDB.properties</value>
</list>
</property>
</bean>
You can leave your bean declaration as is. The properties will be automatically taken from the productionDB.properties file.
There are a few options:
Set your resources via your container's JNDI and use Spring's <jee:jndi-lookup/>.
Use Spring's <context:property-placeholder location="classpath:/myProps.properties" />. I prefer this short-hand over the "full" bean definition because Spring will automatically use the correct implementation (PropertyPlaceholderConfigurer for Spring < 3.1, or PropertySourcesPlaceholderConfigurer for Spring 3.1+). Using this configuration, you would just drop the myProps.properties at the root of your classpath (${TOMCAT_HOME}/lib for example).
You can pass the values using the context:property-placeholder. So your setup would be something like:
<context:property-placeholder location="file://opt/db.properties"/>
Then when you are wiring up your Foo service, you can use the property names in your config, such as
<bean id="foo" class="package.Foo">
<property name="host" value="${db.host}" />
</bean>
Then just use the different set of files for each environmnet
See the spring docs for more details.
There is this tag <terracottaConfig url="host1:9510,host2:9510,host3:9510"/> in ehcache.xml file inside spring web application. I want to externalize url attribute of this tag. Value of URL should be replaced by a property from external file. It will be very helpful if you suggest any solution to this problem.
You can put something like this -
<terracottaConfig url="${terracotta.config.location}" /> , however the big catch is that this will be loaded only from the system properties. It is not resolved from PropertyPlaceHolder as it is not a Spring configuration file.
So if you want to use an external config file, you will basically have to programatically set this system property before the Spring Application starts loading up the ehcache.xml file - one way to do that will be write your custom ServletContextListener to load up your properties file and set the system property based on that, this way when the ehcache.xml is loaded up it would be able to resolve the place holder properly.
Your answer helped me to solve my problem. I just want to add that instead of setting system property through program, I am using util:properties as follows
<bean id="sysProperties" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" value="#{#systemProperties}"/>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<util:properties>
<prop key="propertyname_used_in_ecache_xml">#{proerties_defined_using_property_factory['propertyname_defined_in_external_properties_file']}</prop>
</util:properties>
</property>
</bean>
<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" depends-on="sysProperties">
<property name="configLocation">
<value>classpath:ehcache.xml</value>
</property>
</bean>
One of our team has implemented loading properties this way (see pseudo code below) and advises this approach is right as the client application using this is free to keep the properties in any file. Contrary to the widely used propertyplaceholderconfigurer.
application-context.xml
<bean class="com.mypackage.Myclass">
<property name="xml" value="classpath:"{com.myapp.myproperty1}"> </property>
</bean>
config.properties
com.myapp.myproperty1=data.xml
edit: I should have added it is data.properties and not data.xml. We want to load a property file (this property file is given in the config.properties as a "property".
com.myapp.myproperty1=data.properties
java class
import org.springframework.core.io.Resource;
public class Myclass {
private Resource xmlField;
// setter & getter methods..
}
Is it right to use spring core.io.Resource?
Another reason is the client application wants to load a environment specific configuration. I suggested use the propertyconfigurer and use maven profiles to generate the environment specific build
Can you please advise which one suits which case? and if it differs in different scenarios, please help me point out them?
thanks
You can put the properties in any file and still use PropertyPlaceholderConfigurer. Here's an example that satisfies both your coworker's concerns and your desire for environment specific stuff:
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- default settings -->
<value>classpath:MyCompany.properties</value>
<!-- environment-specific settings -->
<value>classpath:MyCompany.${mycompany.env:dev}.properties</value>
<!-- keep your coworker happy -->
<value>classpath:${mycoworker}</value>
<!-- allows emergency reconfiguration via the local file system -->
<value>file:///${user.home}/MyCompany.properties</value>
</list>
</property>
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true" />
<!-- should be validated separately, in case users of the library load additional properties -->
<property name="ignoreUnresolvablePlaceholders" value="false"/>
</bean>
If you pass in no -D arguments, then you'll pick up the following properties files, where properties in the later files overwrite previously determined values.
MyCompany.properties off the classpath
MyCompany.dev.properties off the classpath
$HOME/MyCompany.properties if it exists
To swap in a production config for #2, just pass -Dmycompany.env=prod to java. Similarly your coworker can pass -Dmycoworker=/some/path/config.properties if he/she wants.
I'm not sure why a PropertyPlaceholderConfigurator wouldn't have been the correct choice.
I've almost always handled environment-specific configs via a customized PPC that can either (a) get a -D parameter on startup, and/or (b) use the machine name, to decide which property file to load.
For me, this is more convenient than bundling the information in via Maven, since I can more easily test arbitrary configurations from whatever machine I'm on (using a -D property).
+1 for Dave's suggestion. You should be using PropertyPlaceholderConfigurer for loading\reading properties. Here is the example i just pulled out from my previous project if you wonder how to use this. This example is for loading multiple properties files but the concept is same. Good luck.
<bean id="projectProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="projectProperties" />
</bean>
<bean id="uniqueAssetIdRetriever" class="com.mypackage.Myclass">
<property name="xml" value="${com.myapp.myproperty1}" />
</bean>