Размышления в пользовательском плагине Java Gradle - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть проект gradle с несколькими модулями, каждый из которых собран в свой собственный файл .jar.Я хочу использовать отражения в пользовательском подключаемом модуле Java для создания отчета по аннотированным классам / методам.

/ 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 , я вижу списокиз всех моих файлов .jar в build \ libs в списке URL.

Хотя classLoader может успешно загрузить (например) MyClass, новая строка Reflections () генерирует многочисленные ошибки «не удалось получить тип для имени», например:

не удалосьполучить тип для имени com.my.services.sample.MyClass из любого загрузчика классов

Затем список классов PermitAll генерируется правильно, но список методов PermitAll завершается ошибкой, например:

Не удалось выполнить задачу «mytask».

> org / dom4j / DocumentException

Я уже использовал следующее в качестве руководства, но не могучтобы добиться дальнейшего прогресса:

https://discuss.gradle.org/t/gradle-plugin-with-reflections/22690

Размышления не могут получить тип класса

1 Ответ

0 голосов
/ 25 апреля 2018

Для создания загрузчика классов следует использовать следующее

URL[] urls = project.sourceSets.main.runtimeClasspath.files.collect {
    it.toURI().toURL()
} as URL[]
ClassLoader classloader = new URLClassLoader(urls, null) 
...