2
votes

My problem is that I'm building spring-boot project and I'm using class A from some other project which use log4j 1.2.8. When I force spring to use log4j 1.2.8 I have following error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jettyEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedJetty.class]: Initialization of bean failed; nested excepti
on is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.boot.autoconfigure.web.ServerProperties org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration.properties; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is java.lang.NoSuchFieldError: TRACE

Spring need at least log4j 1.2.12, so when I use this version of log4j my A class have follwing error:

java.lang.NoSuchMethodError: org.apache.log4j.LogManager.exists(Ljava/lang/String;)Lorg/apache/log4j/Logger;

There is any solution other than upgrade of my A class log4j? Maybe there is any way to force at runtime some classes should use log4j 1.2.8 and other would use 1.2.12 ?

4
You describe one way, forcing Spring to use an older log4j. But what about the other way? Does the class that was built against the older version have any problems when only log4j 1.2.12 is on the classpath?Gimby
Spring is using log4j over slf4j and as you can see github.com/qos-ch/slf4j/blob/master/log4j-over-slf4j/src/main/… this class does not implement exists method which my class is using.adamr

4 Answers

2
votes

OSGI is such kind of technology which you can have multiple versions of same library in one JVM runtime.

However, it's overkilled for most of cases. Same suggestion as others, upgrading your source code would be much cheaper way.

2
votes

Solution for this problem is easy. I mentioned in comment that spring use log4j-over-slf4j which doesn't implement LogManager.exists method which my Class is using. I've just excluded from my project(gradle) log4j-over-slf4j and added dependency to log4j as below.

configurations {
    compile.exclude module: 'log4j-over-slf4j'
}
compile group: 'log4j', name: 'log4j', version: '1.2.17'
1
votes

The easiest solution is to upgrade your project A. Updating the logging library is a minor risk, fiddling with different library versions can be tedious and confusing.

Disclaimer: I'm not familiar with spring-boot, maybe it has a clever way of dealing with this issue.

1
votes

I would highly recommend to upgrade the class that is making the problems with an older log4j version. Every thing you could do, at my knowledge, would be way more complicated then upgrading. You could split up into 2 diffrent projects in their own classloader or something like that.. basicly that is what something like tomcat does to achieve multiple java web applications.. but then you have to look how both communicate etc etc... so I suppose that the most solutions will make it more complicated than it needs to be, or should be