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

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?

Related

Use values from properties file in web.xml

I am a begginer in Spring and encountered the following problem.
I have the following files:
app.properties
applicationContext.xml
web.xml
Within app.properties I have the value app.env=dev
In applicationContext.xml:
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="location">
<value>app.properties</value>
</property>
</bean>
I want to use the app.env from the properties file in web.xml like this:
<context-param>
<param-name>ENV</param-name>
<param-value>${app.env}</param-value>
</context-param>
I am using ${app.env} without problems in applicationContext.xml.
I have found discussions that state you can push values into web.xml from a properties file but I have also found people saying it is not possible (usually older posts).
The issue is the placeholder ${app.env} in web.xml is not replaced by the value from the properties file. Is it possible to do it? If so what am I missing.

Initialize log4j in application using spring 4.1 without web.xml

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>

Loading log4j.xml from outside of war file

For my spring application, I have a requirement to move log4j.xml outside of war file. I have been searching for solutions, and found following ways:
org.springframework.web.util.Log4jConfigListener: this did not work as war is not expanded on tomcat.
Passing jvm property (-Dlog.Localtion=....): Since log4j file is application specific, I do not think this is good way to do this.
I am wondering what is best way to solve this. I believe Spring should make it easy someway, it's just I don't much about it.
You can specify the location of your log4j.xml in your context config file:
<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>/any/path/log4j.xml</value>
</list>
</property>
</bean>
Source http://helpdesk.objects.com.au/java/how-to-specify-log4j-configuration-in-spring-application
You can check org.springframework.util.Log4jConfigurer. You can pass the location of log4j.xml to this class.It also takes care of resolving property place holders.
You can use org.springframework.web.util.Log4jConfigListener in your web.xml - just add this elements:
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>../path/to/config</param-value>
</context-param>

How to read from property file in web.xml

in my web.xml i want to read the welcome file from property file
something like:
<welcome-file-list>
<welcome-file>${home.page}</welcome-file>
</welcome-file-list>
i have propertyPlaceholderConfigurer configured:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:messages/application.properties</value>
</list>
</property>
</bean>
is there's additional param should be added to web.xml, or another bean needs to be defined or what ?
also i have another xml file on the same level of web.xml (under WEB-INF direclty)
can i read from property file in it in the same way ?
please advise.
It doesn't work like that; the web.xml file is completely unrelated to Spring.
What you could do is have a hard-coded welcome file, and inside that file, redirect to something defined in the Spring configuration, retrieving the page by grabbing the Spring context manually.

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