java.lang.NoSuchMethodError 因为 Tomcat 的 lib 文件夹中有重复的 class
java.lang.NoSuchMethodError because of duplicate class available in lib folder of Tomcat
我正面临
java.lang.NoSuchMethodError:javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType
在 Tomcat 8 中部署我的应用程序时,因为 tomcat class 加载程序正在从位于 [=35] 的注释-api.jar 文件加载 PersistenceContext class =] 文件夹和 PersistenceContext class from annotations-api.jar 不包含同步方法如下
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 class 我已经复制到 TOMCAT_HOME\lib 文件夹而不是注释-api.jar 存在于 TOMCAT_HOME\lib 文件夹中,因为来自 javax.persitence-api-2.2 jar 的 PersistenceContext class 包含如下同步方法
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- 加载 PersistenceContext class 2.2.jar代替注解-api.jar ?
编辑:Tomcat 8 lib 文件夹已经包含注释-api.jar 并且我已经在 lib 文件夹中复制了 javax.persistence-api-2.2.jar Tomcat 在 Tomcat 8 中支持 eclipselink,因此我的 dependencies.gradle 中的 exclude annotations-api.jar 选项不会有帮助,因为 annotations-api.jar 已经是Tomcat 的 lib 文件夹。我没有自己加注解-api.jar
注意:相同的应用程序是 Tomcat 9 中的 运行 文件,因为 Tomcat 9 中的注释-api.jar 不包含 javax.persistence 包。
尝试将 javax.persistence-api-2.2.jar 添加为项目的依赖项并将其从 tomcat 库中删除,原因是 /WEB-INF/lib/* 如果 Web 应用程序 class 加载程序未配置 delegate="true
,则将首先加载 Web 应用程序的 .jar
正常顺序:
- Bootstrap class 你的 JVM(核心 java classes)
您的 Web 应用程序 - /WEB-INF/classes
- /WEB-INF/lib/*.jar 你的网络应用程序
- 系统 class 加载程序 classes(Tomcat / 类路径特定 classes)
- 通用 class 加载器 classes(classes 对所有网络应用程序通用)
使用 delegate="true" 然后命令:
- Bootstrap class 你的 JVM(核心 java classes)
- 系统 class 加载程序 classes(Tomcat / 类路径特定 classes)
- 通用 class 加载器 classes(classes 对所有网络应用程序通用)
您的 Web 应用程序 - /WEB-INF/classes
- /WEB-INF/lib/*.jar 你的网络应用程序
我正面临
java.lang.NoSuchMethodError:javax.persistence.PersistenceContext.synchronization()Ljavax/persistence/SynchronizationType
在 Tomcat 8 中部署我的应用程序时,因为 tomcat class 加载程序正在从位于 [=35] 的注释-api.jar 文件加载 PersistenceContext class =] 文件夹和 PersistenceContext class from annotations-api.jar 不包含同步方法如下
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 class 我已经复制到 TOMCAT_HOME\lib 文件夹而不是注释-api.jar 存在于 TOMCAT_HOME\lib 文件夹中,因为来自 javax.persitence-api-2.2 jar 的 PersistenceContext class 包含如下同步方法
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- 加载 PersistenceContext class 2.2.jar代替注解-api.jar ?
编辑:Tomcat 8 lib 文件夹已经包含注释-api.jar 并且我已经在 lib 文件夹中复制了 javax.persistence-api-2.2.jar Tomcat 在 Tomcat 8 中支持 eclipselink,因此我的 dependencies.gradle 中的 exclude annotations-api.jar 选项不会有帮助,因为 annotations-api.jar 已经是Tomcat 的 lib 文件夹。我没有自己加注解-api.jar
注意:相同的应用程序是 Tomcat 9 中的 运行 文件,因为 Tomcat 9 中的注释-api.jar 不包含 javax.persistence 包。
尝试将 javax.persistence-api-2.2.jar 添加为项目的依赖项并将其从 tomcat 库中删除,原因是 /WEB-INF/lib/* 如果 Web 应用程序 class 加载程序未配置 delegate="true
,则将首先加载 Web 应用程序的 .jar正常顺序:
- Bootstrap class 你的 JVM(核心 java classes) 您的 Web 应用程序
- /WEB-INF/classes
- /WEB-INF/lib/*.jar 你的网络应用程序
- 系统 class 加载程序 classes(Tomcat / 类路径特定 classes)
- 通用 class 加载器 classes(classes 对所有网络应用程序通用)
使用 delegate="true" 然后命令:
- Bootstrap class 你的 JVM(核心 java classes)
- 系统 class 加载程序 classes(Tomcat / 类路径特定 classes)
- 通用 class 加载器 classes(classes 对所有网络应用程序通用) 您的 Web 应用程序
- /WEB-INF/classes
- /WEB-INF/lib/*.jar 你的网络应用程序