2017-09-21 105 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)' –