spring - TomcatLoadTimeWeaver breaks Log4j 2 -


i have serious problem tomcatloadtimerweaver , log4j , don't know how solve it.

i'm using following:

  • tomcat 8
  • spring framework 4.1.2
  • log4j 2.1
  • slf4j 1.7.7
  • eclipselink 2.5.2

all logging routed slf4j, , i'm using log4j 2.1 logging backend. log4j configured take configuration file non-standard location, specified in web.xml through log4jconfiguration context-param. log4jservletcontainerinitializer configures log4j on webapp start. works fine spring configures tomcatloadtimeweaver.

i want use load time weaving eclipselink , added application context:

<context:load-time-weaver/> 

the problem this: once spring registers tomcatloadtimeweaver adding transformer tomcat's webappclassloader, first subsequent attempt log through slf4j causes log4j implicitly re-initialized: since configuration file not in standard location (= root of classpath) error:

no log4j2 configuration file found

from moment on, log calls not handled (= in way specified in log4j.xml) more , careful configuration of slf4j+log4j+bridges commons logging , jul gets broken.

it seems addition of class loader transformer resetting in log4j, needs reconfigure itself: i've spent couple of hours try understand better problem, it's not easy without deep knowledge of log4j internals.

moving log4j.xml log4j2.xml on classpath root not can (for deployment reasons) , in case i'm not sure implicit reconfiguration of log4j not under control thing live with.

maybe configuration of load time weaver (before log4j configures first time) make trick, i'm not sure how to this, since log4j should set before spring itself.

any suggestion appreciated.

further details

actually, problem doesn't occur when spring's defaultcontextloadtimeweaver (which carries tomcatloadtimeweaver) initialized, rather when localcontainerentitymanagerfactorybean used set entitymanagerfactory eclipselink initialized (i.e., when org.springframework.orm.jpa.abstractentitymanagerfactorybean.afterpropertiesset() called), because it's @ time org.springframework.context.weaving.defaultcontextloadtimeweaver.addtransformer(classfiletransformer) invoked virtue of actual creation of native entitymanagerfactory eclipselink (triggered org.springframework.orm.jpa.localcontainerentitymanagerfactorybean.createnativeentitymanagerfactory()). so, workaround register beanpostprocessor intercepts initialization of localcontainerentitymanagerfactorybean , forces org.apache.logging.log4j.web.log4jwebinitializerimpl.start() run again , hence reconfigure log4j webapp settings. ended horrible hack, though, because log4j classes full of default , protected methods , had use reflection , place bean post processor in org.apache.logging.log4j.core package make work.

smarter solutions/suggestions/alternative approaches welcome.

the actual cause

i debugged further whole system , found out cause of problem. opened log4j2-903 this. in short, log4j uses class loader tostring() value search current log context in map. since tomcat's webappclassloader.tostring() method changes when register transformer, log4j not able retrieve configured context , creates new 1 eclipselink+spring register load time weaver transformer... :-(

the solution problem upgrade log4j 2.2, contains fix log4j2-903.


Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -