2017-10-13 94 views
0

我發佈了幾個與javassit鏈接錯誤spring Exception when running application on WebSphere with java 8有關的問題。現在經過一些關於這個主題和錯誤的研究後,我已經獲得了一些有關Javassist的字節碼操作以解決鏈接錯誤的有用信息。如何使用Javassist進行字節碼操作來解決鏈接錯誤?

供您參考(已貼在這裏的另一個問題,該堆棧跟蹤)

[10/13/17 ] 00000089 webapp  E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet                  Error]-[weblge]: java.lang.ExceptionInInitializerError 
     at java.lang.J9VMInternals.ensureError(J9VMInternals.java:134) 
     at java.lang.J9VMInternals.recordInitializationFailure(J9VMInternals.java:123) 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
     at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:83) 
     at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:57) 
     at java.lang.reflect.Constructor.newInstance(Constructor.java:437) 
     at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163) 
     at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:120) 
     at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:345) 
     at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:278) 
     at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103) 
     at com.ibm.ws.webcontainer.webapp.WebApp.notifyServletContextCreated(WebApp.java:1826) 
     at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:442) 
     at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88) 
     at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:171) 
     at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:904) 
     at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:789) 
     at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:427) 
     at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:719) 
     at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1247) 
     at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1514) 
     at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:704) 
     at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:1096) 
     at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:799) 
     at com.ibm.ws.runtime.component.ApplicationMgrImpl$5.run(ApplicationMgrImpl.java:2315) 
     at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5488) 
     at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5614) 
     at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255) 
     at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2320) 
     at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:436) 
     at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123) 
     at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:379) 
     at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:127) 
     at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:985) 
     at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:524) 
     at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1909) 
Caused by: java.lang.IllegalStateException: javassist.CannotCompileException: by java.lang.LinkageError: org.springframework.aop.framework.ProxyCreatorSupport 
     at org.springframework.aop.framework.JavassistApplicationContext.<clinit>(JavassistApplicationContext.java:36) 
     ... 34 more 
Caused by: javassist.CannotCompileException: by java.lang.LinkageError: org.springframework.aop.framework.ProxyCreatorSupport 
     at javassist.ClassPool.toClass(ClassPool.java:1170) 
     at javassist.ClassPool.toClass(ClassPool.java:1113) 
     at javassist.ClassPool.toClass(ClassPool.java:1071) 
     at javassist.CtClass.toClass(CtClass.java:1275) 
     at org.springframework.aop.framework.JavassistApplicationContext.<clinit>(JavassistApplicationContext.java:34) 
     ... 34 more 
Caused by: java.lang.LinkageError: org.springframework.aop.framework.ProxyCreatorSupport 
     at java.lang.ClassLoader.defineClassImpl(Native Method) 
     at java.lang.ClassLoader.defineClass(ClassLoader.java:357) 
     at java.lang.ClassLoader.defineClass(ClassLoader.java:293) 
     at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) 
     at java.lang.reflect.Method.invoke(Method.java:508) 
     at javassist.ClassPool.toClass2(ClassPool.java:1183) 
     at javassist.ClassPool.toClass(ClassPool.java:1164) 
     ... 38 more 

和我對這個Java文件收到此錯誤,當我試圖做操作org.springframework.aop.framework.ProxyCreatorSupport

package org.spring.aop.framework; 

import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.CtConstructor; 
import javassist.LoaderClassPath; 
import org.springframework.web.context.support.XmlWebApplicationContext; 

public class JavassistApplicationContext extends XmlWebApplicationContext { 

    static { 
     ClassPool classPool = ClassPool.getDefault(); 
     try { 
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
      classPool.appendClassPath(new LoaderClassPath(classLoader)); 

      CtClass cc = classPool.get("org.spring.aop.framework.ProxyCreatorSupport"); 
      CtConstructor c = cc.getConstructors()[0]; 
      c.insertAfter("$0.aopProxyFactory = new org.spring.aop.framework.JavassistAopProxyFactory();"); 
      cc.toClass(); 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

就行cc.toClass();,我得到這個例外。我在WebSphere上嘗試了不同的類加載器方法來解決此異常並獲得相同的錯誤。

現在我明白,linkage problem is occur when tries to modify the class already loaded by referenced classloader .能夠解決這個錯誤,我should unload the class first from the reference classloader,我認爲這是困難的。

  1. 所以我認爲唯一的方法來解決這個問題,通過任何類加載器之前的類加載器實現字節碼操作。是不是?
  2. 如何將我現有的代碼更改爲使用java代理的字節碼操作?任何想法和建議?請不要把它作爲一個重複的問題。這只是上一個問題的參考工作。
+0

有什麼建議嗎? –

回答

1

您需要編寫a Java agent並動態附加它以在加載時轉換類。你可以找到一個很酷的教程here,解釋如何做到這一點。

請注意,此方法允許您在JVM加載它時攔截類,並在實際完成此加載後對其進行修改。

+0

此檢測過程將解決「由於類加載器導致的鏈接錯誤」? –

+0

我認爲這可能會因爲這將修改你的類,而他們正在加載,而不是當他們已經加載。通過這個過程,我構建了一個軟件,可以對目標軟件的每個庫進行測試,我從來沒有遇到過錯誤。只需試一試 – rakwaht

+0

好的謝謝。我想在現有的代碼中添加這個工具支持。我在/ WEB_INF/lib路徑上使用了Javassit庫。因爲我的代碼已經和我在一起,我想知道是否應該只添加Java代理代碼或其他任何額外的東西。 –