我正在尝试动态加载一个java类。基本思想是,jar包含在运行时动态加载的模块。我就是这样做的(我知道这很有技巧,但没有其他方法可以动态地将jar添加到已经存在的类加载器afaik中):
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
method.invoke(moduleLoader, new Object[] { file.toURI().toURL() });
Class fooClass = moduleLoader.loadClass("com.coderunner.Foo");
Object foo = fooClass.newInstance();
每个模块都带有@module注释。因此,为了获得关于模块的更多信息,我尝试获取注释。问题是foo上的注释是com类型的。太阳$代理27美元,而不是com。编码员。所以我得到了一个
ClassCastException: Cannot cast com.sun.proxy.$Proxy42 (id=64) to com.coderunner.Module
我得说我有点困惑这里发生了什么。我想做的事可能吗?怎样
编辑:我可能还应该提到,我正在spring/spring mvc和tomcat环境中尝试这一点。
我在尝试基于使用注释的声明性方法创建用于代码生成的ant任务时遇到了同样的问题。我发现代理对象的文档说明instanceof应该解决它,但这对我来说也不起作用。我终于找到了一个好朋友
注释[]注释=class Obj.get注释();
for(int i = 0;i < annotations.length;i++) {
Class<?>[] interfaces = annotations[i].getClass().getInterfaces();
for(int i2 = 0; i2 < interfaces.length;i2++) {
System.out.println("interface:" + interfaces[i2].getName());
}
给出原始注释的名称,因此将此名称与注释类名进行比较将得到所需的结果。
在注释类型前面有一个代理并不重要。它实际上可能会误导你,让你相信这是你遇到问题的原因。如果像“isAnnotationPresent(…)”这样的东西失败,这不是由于该代理,而是因为您使用多个类加载器多次加载注释类。例如,Jetty在默认情况下优先考虑WebApp类加载器。因此,如果Jetty服务器实例(或Tomcat或其他什么)已经加载了注释类,并且注释也位于WebApp的类路径上,那么可能会出现“getAnnotation()”之类的问题,无法返回任何内容。只需确保包含注释的库不会被加载两次。
Andreas提供的解决方案是一个非常肮脏的解决方法,只是掩盖了您可能无法控制/正确组织类加载的事实。
反射返回代理对象的事实并不妨碍您收集有关注释及其值的信息。
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()) {
//...
}
}
为了得到这个解决方案,我使用了以下帖子:如何使用反射获取注释类名、属性值
问题内容: 我有一个代码生成器,它使用URLClassLoader在指定的路径上加载类,扫描它们以查找批注,然后在字段/方法上使用Reflection,生成DTO。 在测试应用中,效果很好。 当我将其放入Maven MOJO中时,突然失去了在类上看到javax.persistence.Entity批注的能力。它加载它们,可以看到所有字段,但是Entity注释不再可见。 我假设这与Classpath
你可能认为下面的问题很简单,但我不知道我做错了什么。我觉得我添加了必需的依赖项。我没有吗? 谁能告诉我这里出了什么问题吗? 书JAVA ReadXMLFileJaxb.java 我的书。xml 波姆。xml
我使用契约优先的方法来构建JAX-WS Webservice。客户端使用wsdlLoction属性从SO答案https://stackoverflow.com/a/18323853/775467中指定的客户端jar中选择wsdl和xsd资源。 在服务器端也可以这样做吗。i、 e是否可以在sun-jaxws.xml中使用wsdl和jar中引用的xsd 我知道我可以像上面的代码片段一样引用WEB-IN
本文向大家介绍美化java代码,从合理注释开始,包括了美化java代码,从合理注释开始的使用技巧和注意事项,需要的朋友参考一下 请停止代码注释 “干净的代码应该像写好的散文一样” - Robert C. Martin 不良代码的通病就是有很多注释。这是凌乱的源代码最明显的迹象。 每个程序员的目标应该是编写干净和富有表现力的代码,以避免代码注释。每个变量,函数和类的目的应该隐含在其名称和结构中。 当
我刚开始学习Java,并在我的计算机上安装了JDK,但现在我正在尝试最简单的Java,而不是编译。我在C:/Java/jdk7上安装了JDK。 每当我尝试编译时,都会出现一个错误: 以下是我的编译过程: 我还尝试了: 我不知道我的代码是不是错了,但这是我的测试。java: 以下是JAVA_HOME: 任何帮助都将不胜感激!
我想用C#听Kafka主题的消息。 与Java中一样,还有一个注释@KafkaListener,当添加到函数上方时,它会侦听来自主题的消息,然后执行函数的逻辑。 示例-@KafkaListener(topics=“topicname”,groupId=“groupId”)//这里的函数代码 同样,C#中是否有使用Confluent的注释。Kafka