简体   繁体   English

如何使用Javassist进行字节码处理以解决链接错误?

[英]How to do bytecode manipulation with Javassist for solving linkage errors?

I have posted several question related to javassit linkage error spring Exception when running application on WebSphere with java 8 . 我已经发布了几个与javassit链接错误spring Exception有关的问题, 当在Java 8的WebSphere上运行应用程序时 Now after some research work around this topics and error, i have got some useful information about bytecode manipulation with Javassist to solve linkage error . 现在,在围绕该主题和错误进行了一些研究之后,我获得了一些有关使用Javassist进行字节码操作以解决链接错误的有用信息。

For your reference ( Already posted this stack trace in another questions here ) 供您参考(已经在另一个问题中将此堆栈跟踪信息发布在这里)

  [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

and i am getting this error on this java file , when i am trying do operation on org.springframework.aop.framework.ProxyCreatorSupport 当我尝试在org.springframework.aop.framework.ProxyCreatorSupport上执行操作时,我在此java文件上收到此错误

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);
        }
    }
}

on the line cc.toClass(); cc.toClass(); , i am getting this exception . ,我正在得到这个例外。 I have tried different class loader methods on WebSphere to solve this exception and getting same error . 我已经尝试在WebSphere上使用不同的类加载器方法来解决此异常并得到相同的错误。

Now i understood that linkage problem is occur when tries to modify the class already loaded by referenced classloader . 现在我知道, linkage problem is occur when tries to modify the class already loaded by referenced classloader . being able to solve this error , i should unload the class first from the reference classloader and i think it's difficult . 为了能够解决此错误,我should unload the class first from the reference classloader ,我认为这很困难。

  1. So i think the only method to solve this with the implementation of bytecode manipulation before the class loader by any class loader . 因此,我认为通过任何类加载器在类加载器之前执行字节码操作来解决此问题的唯一方法。 isn't? 是不是?
  2. How to change my existing code to bytecode manipulation with java agent ? 如何使用Java代理将现有代码更改为字节码操作? Any idea and suggestion ? 有什么想法和建议吗? please don't put as a duplicate question . 请不要重复提出问题。 This is only the reference work of the previous question . 这只是上一个问题的参考资料。

You need to write a Java agent and attach it dynamically to transform a class at load time. 您需要编写Java代理并将其动态附加以在加载时转换类。 You can find a cool tutorial here that explains how to do it. 您可以在此处找到一个不错的教程其中介绍了如何进行操作。

Note that this method allows you to intercept the class while it's loaded by the JVM and modify it after this loading is actually done. 请注意,此方法允许您在JVM加载类时对其进行拦截,并在实际完成加载后对其进行修改。

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

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