Log4jConfigurer in Spring 5.0.2 - java

I was using Spring 4.X.X and used the below setup to configure Log4j. Now am upgrading it to Spring 5.0.2 where the Log4jConfigurer class has been removed. How can I do it in Spring 5.0.2?
<bean
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>classpath:log4j.properties</value>
</list>
</property>
</bean>

The Log4JConfigurer was required for non default Log4j initialisation e.g. if using a custom config file name/location but your config file is located in the default location: classpath:log4j.properties so you can simply remove the Log4jConfigurer declaration and Spring will auto discover your log4j.properties.
There is one possible caveat here; Spring 5 uses Log4j v2 (following Apache's EOL declaration for log4j 1.x) so as long as you are using Log4j v2 then Spring 5 will auto detect it and your log4j.properties file without any need to declare a Log4JConfigurer. If you are not currently using Log4j v2 then I think you'll need to upgrade since Spring 5 does not support the use of Log4j v1.x.

Related

Is it possible to specify a context property placeholder at runtime

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.

log4j and spring

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>

Spring mvc ResourceBundleMessageSource for different themes

I configures my appstrings.properties file which contains strings related to theme used by my application. There are two themes for my application. Both have their own appstrings.properties file located at WEB-INF/strings/theme1/appstrings and WEB-INF/strings/theme2/appstrings. I specified property themeName in config.properties file.
Here is my spring config file:
<context:property-placeholder location="file:///${config.properties}" />
...
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basenames="WEB-INF/strings/theme1/appstrings" />
Right now all my app strings are coming from WEB-INF/strings/theme1/appstrings.properties file. How can I make it dynamic. i.e. when I change themeName propperty to theme2 it should get string from WEB-INF/strings/theme2/appstrings.properties
You need to use a ResourceBundleThemeSource
<!-- resolves localized <theme_name>.properties files in the classpath to
allow for theme support -->
<bean
class="org.springframework.ui.context.support.ResourceBundleThemeSource"
id="themeSource" />
<mvc:interceptors>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
</mvc:interceptors>
See Spring Reference Chapter 15.7 Using Themes
For an running example you can quickly create a small Spring Roo application. It uses the theme support to change the css files.
If config.properties contains a property say: themeName = propertyValue. If you want to use this themeName's value in spring mvc configuration servlet xml file then you can use ${themeName}
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basenames="WEB-INF/strings/${themeName}/appstrings" />
reference

Different persistence.xml properies for test run / JPA Fixtures

I develop some Java EE/Spring web-app. I use JPA 2.0 - Hibernate. For integration tests I need to use different database. Those tests require Jetty to run application, but I managed to override web.xml for such run, there I can modify my Spring context files, it's ok.
But I need each time a clean database (and load some data into it).
As my database name and address are configured in sprig context I just switched them as I described above - but how can I change some of my persistence.xml properies for this tests only to have database drop and recreated?
I tried to make another persistence.xml in /src/test/resources/META-INF (and checked that test-classes are first in classpath) but it is not loaded and only the 'master' version is used (from /src/main/resources/META-INF). Any help?
With spring you usually define your data source as a spring bean. The database url and credentials are usually included form an external file, for example application.properties.
If you put a new applicaiton.properties in src/test/resources it will work. See also here.
You can define org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager :
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>/path/to/my/test-persistence.xml</value>
</list>
</property>
<property name="dataSources">
<map>
<entry key="dataSource" value-ref="dataSource"/>
</map>
</property>
<!-- if no datasource is specified, use this one -->
<property name="defaultDataSource" ref="dataSource"/>
</bean>
Then, link it to your entityManagerFactory :
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
...
<property name="persistenceUnitManager" ref="pum"/>
</bean>
I used this to make my own persistence.xml linked to a HSQL in-memory db, preloaded with DBUnit (using hibernate.hbm2ddl.auto=create-drop).
It Works perfectly.

LOG4j Spring AOP

I have a j2ee web application running on Spring framework. I want to implement logging using log4j and Spring's AOP. I was trying to find for references but I only get references which does not use log4j.
I had exactly the same configuration as what was on the link you gave. I have declared too a bean which where I want to implement logging. The beans id is ExecuteBLogic so I put below *BLogic
<bean name="methodLoggingInterceptor" class="org.developers.blog.spring.aop.logging.MethodLoggingInterceptor"/>
<bean name="proxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*BLogic</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>methodLoggingInterceptor</value>
</list>
</property>
</bean>
There are many examples that show how to log information using spring AOP. The fact that they are using System.out or java.util.logging should bother you - just replace these lines with log4j lines.
So, ontop of the class:
private static final Logger logger = Logger.getLogger(LoggingInterceptor.class);
and then instead of System.out.println(..):
logger.info(..);

Categories

Resources