Initialize log4j in application using spring 4.1 without web.xml - spring

In my Spring 4.1 based application, I am not using any web.xml. How can I initialize log4j without web.xml in my app? I came across this SO question which suggests the required configuration through web.xml, but I am not sure how to do it through code.
. I have placed my log4j.properties in WEB-INF/lib folder and it looks like this:
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
log4j.category.org.springframework.beans.factory=DEBUG
log4j-1.2.17.jar is also in WEB-INF/lib folder. But the following message appears at startup:
log4j:WARN No appenders could be found for logger
(org.springframework.web.context.support.StandardServletEnvironment).
log4j:WARN Please initialize the log4j system properly.
Please help.

add log4j as dependency and put log4j.properties into main/resources - should be working fine.

As you are starting a spring application without web.xml, I suppose you have some initialization class implementing WebApplicationInitializer, and probably extending AbstractAnnotationConfigDispatcherServletInitializer.
If you are not satisfied with the standard log4j.properties at the base of classpath as proposed by freakman, you can overide the onStartup method to configure log4j with a Log4jConfigurer - do not forget to call the base class implementation ...

You can use it as a bean inside root-context.xml, use classpath for relative path . It works for me
<bean id="log4jInitializer" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" depends-on="sbeHome">
<property name="targetClass" value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>classpath:/conf/log4j.xml</value>
</list>
</property>
</bean>

Related

No appenders could be found for logger (org.springframework.web.context.ContextLoader)

I inherited a bunch of code and I noticed that in the tomcat logs it says
log4j:WARN No appenders could be found for logger
(org.springframework.web.context.ContextLoader). log4j:WARN Please
initialize the log4j system properly. log4j:WARN See
http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
The faq link mentions that this occurs when the default configuration files log4j.properties and log4j.xml can not be found and the application performs no explicit configuration.
How can I figure out how exactly to fix this. The xml file has the following. So I'm guessing its because there is no log4j.xml and instead there is one for each environment. Assuming that is the problem how do I configure things correctly.
<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>classpath:log4j-${environment}.properties</value>
</list>
</property>
</bean>
Few collective solutions -
While defining the bean, there shall be some property file from where the value(assume env) of ${environment} is being fetched. You must note that appending that value to the file name. Should exist under your project resources. In your case a file named log4j-env.properties.
Would recommend ways of using different method of logging for different environments while categorising them under different directory, so as to modify your values instead as -
<property name="arguments">
<list>
<value>#{environment + '/log4j.properties'}</value>
</list>
</property>
You could configure your Log4j listener in the web.xml instead of the spring-context.xml, so it is up before Spring starts. as -
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/${environment}/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
Source - Initializing Log4J with Spring?
Note - On how to assign the correct value to environment at runtime, follow How to replace a value in web.xml with a Maven property?

Spring Property place holder: reading value from external property file fails

I am trying to read logpath from external property file.
I have below spring configuration. I am using spring 2, maven.
beans-config.xml
<bean id="loglocation" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>file:///D:/logpath.properties</value>
</property>
logpath.properties
logpath=D:/logs/myproject.log
log4j.properties
log4j.rootLogger=INFO, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=${logpath}
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
I dont know how to pass the log path from logpath.property file to the placeholder ${logpath}in log4j.prop. Am I missing anything in beans configuration xml? Any help

CXF request response logging using log4j: debug

I am trying to enable logging for cxf framework in weblogic application server along with log4j.
I have placed cxf.xml in domain home and have modified setdomainenv to add cxf.xml entry -Dcxf.config.file.url=cxf.xml.
I am setting System.setProperty("org.apache.cxf.Logger", "org.apache.cxf.common.logging.Log4jLogger") before making a webservice call and i have tried configuring all 3 types of configuration specified in http://cxf.apache.org/docs/configuration.html. But nothing seems to work.
I even tried creating org.apache.cxf.Logger file containing value org.apache.cxf.common.logging.Log4jLogger.
my log4j.properties
log4j.rootLogger = DEBUG, FILE
log4j.logger.org.apache.cxf=DEBUG
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=<>/logFile.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n
CXF version: 2.7.5
Please suggest if there is change required for me to log both request and response xml?
Make sure your org.apache.cxf.Logger file is under META-INF/cxf. Inspect your war to make sure.
Also, assuming you are defining your services using jaxws, make sure you're defining loggers under the jaxws:inInterceptor and jaxws:outInterceptor
<jaxws:client id="..." serviceClass="..." address="..." >
<jaxws:outInterceptors>
<ref bean="logOut" />
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="logIn"/>
</jaxws:inInterceptors>
</jaxws:client>
<bean class='org.apache.cxf.interceptor.LoggingInInterceptor' id='logIn'/>
<bean class='org.apache.cxf.interceptor.LoggingOutInterceptor' id='logOut'/>

How to locate the properties file in the spring context configuration file

I am using spring web mvc project, and I put all the spring related files under WEB-INF\spring, including a ormlite.xml and a jdbc.properties.
Now I want to locate the jdbc.properties file in the ormlite.xml,Like this:
<context:property-placeholder location="/WEB-INF/spring/jdbc.properties"/>
But when I run the application ,it will told me that :
Could not load properties
It can not find the properties file.
What is the problem?
From Spring forum:
The problem is that /WEB-INF isn't accessible as it isn't in the root
of the path, you must use the same path as you use in your test case
(include the src/main/webapp part but that will break your application
from running).
I suggest you move the jdbc.properties to the src/main/resources
directory and simply use classpath: prefix to load the properties.
Code:
<context:property-placeholder location="classpath:jdbc.properties"/>
The code above assumes they are on the root of the classpath (which is
where they are when they are in src/main/resources).
I hope this can help someone else.
I had the same problem - property files outside the classpath.
My solution:
First define a properties bean:
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">
<value>/WEB-INF/your.properties</value>
</property>
</bean>
Then reference it in the property-placeholder:
<context:property-placeholder properties-ref="configProperties" />
Works perfectly well for me!
Instead of:
<context:property-placeholder location="/WEB-INF/spring/jdbc.properties"/>
Use:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/spring/jdbc.properties"/>
And your properties will be available in Spring file, and don't forget to add a namespace: xmlns:p="http://www.springframework.org/schema/p"
I think you're missing the prefix to instruct Spring how to attempt to load the properties. I think your definition needs to be:
<context:property-placeholder location="file:/WEB-INF/spring/jdbc.properties"/>
Note the addition of the file: prefix.

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.

Resources