我有一个Reflections库的问题.我试图动态加载实现特定接口的所有类.只要我不在这些类中使用lambda表达式(java 8),一切正常(所有类都已加载).我尝试升级lib版本,但效果是相同的(java.io.IOException:无效的常量类型:18).
依赖并在pom.xml中构建
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.19.0-GA</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Run Code Online (Sandbox Code Playgroud)
不排斥是同样的效果.
码:
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader child = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
ConfigurationBuilder builder = new ConfigurationBuilder()
.addClassLoader(child)
.addUrls(jarUrl)
.setScanners(new SubTypesScanner());
Reflections r = new Reflections(builder);
return r.getSubTypesOf(cls);
Run Code Online (Sandbox Code Playgroud)
如何使用lambda表达式加载类?
PS抱歉英语:)
所以我使用Java Reflections API在另一个jar中搜索Foo 使用以下代码扩展的类:
Reflections reflections = new Reflections("com.example");
for(Class<? extends Foo> e : reflections.getSubTypesOf(Foo.class)) {
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,思考会抛出以下错误:
org.reflections.ReflectionsException: could not get type for name com.example.ExtendsFoo
Run Code Online (Sandbox Code Playgroud)
有谁知道如何解决这个问题我难倒?
提前致谢!
我想使用Google Reflections从我的Maven插件中扫描已编译项目中的类.但默认情况下,插件不会看到项目的已编译类.从Maven 3文档我读到:
需要从项目的compile/runtime/test类路径加载类的插件需要与mojo注释@requiresDependencyResolution一起创建自定义URLClassLoader.
至少可以说这有点模糊.基本上我需要一个加载已编译项目类的类加载器的引用.我怎么做到的?
编辑:
好的,@Mojo注释有requiresDependencyResolution参数,所以这很容易,但仍然需要正确的方法来构建一个类加载器.
如果我有
Reflections reflections = new Reflections("my.package", classLoader, new SubTypesScanner(false));
Run Code Online (Sandbox Code Playgroud)
然后这会找到我的枚举类
Set<Class<? extends Enum>> enums = reflections.getSubTypesOf(Enum.class);
Run Code Online (Sandbox Code Playgroud)
但事实并非如此
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
Run Code Online (Sandbox Code Playgroud)
是否有一个原因?
可重复的例子:
package cupawntae;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
public class Reflector {
public static void main(String[] args) {
Reflections reflections = new Reflections("cupawntae", Reflector.class.getClassLoader(), new SubTypesScanner(false));
System.out.println("Objects: " + reflections.getSubTypesOf(Object.class));
System.out.println("Enums: " + reflections.getSubTypesOf(Enum.class));
System.out.println("Enum's superclass: " + Enum.class.getSuperclass());
}
}
Run Code Online (Sandbox Code Playgroud)
枚举类:
package cupawntae;
public enum MyEnum {
}
Run Code Online (Sandbox Code Playgroud)
输出:
Objects: [class cupawntae.Reflector]
Enums: [class cupawntae.MyEnum]
Enum's superclass: class …Run Code Online (Sandbox Code Playgroud) 我正在使用Google Reflections库来查询类路径中的某些资源.这些资源与我项目中的类位于同一位置.
我写了一些单元测试,这些测试在Eclipse中作为单元测试执行时成功,但是当我尝试用Maven执行它们时(maven install例如),它们没有按预期工作.经过一些调试,显然问题是当使用Maven执行时,Reflections库找不到资源所在的类路径url.
我得出结论,研究Reflection如何确定应检查的类路径URL.作为一个例子,下面的方法显示了Reflection如何在给定类加载器的情况下找到可用的类路径URL(原始的Reflection方法已经简化了一点):
public static Set<URL> forClassLoader(ClassLoader... classLoaders) {
final Set<URL> result = Sets.newHashSet();
for (ClassLoader classLoader : classLoaders) {
while (classLoader != null) {
if (classLoader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) classLoader).getURLs();
if (urls != null) {
result.addAll(Sets.<URL>newHashSet(urls));
}
}
classLoader = classLoader.getParent();
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
简而言之,它遍历类加载器层次结构,询问每个单独的类加载器的URL.
在Eclipse中,我使用类似这样的单元测试调用前一个方法:
ClassLoader myClassClassLoader = <MyClass>.class.getClassLoader(); //<MyClass> is in the same classpath url than the resources I need to find
Set<URL> urls = forClassLoader(myClassClassLoader); …Run Code Online (Sandbox Code Playgroud) 我正在使用google Reflections包来构建可用于调用的所有类的索引.以下代码应该返回JVM中加载的所有类:
List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false), new ResourcesScanner())
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))));
Set<Class<? extends Object>> allClasses =
reflections.getSubTypesOf(Object.class);
Run Code Online (Sandbox Code Playgroud)
我注意到它返回的集合不包含java.*域中的任何内容.熟悉Reflections包的人可以告诉我如何获得这些吗?谢谢!
我正在使用Reflections包来获取一组实现某个接口的类.此集将用作可能的命令行选项列表.我的问题是我只想获得可实例化的类,但现在从以下代码中获取可实例化和不可实例化的类(例如抽象类):
Map<String, Class<? extends InterfaceOptimizer>> optimizerList = new HashMap<String, Class<? extends InterfaceOptimizer>>();
Reflections reflections = new Reflections("eva2.optimization.strategies");
Set<Class<? extends InterfaceOptimizer>> optimizers = reflections.getSubTypesOf(InterfaceOptimizer.class);
for(Class<? extends InterfaceOptimizer> optimizer : optimizers) {
optimizerList.put(optimizer.getName(), optimizer);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法过滤返回的集合getSubTypesOf来过滤掉抽象类?
简单的流程要求: 在包中找到的所有扩展名List.classjava.util。
这是我正在使用的来源:
Reflections reflections = new Reflections("java.util");
Set<Class<?>> subtypes = reflections.getSubTypesOf(List.class);
Run Code Online (Sandbox Code Playgroud)
很简单,对吧?
它既可以在IntelliJ IDEA中也可以在Eclipse中使用,但是当我通过Maven运行测试时不起作用。我尝试使用所org.reflections.util.ConfigurationBuilder提供的方法添加内容,以添加URL和过滤包名称,但没有运气。
有什么建议么?
我浏览了这篇文章,但无法正常工作:“ 仅当由Maven执行时,使用Reflections谷歌库的单元测试才会失败 ”
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>ohno</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)
Sample.java
package com.example.uhoh;
import org.reflections.Reflections;
import java.util.Set;
public class Sample {
@SuppressWarnings ("unchecked")
public static Set<Class<?>> lookup(Class<?> type) {
Reflections reflections = new Reflections("java.util"); …Run Code Online (Sandbox Code Playgroud) 我使用了 org.reflections (最新):
new Reflections("my.package").getSubTypesOf(MyService.class);
Run Code Online (Sandbox Code Playgroud)
它在 IntelliJ 中运行良好,并返回MyService.class.
但在 docker 容器中运行时,它返回一个空的Set.
(其他任何东西都可以在 docker-container 中正常运行)
有任何想法吗?蒂亚!
是否有配置反射库的解决方案,以便它也扫描在运行时使用 URLClassLoader 添加的 JAR?
现在,反射只是扫描 ClassLoader 中的 URL。这是我现在使用的配置:
Reflections reflections = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader()));
Run Code Online (Sandbox Code Playgroud)
我在反射库的文档中找不到任何提示。
编辑: 这就是我加载 jar 文件的方式:
File f = new File("C:/Users/mkorsch/Desktop/test-reflections.jar");
URLClassLoader urlCl = new URLClassLoader(new URL[] {f.toURI().toURL()},System.class.getClassLoader());
Run Code Online (Sandbox Code Playgroud) reflections ×10
java ×9
classloader ×3
maven ×2
maven-3 ×2
reflection ×2
class ×1
docker ×1
eclipse ×1
enums ×1
java-8 ×1
javassist ×1
runtime ×1
spring ×1
spring-boot ×1