EclipseLink織入失敗:java.lang.AbstractMethodError _persistence_shallow_clone

最近在升級項目的版本,由jdk8.x升到jdk 11.x, 發現一個奇怪的EclipseLink異常:java.lang.AbstractMethodError does not define or inherit an implementation of the resolved method abstract _persistence_shallow_clone()
完整異常棧:

	java.lang.AbstractMethodError: Receiver class com.apobates.forum.core.entity.BoardActionCollection does not define or inherit an implementation of the resolved method abstract _persistence_shallow_clone()Ljava/lang/Object; of interface org.eclipse.persistence.internal.descriptors.PersistenceObject.
		at org.eclipse.persistence.descriptors.copying.PersistenceEntityCopyPolicy.buildClone(PersistenceEntityCopyPolicy.java:37)
		at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildBackupClone(ObjectBuilder.java:602)
		at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.buildBackupClone(DeferredChangeDetectionPolicy.java:233)
		at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:2270)
		at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:858)
		at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:745)
		at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:699)
		at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:861)
		at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:987)
		at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:598)
		at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1232)
		at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:911)
		at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1191)
		at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:485)
		at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1279)
		at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2983)
		at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1898)
		at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1880)
		at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1845)
		at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:262)
		at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:482)
		at javax.persistence.TypedQuery.getResultStream(TypedQuery.java:87)
		at jdk.internal.reflect.GeneratedMethodAccessor147.invoke(Unknown Source)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:566)
		at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:409)
		at com.sun.proxy.$Proxy87.getResultStream(Unknown Source)
		at com.apobates.forum.core.impl.dao.BoardActionCollectionDaoImpl.findAllMemberFavoriteBoard(BoardActionCollectionDaoImpl.java:241)
		at com.apobates.forum.core.impl.dao.BoardActionCollectionDaoImpl$$FastClassBySpringCGLIB$$85b044de.invoke(<generated>)
		at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
		at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:687)
		at com.apobates.forum.core.impl.dao.BoardActionCollectionDaoImpl$$EnhancerBySpringCGLIB$$6124c825.findAllMemberFavoriteBoard(<generated>)
		at com.apobates.forum.core.impl.service.BoardServiceImpl.getMemberFavorites(BoardServiceImpl.java:227)
		at com.apobates.forum.core.impl.service.BoardServiceImpl$$FastClassBySpringCGLIB$$c71260d2.invoke(<generated>)
		at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
		at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
		at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
		at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
		at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
		at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
		at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
		at com.apobates.forum.core.impl.service.BoardServiceImpl$$EnhancerBySpringCGLIB$$2256bf96.getMemberFavorites(<generated>)
		at com.apobates.forum.thrones.controller.MemberHomeController.getMemberStarBoard(MemberHomeController.java:558)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
		at java.base/java.lang.reflect.Method.invoke(Method.java:566)
		at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
		at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
		at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
		at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
		at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
		at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
		at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
		at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
		at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
		at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
		at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
		at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
		at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
		at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.bufferAndPostProcess(ContentBufferingFilter.java:169)
		at org.sitemesh.webapp.contentfilter.ContentBufferingFilter.doFilter(ContentBufferingFilter.java:126)
		at org.sitemesh.webapp.SiteMeshFilter.doFilter(SiteMeshFilter.java:120)
		at org.sitemesh.config.ConfigurableSiteMeshFilter.doFilter(ConfigurableSiteMeshFilter.java:163)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
		at com.apobates.forum.thrones.controller.helper.RequestTokenParameterFilter.doFilter(RequestTokenParameterFilter.java:87)
		at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
		at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
		at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
		at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
		at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
		at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
		at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
		at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
		at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
		at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
		at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
		at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
		at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
		at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
		at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
		at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
		at java.base/java.lang.Thread.run(Thread.java:834)

BoardActionCollection 類是一個子類, 實現單表繼承. 完全參考官方的示例: EclipseLink/Examples/JPA/Inheritance

具體代碼如下:

/**
 * 抽像的操作集合
 * 
 * @author xiaofanku
 * @since 20200514
 */
@Entity
@Table(name = "apo_action_event_set")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
@DiscriminatorValue("P")
public class ActionEventDescriptor implements Serializable {
//ETC
}

/**
 * 版塊的操作集合
 * 
 * @author xiaofanku
 * @since 20200514
 */
@Entity
@DiscriminatorValue("B")
public class BoardActionCollection extends ActionEventDescriptor{
//ETC
}

/**
 * 話題的操作集合
 * 
 * @author xiaofanku
 * @since 20200514
 */
@Entity
@DiscriminatorValue("T")
public class TopicActionCollection extends ActionEventDescriptor{}

子類TopicActionCollection 織入成功, 只有BoardActionCollection子類的業務方法調用失敗, 拋出上面的異常. 原來的織入設置,persistence.xml

      <property name="eclipselink.weaving" value="true"/>
      <property name="eclipselink.weaving.lazy" value="true"/>
      <property name="eclipselink.weaving.internal" value="true"/>

用spring3 + EclipseLink 2.5.2 + jdk8 運行沒問題, 後來升級到jdk8 + spring 5.0.7 + EclipseLink2.7.1 運行沒問題. 當前異常的環境爲: spring 5.2.6 + EclipseLink2.7.6 + jdk 11.0.2 + tomcat 9.x

原來一直以爲是環境沒配置對, 必竟是第一次寫jdk 11的項目. 去EclipseLink官方文檔一頓找,發現下面的文章:
AbstractMethodError: _persistence_shallow_clone()

Configuring Static Weaving

eclipselink-static-weave-plugin

按此路子可以解決. 在編譯時進行靜態織入, 也省的項目啓動時進行動態織入,項目的啓動時間也縮短了. 注意改用靜態織入需要在persistence.xml中進行如下變動:

      <property name="eclipselink.weaving" value="false"/>
      <property name="eclipselink.weaving.lazy" value="false"/>
      <property name="eclipselink.weaving.internal" value="true"/>

項目pom.xml的build部分如下:

    <build>
        <finalName>ROOT</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.0.1</version>
                <executions>
                    <execution>
                        <id>copy</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.20</version>
                <dependencies>
                    <dependency>
                        <groupId>org.apache.maven.surefire</groupId>
                        <artifactId>surefire-junit4</artifactId>
                        <version>2.20</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <argLine>-Dfile.encoding=${project.build.sourceEncoding}</argLine>
                    <argLine>-javaagent:${settings.localRepository}/org/springframework/spring-instrument/${spring-framework.version}/spring-instrument-${spring-framework.version}.jar</argLine>
                </configuration>
            </plugin>
            <plugin>
                <groupId>de.empulse.eclipselink</groupId>
                <artifactId>staticweave-maven-plugin</artifactId>
                <version>1.0.0</version>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>weave</goal>
                        </goals>
                        <configuration>
                            <persistenceXMLLocation>META-INF/persistence.xml</persistenceXMLLocation>
                            <logLevel>FINE</logLevel>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.eclipse.persistence</groupId>
                        <artifactId>org.eclipse.persistence.jpa</artifactId>
                        <version>${eclipselink.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章