2017-09-21 103 views
0

我使用了Javassist 3.19.0-GA jar文件修改构造函数体使用Java代码。这是我的代码收到错误时使用了Javassist修改类

<dependency> 
    <groupId>org.javassist</groupId> 
    <artifactId>javassist</artifactId> 
    <version>3.19.0-GA</version> 
</dependency> 

和java文件

package org.springframework.aop.framework; 

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

public class JavassistApplication extends XmlWebApplicationContext { 

    static { 
     ClassPool classPool = ClassPool.getDefault(); 
     try { 
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
      classPool.appendClassPath(new LoaderClassPath(classLoader)); 
      CtClass cc = classPool.get("org.springframework.aop.framework.ProxyCreatorSupport"); 
      /*modify the constructor body with java code*/ 
      CtConstructor c = cc.getConstructors()[0]; 
      c.insertAfter("$0.aopProxyFactory = new org.springframework.aop.framework.JavassistAopProxyFactory();"); 
      /*Here getting exceptions when i run*/ 
      cc.toClass(); 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 

和代码JavassistAopProxyFactory():

package org.springframework.aop.framework; 
import org.springframework.aop.SpringProxy; 
import org.springframework.util.ClassUtils; 
import java.io.Serializable; 

public class JavassistAopProxyFactory implements AopProxyFactory, Serializable { 

    private static final long serialVersionUID = -37444691555886L; 
    // Whether the Javassist library is present on the classpath 
    private static final boolean javassistAvailable = 
      ClassUtils.isPresent("javassist.ClassPool", JavassistAopProxyFactory.class.getClassLoader()); 


    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 
     if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { 
      Class targetClass = config.getTargetClass(); 
      if (targetClass == null) { 
       throw new AopConfigException("TargetSource cannot determine target class: " + 
         "Either an interface or a target is required for proxy creation."); 
      } 
      if (targetClass.isInterface()) { 
       return new JdkDynamicAopProxy(config); 
      } 
      if (!javassistAvailable) { 
       throw new AopConfigException(
         "Cannot proxy target class because Javassist is not available. " + 
           "Add Javassist to the class path or specify proxy interfaces."); 
      } 
      return new JavassistAopProxy(config); 
     } else { 
      return new JdkDynamicAopProxy(config); 
     } 
    } 

    /** 
    * Determine whether the supplied {@link AdvisedSupport} has only the 
    * {@link org.springframework.aop.SpringProxy} interface specified 
    * (or no proxy interfaces specified at all). 
    */ 
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { 
     Class[] interfaces = config.getProxiedInterfaces(); 
     return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0]))); 
    } 

} 

,我得到错误的

java.lang.IllegalStateException: javassist.CannotCompileException: by java.lang.LinkageError: org.springframework.aop.framework.ProxyCreatorSupport 
at org.springframework.aop.framework.JavassistApplicationContext.<clinit> 

我试着加入cc.defrost();cc.writeFile();。我不知道为什么会出现这个异常。这是JavassistAopProxyFactory类的新方法中的问题吗?

c.insertAfter("$0.aopProxyFactory = new org.springframework.aop.framework.JavassistAopProxyFactory();"); 

而且在classpool.class文件,我可以看到代码

public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain) 
/*  */  throws CannotCompileException 
/*  */ { 
/*  */  try 
/*  */  { 
/* 1065 */  byte[] b = ct.toBytecode(); 
/*  */  Object[] args; 
/*  */  Method method; 
/* 1068 */  Object[] args; if (domain == null) { 
/* 1069 */   Method method = defineClass1; 
/* 1070 */   args = new Object[] { ct.getName(), b, new Integer(0), new Integer(b.length) }; 
/*  */  } 
/*  */  else 
/*  */  { 
/* 1074 */   method = defineClass2; 
/* 1075 */   args = new Object[] { ct.getName(), b, new Integer(0), new Integer(b.length), domain }; 
/*  */  } 
/*  */  
/*  */ 
/* 1079 */  return toClass2(method, loader, args); 
/*  */  } 
/*  */  catch (RuntimeException e) { 
/* 1082 */  throw e; 
/*  */  } 
/*  */  catch (InvocationTargetException e) { 
/* 1085 */  throw new CannotCompileException(e.getTargetException()); 
/*  */  } 
/*  */  catch (Exception e) { 
/* 1088 */  throw new CannotCompileException(e); 
/*  */  } 
/*  */ } 
/*  */ 

我得到异常的行号1085

我从Use javassist to modify fields that use getters and setters in a class constructorjava javassist.CannotCompileException: by java.lang.LinkageError: loader研究一些类似的问题。但仍然有同样的问题。任何解决方案

+0

我认为大家都知道,在Javassist是'$ 0'是一个特殊的标识符。那么什么是假设'$ 0.aopProxyFactory = ..'? – rakwaht

+0

$ 0相当于此。如果该方法是静态的,$ 0不是可用 –

+0

您是否尝试过使用'公共无效setAopProxyFactory(AopProxyFactory aopProxyFactory)',而不是直接分配值的变量? – rakwaht

回答

0

我会尝试与改变,并呼吁与内部setter设置工厂:

package org.springframework.aop.framework; 

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

public class JavassistApplication extends XmlWebApplicationContext { 

    public JavassistApplication(){ 
     ClassPool classPool = ClassPool.getDefault(); 
     try { 
      // ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
      // classPool.appendClassPath(new LoaderClassPath(classLoader)); 
      CtClass cc = classPool.get("org.springframework.aop.framework.ProxyCreatorSupport"); 
      /*modify the constructor body with java code*/ 
      CtConstructor c = cc.getConstructors()[0]; 
      c.insertAfter("setAopProxyFactory(new org.springframework.aop.framework.JavassistAopProxyFactory());"); 
      /*Here getting exceptions when i run*/ 
      cc.toClass(); 
     } catch (Exception e) { 
      throw new IllegalStateException(e); 
     } 
    } 
} 
+0

我应该再次将此值分配给aopProxyFactory吗?像void'setAopProxyFactory(AopProxyFactory aopProxyFactory){this.aopProxyFactory = aopProxyFactory;}'我怎样才能声明这个函数的定义?你能否更新代码? –

+0

只是尝试像我贴的代码,并告诉我什么是结果 – rakwaht

+0

仍然得到相同的例外。什么也没有变 。 '产生的原因:java.lang.IllegalStateException:javassist.CannotCompileException:由java.lang.LinkageError的:org.springframework.aop.framework.ProxyCreatorSupport 在org.springframework.aop.framework.JavassistApplication。 (JavassistApplication.java:36)' –