简体   繁体   English

jetty-maven-plugin 和 tomcat-jdbc 8.0.9+ 之间的类路径问题导致 ServiceConfigurationError

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

I'm working on an app using :我正在使用一个应用程序:

jetty-maven-plugin:9.3.2.v20150730码头行家插件:9.3.2.v20150730
tomcat-jdbc:8.0.8 (which has tomcat-juli as dependency) tomcat-jdbc:8.0.8(依赖 tomcat-juli)

After trying to upgrade the tomcat-jdbc jar to any version beyond 8.0.9+ I get the following error:在尝试将 tomcat-jdbc jar 升级到 8.0.9+ 之后的任何版本后,我收到以下错误:

java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtype java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog 不是一个子类型

Looking the changelog between those 2 versions I've found something that looks suspicious:查看这两个版本之间的变更日志,我发现了一些可疑的东西:

"Add a simple ServiceLoader based discovery mechanism to the JULI LogFactory to make it easier to use JULI and Tomcat components that depend on JULI (such as Jasper) independently from Tomcat. Patch provided by Greg Wilkins. (markt)" “在JULI LogFactory中添加一个简单的基于ServiceLoader的发现机制,可以更容易地独立于Tomcat使用依赖JULI的JULI和Tomcat组件(如Jasper)。补丁由Greg Wilkins提供。(markt)”

Also, I've found that a new system property was introduced in the Apache Tomcat JDBC Connection Pool:此外,我发现在 Apache Tomcat JDBC 连接池中引入了一个新的系统属性:

org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader org.apache.tomcat.jdbc.pool.onlyAttemptCurrentClassLoader

"Controls classloading of dynamic classes, such as JDBC drivers, interceptors and validators. If set to false, default value, the pool will first attempt to load using the current loader (ie the class loader that loaded the pool classes) and if class loading fails attempt to load using the thread context loader. Set this value to true, if you wish to remain backwards compatible with Apache Tomcat 8.0.8 and earlier, and only attempt the current loader. If not set then the default value is false." "控制动态类的类加载,例如 JDBC 驱动程序、拦截器和验证器。如果设置为 false,默认值,池将首先尝试使用当前加载器(即加载池类的类加载器)和如果类加载尝试使用线程上下文加载器加载失败。如果您希望与 Apache Tomcat 8.0.8 及更早版本保持向后兼容,请将此值设置为 true,并且仅尝试当前加载器。如果未设置,则默认值为 false。”

Unfortunately, starting the plugin with jetty:run using this property didn't resolve the issue.不幸的是,使用此属性通过 jetty:run 启动插件并没有解决问题。

Any help would be appreciated!任何帮助,将不胜感激! Thanks!谢谢!

Stack trace and dependencies tree :堆栈跟踪和依赖关系树:

Caused by: 
java.util.ServiceConfigurationError: org.apache.juli.logging.Log: Provider org.eclipse.jetty.apache.jsp.JuliLog not a subtype
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at org.apache.juli.logging.LogFactory.(LogFactory.java:78)
    at org.apache.juli.logging.LogFactory.(LogFactory.java:66)
    at org.apache.tomcat.jdbc.pool.DataSourceFactory.(DataSourceFactory.java:58)
    at local.ristretto.persistence.datasource.mail.MailDataSourceConfiguration.dataSource(MailDataSourceConfiguration.java:31)
    at local.ristretto.persistence.datasource.mail.MailDataSourceConfiguration$$EnhancerBySpringCGLIB$$497970dd.CGLIB$dataSource$0()
    at local.ristretto.persistence.datasource.mail.MailDataSourceConfiguration$$EnhancerBySpringCGLIB$$497970dd$$FastClassBySpringCGLIB$$2ba2dde9.invoke()
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
    at local.ristretto.persistence.datasource.mail.MailDataSourceConfiguration$$EnhancerBySpringCGLIB$$497970dd.dataSource()
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:434)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:798)
    at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:530)
    at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:771)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:342)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1368)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.startWebapp(JettyWebAppContext.java:320)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1335)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:735)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:259)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:511)
    at org.eclipse.jetty.maven.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:403)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:405)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:372)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:457)
    at org.eclipse.jetty.maven.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:328)
    at org.eclipse.jetty.maven.plugin.JettyRunMojo.execute(JettyRunMojo.java:170)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:132)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:120)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:347)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:154)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:582)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:214)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:158)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
[INFO] |  +- org.springframework.data:spring-data-jpa:jar:1.8.2.RELEASE:compile               
[INFO] |  |  +- org.springframework.data:spring-data-commons:jar:1.10.2.RELEASE:compile       
[INFO] |  |  +- org.springframework:spring-orm:jar:4.1.7.RELEASE:compile                      
[INFO] |  |  |  \- org.springframework:spring-jdbc:jar:4.1.7.RELEASE:compile                  
[INFO] |  |  +- org.springframework:spring-tx:jar:4.1.7.RELEASE:compile                       
[INFO] |  |  \- org.aspectj:aspectjrt:jar:1.8.6:compile                                       
[INFO] |  +- org.postgresql:postgresql:jar:9.4-1202-jdbc42:compile                            
[INFO] |  +- org.apache.tomcat:tomcat-jdbc:jar:8.0.9:compile                                 
[INFO] |  |  \- org.apache.tomcat:tomcat-juli:jar:8.0.9:compile                              
[INFO] |  +- org.hibernate:hibernate-entitymanager:jar:5.0.1.Final:compile                    
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile                       
[INFO] |  |  +- org.hibernate:hibernate-core:jar:5.0.1.Final:compile                          
[INFO] |  |  |  +- antlr:antlr:jar:2.7.7:compile                                              
[INFO] |  |  |  \- org.jboss:jandex:jar:1.2.2.Final:compile                                   
[INFO] |  |  +- dom4j:dom4j:jar:1.6.1:compile                                                 
[INFO] |  |  |  \- xml-apis:xml-apis:jar:1.0.b2:compile                                       
[INFO] |  |  +- org.hibernate.common:hibernate-commons-annotations:jar:5.0.0.Final:compile    
[INFO] |  |  +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile 
[INFO] |  |  +- org.apache.geronimo.specs:geronimo-jta_1.1_spec:jar:1.1.1:compile             
[INFO] |  |  \- org.javassist:javassist:jar:3.18.1-GA:compile                                 
[INFO] |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.6.1:compile                    
[INFO] |     +- com.fasterxml.jackson.core:jackson-annotations:jar:2.6.1:compile              
[INFO] |     \- com.fasterxml.jackson.core:jackson-core:jar:2.6.1:compile                     

[INFO] |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile                                      
[INFO] |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile                                        
[INFO] |  +- org.slf4j:log4j-over-slf4j:jar:1.7.12:compile                                    
[INFO] |  +- org.slf4j:slf4j-api:jar:1.7.12:compile                                           
[INFO] |  +- ch.qos.logback:logback-classic:jar:1.1.3:compile                                 
[INFO] |  |  \- ch.qos.logback:logback-core:jar:1.1.3:compile                                 
[INFO] |  +- org.wicketstuff:wicketstuff-logback:jar:6.20.0:compile                           
[INFO] |  +- org.apache.commons:commons-lang3:jar:3.4:compile                                 
[INFO] |  +- org.apache.commons:commons-collections4:jar:4.0:compile                          
[INFO] |  +- commons-io:commons-io:jar:2.4:compile                                            
[INFO] |  +- commons-codec:commons-codec:jar:1.10:compile                                     
[INFO] |  +- commons-beanutils:commons-beanutils:jar:1.9.2:compile                            
[INFO] |  |  \- commons-collections:commons-collections:jar:3.2.1:compile                     
[INFO] |  \- com.google.guava:guava:jar:18.0:compile                                          
[INFO] +- junit:junit:jar:4.12:test                                                           
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test                                          
[INFO] +- org.springframework:spring-test:jar:4.1.7.RELEASE:test                              
[INFO] |  \- org.springframework:spring-core:jar:4.1.7.RELEASE:compile                        
[INFO] +- org.springframework:spring-web:jar:4.1.7.RELEASE:compile                            
[INFO] |  +- org.springframework:spring-aop:jar:4.1.7.RELEASE:compile                         
[INFO] |  |  \- aopalliance:aopalliance:jar:1.0:compile                                       
[INFO] |  +- org.springframework:spring-beans:jar:4.1.7.RELEASE:compile                       
[INFO] |  \- org.springframework:spring-context:jar:4.1.7.RELEASE:compile                     
[INFO] |     \- org.springframework:spring-expression:jar:4.1.7.RELEASE:compile               
[INFO] \- javax:javaee-web-api:jar:7.0:provided

The spring boot starter web dependency will include tomcat by default.默认情况下,spring boot starter web 依赖项将包含 tomcat。 This will confuse jetty when you start it, since it uses different versions of the juli lib.这会在您启动时混淆 jetty,因为它使用不同版本的 juli lib。

Simply fix in your pom.xml, exlude the starter-tomcat and separately include the jetty dependency:只需在 pom.xml 中修复,排除 starter-tomcat 并单独包含 jetty 依赖项:

    <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.看起来,这是由 Jetty 使用修改后的 Apache JSP 包 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.它有自己的 Juli 日志版本(检查 Jetty 主目录下的lib/apache-jsp/org.mortbay.jasper.apache-jsp-8.0.27.jar ),这似乎引起了所有的混乱。 I think, that Jetty's default webapp class loading logic causes Juli LogFactory from your webapp to be loaded everytime that class is requested.我认为,Jetty 的默认 webapp 类加载逻辑会导致每次请求该类时从您的 webapp 加载 Juli LogFactory It's all good and dandy when that LogFactory has to load tomcat-jdbc classes.LogFactory必须加载tomcat-jdbc类时,这一切都很好。 It gets tricky when it gets passed Jetty's modified Jasper classes, because it realises that there are type conflicts.当它通过 Jetty 修改后的 Jasper 类时变得棘手,因为它意识到存在类型冲突。

How you can solve this?你怎么能解决这个问题? I think there are 2 ways to do so:我认为有两种方法可以做到:

1. Change Jetty webapp classloader logic 1.更改Jetty webapp类加载器逻辑

You can modify classloader logic, to always delegate class loading to parent classloader.您可以修改类加载器逻辑,以始终将类加载委托给父类加载器。 You just need to call setParentLoaderPriority(true) on particular WebAppContext .您只需要在特定的WebAppContext上调用setParentLoaderPriority(true) You can do that either by Jetty configuration or by including jetty-web.xml file with your war.您可以通过 Jetty 配置或通过在您的战争中包含jetty-web.xml文件来做到这一点。

2. Exclude tomcat-juli dependency 2.排除tomcat-juli依赖

Using Maven's Dependency exclusions you can skip any transitive dependency you do not like.使用 Maven 的依赖项排除,您可以跳过您不喜欢的任何传递依赖项。 So just include tomcat-jdbc without tomcat-juli and you're done.所以只包含没有tomcat-juli tomcat-jdbc就完成了。

The only problem is that both solutions force you to use Jetty's modified Juli package.唯一的问题是这两种解决方案都迫使您使用 Jetty 的修改后的 Juli 包。 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.还没有看到这种情况的问题,但我想在某些时候您可能会发现您缺少某些功能,因为 Jetty 修改后的 Juli 未与 Apache 最新版本同步。

IF IT'S NOT A SPRING PROJECT如果这不是春季项目

Here is the exclusion that I provided in pom.xml:这是我在 pom.xml 中提供的排除:

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-maven-plugin</artifactId>
            <version>9.4.24.v20191120</version>
             <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>apache-jsp</artifactId>
                </exclusion>
             </exclusions>
        </dependency>

Also provided the plugin:还提供了插件:

           <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.24.v20191120</version>

                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <webApp>
                        <contextPath>/ezops-preprocessor</contextPath>
                    </webApp>
                </configuration>

            </plugin>

With the above exclusion, apache-jsp(Jule Logging), I am not getting that exception.有了上面的排除,apache-jsp(Jule Logging),我没有得到那个例外。

Hope this helps.!!!希望这可以帮助。!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM