Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
Java URLClassLoader将注释加载为com.sun.$Proxy$27_Java_Spring_Annotations_Classloader_Urlclassloader - Fatal编程技术网

Java URLClassLoader将注释加载为com.sun.$Proxy$27

Java URLClassLoader将注释加载为com.sun.$Proxy$27,java,spring,annotations,classloader,urlclassloader,Java,Spring,Annotations,Classloader,Urlclassloader,我正在尝试动态加载一个java类。基本思想是,jar包含在运行时动态加载的模块。我就是这样做的(我知道这很有技巧,但是没有其他方法可以动态地将jar添加到已经存在的类加载器afaik中): 每个模块都使用@module注释进行注释。因此,为了获得关于模块的更多信息,我尝试获取注释。问题是foo上的注释的类型是com.sun.$Proxy$27,而不是com.coderunner.Module,因此我得到了一个 ClassCastException: Cannot cast com.sun.pro

我正在尝试动态加载一个java类。基本思想是,jar包含在运行时动态加载的模块。我就是这样做的(我知道这很有技巧,但是没有其他方法可以动态地将jar添加到已经存在的类加载器afaik中):

每个模块都使用@module注释进行注释。因此,为了获得关于模块的更多信息,我尝试获取注释。问题是foo上的注释的类型是com.sun.$Proxy$27,而不是com.coderunner.Module,因此我得到了一个

ClassCastException: Cannot cast com.sun.proxy.$Proxy42 (id=64) to com.coderunner.Module
我得说我对这里发生的事情有点困惑。我想做的事可能吗?怎么做


编辑:我可能还应该提到,我正在spring/spring mvc和tomcat环境中尝试这一点。

我在尝试基于使用注释的声明性方法创建代码生成的ant任务时遇到了相同的问题。 我发现代理对象的文档说明instanceof应该解决它, 但这对我也不起作用。 我终于找到了一个好朋友

Annotation[]annotations=classObj.getAnnotations()

for(int i=0;i

为my指定原始注释的名称,因此将此名称与注释类名进行比较将得到所需的结果。

反射返回代理对象的事实并不妨碍您收集有关注释及其值的信息

getclass方法返回一个代理对象:

 log.info("annotation class:" + annotation.getClass());
输出:

 [INFO] annotation class:class com.sun.proxy.$Proxy16class 
输出与示例中的相同,但这没有问题。具有方法(或字段)就足够了。附加部分是调用注释方法

public void analyseClass(Class myClass) {

    for (Method method: myClass.getMethods()) {
        System.out.println("aanotations :" + Arrays.toString(field.getAnnotations()));

        for (Annotation annotation : method.getAnnotations()) {

            log.info("annotation class:" + annotation.getClass());
            log.info("annotation class type:" + annotation.annotationType());

            Class<Annotation> type = (Class<Annotation>) annotation.annotationType();

            /* extract info only for a certain annotation */
            if(type.getName().equals(MyAnnotation.class.getName())) {

                 String annotationValue = 
                     (String) type.getMethod("MY_ANNOTATION_CERTAIN_METHOD_NAME").invoke(annotation);

                 log.info("annotationValue :" + annotationValue);
                 break;
            }
        }
    }

    //do the same for the fields of the class
    for (Field field : myClass.getFields()) {
         //...
    }

}  
public void分析类(类myClass){
对于(方法:myClass.getMethods()){
System.out.println(“aanotations:+Arrays.toString(field.getAnnotations()));
for(注释:方法.getAnnotations()){
log.info(“注释类:+annotation.getClass());
log.info(“注释类类型:”+annotation.annotationType());

在注释类型前面有一个代理这一事实应该无关紧要。它实际上可能会误导您,使您相信这是您遇到问题的原因。如果像“isAnnotationPresent(…)”这样的内容失败,这不是由于该代理,而是因为您使用多个类加载器多次加载注释类。例如,Jetty默认优先于WebApp类加载器。因此,如果您的Jetty服务器实例(或Tomcat或其他)已加载批注类,并且批注也位于您的WebApp的类路径上,您可能会遇到诸如“getAnnotation()”不返回任何内容之类的问题。只需确保包含批注的库未加载两次

Andreas提供的解决方案是一个非常肮脏的解决方法,只是掩盖了一个事实,即您可能无法控制/正确组织类加载

 [INFO] annotation class:class com.sun.proxy.$Proxy16class 
public void analyseClass(Class myClass) {

    for (Method method: myClass.getMethods()) {
        System.out.println("aanotations :" + Arrays.toString(field.getAnnotations()));

        for (Annotation annotation : method.getAnnotations()) {

            log.info("annotation class:" + annotation.getClass());
            log.info("annotation class type:" + annotation.annotationType());

            Class<Annotation> type = (Class<Annotation>) annotation.annotationType();

            /* extract info only for a certain annotation */
            if(type.getName().equals(MyAnnotation.class.getName())) {

                 String annotationValue = 
                     (String) type.getMethod("MY_ANNOTATION_CERTAIN_METHOD_NAME").invoke(annotation);

                 log.info("annotationValue :" + annotationValue);
                 break;
            }
        }
    }

    //do the same for the fields of the class
    for (Field field : myClass.getFields()) {
         //...
    }

}