【问题标题】:java.lang.NoSuchMethodError because of duplicate class available in lib folder of Tomcatjava.lang.NoSuchMethodError 因为 Tomcat 的 lib 文件夹中有重复的类
【发布时间】:2020-01-11 02:06:44
【问题描述】:

我面对

java.lang.NoSuchMethodError:javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType

在 Tomcat 8 中部署我的应用程序时,因为 tomcat 类加载器正在从位于 TOMCAT_HOME\lib 文件夹的 annotations-api.jar 文件中加载 PersistenceContext 类,而 annotations-api.jar 中的 PersistenceContext 类不包含如下同步方法

package javax.persistence;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PersistenceContext {
  String name() default "";

  String unitName() default "";

  PersistenceContextType type() default PersistenceContextType.TRANSACTION;

  PersistenceProperty[] properties() default {};
}

虽然我希望 tomcat 从 javax.persitence-api-2.2 jar 加载 PersistenceContext 类,但我已将其复制到 TOMCAT_HOME\lib 文件夹而不是 TOMCAT_HOME\lib 文件夹中的 annotations-api.jar,因为来自 javax.persitence-的 PersistenceContext 类api-2.2 jar包含同步方法如下

package javax.persistence;

import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Repeatable(PersistenceContexts.class)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PersistenceContext {
  String name() default "";

  String unitName() default "";

  PersistenceContextType type() default PersistenceContextType.TRANSACTION;

  SynchronizationType synchronization() default SynchronizationType.SYNCHRONIZED;

  PersistenceProperty[] properties() default {};
}

这样tomcat在部署我的应用程序时不会给出java.lang.NoSuchMethodError: javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType

如何在 Tomcat 8 中设置优先级,以便 Tomcat 8 从 javax.persistence-api-2.2.jar 而不是 annotations-api.jar 加载 PersistenceContext 类?

编辑:Tomcat 8 lib 文件夹已经包含 annotations-api.jar 并且我已将 javax.persistence-api-2.2.jar 复制到 Tomcat 的 lib 文件夹中以获得 Tomcat 8 中的 eclipselink 支持,因此请排除我的 annotations-api.jar 选项dependencies.gradle 没有帮助,因为 annotations-api.jar 已经是 Tomcat 的 lib 文件夹的一部分。 annotations-api.jar 不是我自己加的。

注意:同一应用程序正在 Tomcat 9 中运行文件,因为 Tomcat 9 中的 annotations-api.jar 不包含 javax.persistence 包。

【问题讨论】:

  • 我想如果你把两个都放在lib文件夹里他会随机选择一个?
  • 你在用maven吗?如果是这样,请从您不希望在依赖项上使用 的库中排除该库
  • 我正在使用 Gradle
  • Tomcat 已经在 lib 文件夹中包含 annotations-api.jar 如何添加排除项有意义?
  • 很高兴它起作用了,我已按要求添加了答案,干杯

标签: java spring tomcat classloader tomcat8


【解决方案1】:

尝试在项目中添加 javax.persistence-api-2.2.jar 作为依赖项并将其从 tomcat lib 中删除,原因是您的 Web 应用程序的 /WEB-INF/lib/*.jar 将被加载首先,如果 Web 应用程序类加载器未配置为 delegate="true

正常顺序:

  1. JVM 的引导类(核心 java 类)
  2. /WEB-INF/Web 应用程序的类
  3. /WEB-INF/lib/*.jar 您的 Web 应用程序
  4. 系统类加载器类(Tomcat / Classpath 特定类)
  5. 通用类加载器类(所有网络应用通用的类)

使用 delegate="true" 然后订购:

  1. JVM 的引导类(核心 java 类)
  2. 系统类加载器类(Tomcat / Classpath 特定类)
  3. 通用类加载器类(所有网络应用通用的类)
  4. /WEB-INF/Web 应用程序的类
  5. /WEB-INF/lib/*.jar 您的 Web 应用程序

【讨论】:

    猜你喜欢
    • 2011-08-27
    • 2016-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2012-04-11
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    相关资源
    最近更新 更多