2

I am using spring 3.x version and am using annotations to wire the dependencies. I have two beans as below.

package com.sample.project.service;
@Component
public class MyAppender extends AppenderSkeleton{


     //here trying to inject emailSender bean
    @Autowired
    private EmailSender emailSender;

//some code with emailSender
//emailSender.callSomeService...


}

Above bean extends AppenderSkeleton class of log4j.

package com.sample.project.service;
@Component
public class EmailSender {

  @Autowired
  private SomeOtherBean someOther;

//somecode

}

I have an entry in applicationContext.xml as below.

<context:component-scan base-package="com.sample.project.service" />

Log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

    <!-- Appenders -->

    <appender name="stdout" class="com.sample.project.service.MyAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
        </layout>
    </appender>


    <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <param name="BufferSize" value="500"/>
        <appender-ref ref="stdout"/>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="ASYNC" />
    </root>

</log4j:configuration>

But the problem is, emailSender injected into MyAppender is always null. Am i doing anything wrong here. Or is there any problem with overriding log4jspecific classes and annotating them with @Component ? Thanks! Please help me!

user755806
  • 6,565
  • 27
  • 106
  • 153

1 Answers1

0

With this config

<appender name="stdout" class="com.sample.project.service.MyAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
    </layout>
</appender>

log4j is creating its own MyAppender instance. This instance has nothing to do with the @Component instance that Spring creates. As such, there is no autowiring being done and your field is initialized to null by default.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Please suggest me any alternative here.somehow i need emailSender instance in MyAppender.Thanks! – user755806 Oct 18 '13 at 15:10
  • @user755806 There is no simple alternative. `log4j` sets itself up with `static` initializers. Spring runs after that. You can do something [like what is described here](http://stackoverflow.com/questions/1324053/configure-log4j-to-log-to-custom-file-at-runtime) by specifying to `root` logger. Until that's done, `log4j` will be using what's in your config file. – Sotirios Delimanolis Oct 18 '13 at 15:15
  • @user755806 `ApplicationContextAware` will only make it aware of Springs `ApplicationContext` it's being created it. It still has nothing to do with log4j. You're kind of out of luck. [Try this while you are at it.](http://stackoverflow.com/questions/8592399/change-log4j-properties-at-runtime) – Sotirios Delimanolis Oct 18 '13 at 15:19
  • @Stirios, Thanks much. I will try by following the above. Meanwhile if you get some time please throw some ideas. Thanks! – user755806 Oct 18 '13 at 15:25
  • @user755806 [Found this too.](http://stackoverflow.com/questions/1730634/what-are-the-available-options-to-retrieve-spring-managed-beans-in-a-log4j-appen) These are your only real options :( – Sotirios Delimanolis Oct 18 '13 at 15:27
  • Thank you so much for your help. I will try all the links you suggested. Please give me any good approach if possible. Thanks! – user755806 Oct 18 '13 at 15:29
  • @Stirios, I accepted the answer. Please give me some ideas if you get. Thanks..Please help me... – user755806 Oct 18 '13 at 15:46