java 反射无法获得类类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16824745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 00:05:42  来源:igfitidea点击:

Reflections could not get class type

javagoogle-reflections

提问by Kezz101

So I am using the Java Reflections API to search another jar for Classes that extend Foousing the following code:

所以我使用 Java Reflections API 在另一个 jar 中搜索Foo使用以下代码扩展的类:

Reflections reflections = new Reflections("com.example");
for(Class<? extends Foo> e : reflections.getSubTypesOf(Foo.class)) {
    doSomething()
}

When I do this Reflections throws the following error:

当我这样做时,反射会引发以下错误:

org.reflections.ReflectionsException: could not get type for name com.example.ExtendsFoo

Does anyone know how to fix this cause I'm stumped?

有谁知道如何解决这个问题,因为我很难过?

Thanks in advance!

提前致谢!

采纳答案by chooks

The problem may be due to not having a class loader that can resolve the name (even though it can resolve the subtype). This sounds contradictory, but I had the error message when I was building a Configuration and using ClasspathHelper.forClassLoaderon an application- instantiated URLClassloader to figure out what to scan on the classpath, but not passing in said URLClassLoader into the Reflections configuration so that it could instantiate things correctly.

问题可能是由于没有可以解析名称的类加载器(即使它可以解析子类型)。这听起来很矛盾,但是当我构建配置并ClasspathHelper.forClassLoader在应用程序实例化的 URLClassloader 上使用以找出在类路径上扫描的内容时,我收到了错误消息,但没有将所述 URLClassLoader 传递到 Reflections 配置中,以便它可以实例化事物正确。

So you may want to try something along the lines of the following:

因此,您可能想尝试以下方法:

URLClassLoader urlcl = new URLClassLoader(urls);
Reflections reflections = new Reflections(
  new ConfigurationBuilder().setUrls(
    ClasspathHelper.forClassLoader(urlcl)
  ).addClassLoader(urlcl)
);

where urlsis an array of URLS to the jars containing the classes you want to load. I was getting the same error as you if I did not have the final addClassLoader(...)call to the ConfigurationBuilder.

其中urls是包含要加载的类的 jar 的 URL 数组。如果我没有addClassLoader(...)ConfigurationBuilder.

If this doesn't work, or is not applicable, it may be worth just setting a breakpoint in ReflectionsUtil.forName(String typeName, ClassLoader... classLoaders))to see what is going on.

如果这不起作用或不适用,可能值得只设置一个断点ReflectionsUtil.forName(String typeName, ClassLoader... classLoaders))以查看发生了什么。

回答by yegor256

Take a look: https://code.google.com/p/reflections/issues/detail?id=163

看一看:https: //code.google.com/p/reflections/issues/detail?id=163

Reflections (in its current version 0.9.9-RC1) doesn't re-throw exception correctly. That's why you may miss the true cause of the problem. In my case it was a broken .classfile, which my default class loader failed to load and threw an exception. So, first of all, try to make sure that your class is truly loadable.

反射(在其当前版本 0.9.9-RC1 中)不会正确地重新抛出异常。这就是为什么您可能会错过问题的真正原因。在我的情况下,它是一个损坏的.class文件,我的默认类加载器无法加载并引发异常。因此,首先,请尝试确保您的类真正可加载。

回答by Satya

Scanning for classes is not easy with pure Java.

使用纯 Java 扫描类并不容易。

The spring framework offers a class called ClassPathScanningCandidateComponentProvider that can do what you need. The following example would find all subclasses of MyClass in the package org.example.package

spring 框架提供了一个名为 ClassPathScanningCandidateComponentProvider 的类,它可以满足您的需求。以下示例将在包 org.example.package 中找到 MyClass 的所有子类

ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
 provider.addIncludeFilter(new AssignableTypeFilter(MyClass.class));

// scan in org.example.package
 Set<BeanDefinition> components = provider.findCandidateComponents("org/example/package");
for (BeanDefinition component : components)
{

This method has the additional benefit of using a bytecode analyzer to find the candidates which means it will not load all classes it scans. Class cls = Class.forName(component.getBeanClassName()); // use class cls found }

此方法具有使用字节码分析器查找候选对象的额外好处,这意味着它不会加载它扫描的所有类。Class cls = Class.forName(component.getBeanClassName()); // 使用找到的类 cls }

Fore more info read the link

欲了解更多信息,请阅读链接