Classpath issue between jetty-maven-plugin and tomcat-jdbc 8.0.9+ leading to ServiceConfigurationError

那年仲夏 提交于 2019-12-05 00:18:38

The spring boot starter web dependency will include tomcat by default. This will confuse jetty when you start it, since it uses different versions of the juli lib.

Simply fix in your pom.xml, exlude the starter-tomcat and separately include the jetty dependency:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>

It appears, that this is caused by Jetty using a modified Apache JSP package Jasper. It has its own version of Juli logging (check lib/apache-jsp/org.mortbay.jasper.apache-jsp-8.0.27.jar under Jetty home directory) which seems to cause all the confusion. I think, that Jetty's default webapp class loading logic causes Juli LogFactory from your webapp to be loaded everytime that class is requested. It's all good and dandy when that LogFactory has to load tomcat-jdbc classes. It gets tricky when it gets passed Jetty's modified Jasper classes, because it realises that there are type conflicts.

How you can solve this? I think there are 2 ways to do so:

1. Change Jetty webapp classloader logic

You can modify classloader logic, to always delegate class loading to parent classloader. You just need to call setParentLoaderPriority(true) on particular WebAppContext. You can do that either by Jetty configuration or by including jetty-web.xml file with your war.

2. Exclude tomcat-juli dependency

Using Maven's Dependency exclusions you can skip any transitive dependency you do not like. So just include tomcat-jdbc without tomcat-juli and you're done.

The only problem is that both solutions force you to use Jetty's modified Juli package. Haven't seen a problem with such scenario yet, but I guess at some point you might find you're missing some feature, because Jetty's modified Juli wasn't synced with Apache latest version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!