java - 自定义 java gradle 插件中的反射
问题描述
我有一个包含多个模块的 gradle 项目,每个模块都构建到它自己的 .jar 文件中。我想在自定义 java gradle 插件中使用反射,以生成关于带注释的类/方法的报告。
/build.gradle
apply plugin: com.my.plugins.MyPlugin
/buildSrc/build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'org.reflections:reflections:0.9.11'
compile 'javax.annotation:javax.annotation-api:1.3.2'
}
/buildSrc/src/main/java/com/my/plugins/MyPlugin.java
@NonNullApi
public class MyPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
MyTask myTask = project.getTasks().create("mytask", MyTask.class);
Task javaCompileTask = project.getTasks().getByName("compileJava");
myTask.dependsOn(javaCompileTask);
}
}
/buildSrc/src/main/java/com/my/plugins/MyTask.java
public class MyTask extends DefaultTask {
@TaskAction
public void perform() throws MalformedURLException, ClassNotFoundException {
List<URL> listOfURL = new ArrayList<>();
Set<File> runtimeFiles = getProject().getConfigurations().findByName("runtime").getFiles();
for (File file : runtimeFiles) {
// TODO: Exclude files from gradle cache folder
if (file.getPath().contains("build\\libs")) {
listOfURL.add(file.toURI().toURL());
}
}
URL[] urls = listOfURL.toArray(new URL[0]);
System.out.println("\nURLs:");
for (URL u : urls) {
System.out.println(" " + u.toString());
}
ClassLoader classLoader = new URLClassLoader(urls, null);
classLoader.loadClass("com.my.services.sample.MyClass");
System.out.println("\nClassLoader OK!\n");
Configuration config = new ConfigurationBuilder()
.setUrls(ClasspathHelper.forClassLoader(classLoader))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix("com.my.services")))
.addClassLoader(classLoader)
.setScanners(new SubTypesScanner(),
new TypeAnnotationsScanner(),
new MethodAnnotationsScanner());
Reflections reflections = new Reflections(config);
System.out.println("\nPermitAll Classes\n");
for (Class c : reflections.getTypesAnnotatedWith(PermitAll.class)) {
System.out.println(c.getName());
}
System.out.println("\nPermitAll Methods\n");
for (Method m : reflections.getMethodsAnnotatedWith(PermitAll.class)) {
System.out.println(m.getName());
}
}
}
当我运行gradlew mytask时,我会在 URL 列表中的 build\libs 下看到所有 .jar 文件的列表。
尽管 classLoader 可以成功加载(例如)MyClass,但新的 Reflections() 行会生成许多“无法获取名称的类型”错误,例如:
无法从任何类加载器获取名称 com.my.services.sample.MyClass 的类型
然后,PermitAll Classes 列表正确生成,但 PermitAll 方法列表失败并出现异常,例如:
任务 ':mytask' 执行失败。
> org/dom4j/DocumentException
我已经使用以下内容作为指南,但无法取得任何进一步的进展:
https://discuss.gradle.org/t/gradle-plugin-with-reflections/22690
解决方案
您应该使用以下内容来创建类加载器
URL[] urls = project.sourceSets.main.runtimeClasspath.files.collect {
it.toURI().toURL()
} as URL[]
ClassLoader classloader = new URLClassLoader(urls, null)
推荐阅读
- microservices - Eureka 客户端注册多个 Eureka 服务器问题
- shell - 我如何 grep 为“->”?
- python - 数据分析:集团价值流acc。相似度
- java - 如何通过触摸毕加索加载的图像进行手指绘画
- c# - 在 Xamarin.iOS 中使用 Azure 服务总线包时出现“无法解析引用”
- python - 如何在 Python 中使用正则表达式从字符串中提取最小和最大日期?
- react-native - scrollToIndex 在 RTL FlatList React-Native 中不起作用
- tomcat - 使用 NGINX 的 Tomcat HA 集群设置
- php - PHP excel面临一些烦人的问题
- node.js - 本地主机上的连接被拒绝