Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Javassist向运行时生成的类添加注释_Java_Annotations_Javassist - Fatal编程技术网

使用Javassist向运行时生成的类添加注释

使用Javassist向运行时生成的类添加注释,java,annotations,javassist,Java,Annotations,Javassist,我正在使用Javassist(Java1.7)向类ClassA添加注释,但我得到了一个异常。我做错了什么?我尝试的代码如下所示: ClassA.java public class ClassA { } 添加方法 public static <T> Class<T> addXmlRootAnnotationDynamicly(Class<T> declaredTyp) throws NotFoundException, CannotCompileExcept

我正在使用Javassist(Java1.7)向类ClassA添加注释,但我得到了一个异常。我做错了什么?我尝试的代码如下所示:

ClassA.java

public class ClassA
{

}
添加方法

public static <T> Class<T> addXmlRootAnnotationDynamicly(Class<T> declaredTyp) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException
{
    //pool creation 
    ClassPool pool = ClassPool.getDefault();
    //extracting the class
    CtClass cc = pool.getCtClass(declaredTyp.getCanonicalName());

    // create the annotation
    ClassFile ccFile = cc.getClassFile();
    ConstPool constpool = ccFile.getConstPool();
    AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
    Annotation annot = new Annotation("javax.xml.bind.annotation.XmlRootElement", constpool);
    attr.addAnnotation(annot);

    // add the annotation to the class
    cc.getClassFile().addAttribute(attr);

    // transform the ctClass to java class
    Class<T> dynamiqueBeanClass = cc.toClass();

    //instanciating the updated class 
    //      T sayHelloBean = dynamiqueBeanClass.newInstance();

    return dynamiqueBeanClass;

}
公共静态类addXmlRootAnnotationDynamicly(类declaredTyp)抛出NotFoundException、CannotCompileException、InstanceionException、IllegaAccess Exception
{
//池创建
ClassPool=ClassPool.getDefault();
//提取类
CtClass cc=pool.getCtClass(declaredTyp.getCanonicalName());
//创建注释
ClassFile ccFile=cc.getClassFile();
ConstPool ConstPool=ccFile.getConstPool();
AnnotationsAttribute attr=新的AnnotationsAttribute(constpool,AnnotationsAttribute.visibleTag);
Annotation annot=new注释(“javax.xml.bind.Annotation.XmlRootElement”,constpool);
属性添加注释(注释);
//将注释添加到类中
cc.getClassFile().addAttribute(attr);
//将ctClass转换为java类
类dynamicquebeanclass=cc.toClass();
//实例化更新的类
//T sayHelloBean=dynamiqueBeanClass.newInstance();
返回动态类;
}
召唤

Class addXmlRootAnnotationDynamicly=addXmlRootAnnotationDynamicly(ClassA.Class);
例外情况

javassist.cannotcompileeException:by java.lang.LinkageError:loader(sun/misc/Launcher$AppClassLoader的实例):尝试复制名称的类定义:“de/it_p/pvlight/share/util/ClassA” 位于javassist.ClassPool.toClass(ClassPool.java:1099) 位于javassist.ClassPool.toClass(ClassPool.java:1042) 位于javassist.ClassPool.toClass(ClassPool.java:1000) 位于javassist.CtClass.toClass(CtClass.java:1224) 位于de.it_p.pvlight.share.util.JAXBUtil.addXmlRootAnnotationDynamicly(JAXBUtil.java:107) 在de.it_p.pvlight.share.util.JAXBUtilTest.addXmlRootAnnotationDynamicly(JAXBUtilTest.java:60) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于java.lang.reflect.Method.invoke(Method.java:606) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于java.lang.reflect.Method.invoke(Method.java:606) 位于org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 位于org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 原因:java.lang.LinkageError:loader(sun/misc/Launcher$AppClassLoader的实例):尝试为名称重复类定义:“de/it_p/pvlight/share/util/ClassA” 位于java.lang.ClassLoader.defineClass1(本机方法) 位于java.lang.ClassLoader.defineClass(ClassLoader.java:800) 位于java.lang.ClassLoader.defineClass(ClassLoader.java:643) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于java.lang.reflect.Method.invoke(Method.java:606) 位于javassist.ClassPool.toClass2(ClassPool.java:1112) 位于javassist.ClassPool.toClass(ClassPool.java:1093) ... 还有15个


可以在堆栈跟踪中找到问题的根源:

尝试为名称复制类定义:“de/it\p/pvlight/share/util/ClassA”

您的
addXmlRootAnnotationDynamicly
方法接受一个加载的类,并在不更改其名称的情况下重新定义这个非常相同的类。在重新定义之后,您将再次尝试加载修改过的类。然而,这在Java中是不可能的,因为任何人都可以

因此,
pool.getCtClass
方法采用
字符串而不是加载的
,并与
CtClass
es一起工作,后者用于描述卸载的
es。要解决您的问题,您有不同的选择:

  • 将方法的签名更改为
    addXmlRootAnnotationDynamicly(String)
    ,并将
    de.it\u p.pvlight.share.util.ClassA
    作为参数传递。确保在转换该类之前,未在代码中的任何位置加载该类。因此,您应该在应用程序启动时运行转换,以确保在转换之前不会意外加载该类。然后将更改后的
    加载到
    cc.toClass()
  • 创建使用随机名称的参数类(或使用接口)的子类。然后,子类与参数类的类型兼容,但从未加载
  • 使用在运行时重新定义加载的类
  • 确保输入类和输出类加载了不同的
    ClassLoader
    s。(不推荐)
Class<ClassA> addXmlRootAnnotationDynamicly = addXmlRootAnnotationDynamicly(ClassA.class);