如何允许 gradle 插件访问项目依赖项中的类

Kni*_*nta 1 java classpath jsonschema gradle

我正在编写一个 gradle 插件来json-schema在我的项目中生成一个for beans。我的目标是在构建过程中生成和发布模式,这样我就不需要手动更新它。

目前,我传递project.compileJava.inputs.files给我的任务并使用它来构建一个URLClassLoader. 然后我将这些类传递给模式生成器

为了确保正确生成 json 模式,我想使用ObjectMapper来自目标应用程序的 。不幸的是,我在该模块的深处ObjectMapper添加了 jackson Hibernate5Module.,它尝试检查我的类是否可以分配给 aHibernateProxy,并且因为HibernateProxy它加载了 Gradle 的类加载器,并且我的类加载了URLClassLoader所有内容都会爆炸。

我可以删除 Hibernate 模块,但这仍然会在其他类似情况下触发该错误,并且它使我的插件不易分发。所以我需要一种在运行时向 gradle 的类路径或默认类加载器添加新条目的方法。

作为参考,以下是相关代码片段:

目标项目的 build.gradle

jsonSchema {
    classpath = project.compileJava.inputs.files
}
Run Code Online (Sandbox Code Playgroud)

公共类 WriteJsonSchema 扩展了 DefaultTask

@TaskAction
public void write() throws ClassNotFoundException, IOException {
    ObjectMapper mapper = new ObjectMapper();

    mapper.registerModule(new Hibernate5Module());
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());

    mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
    mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);

    Set<File> files = getClasspath().getFiles();
    List<URL> urls = new ArrayList<URL>(files.size());
    for(File file : files)
    {
        urls.add(file.toURI().toURL());
    }
    URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader());

    JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(mapper);
    JsonNode jsonSchema =
        jsonSchemaGenerator.generateJsonSchema(classLoader.loadClass("com.example.Widget"));
    System.out.println(mapper.writeValueAsString(jsonSchema));
    classLoader.close();
}
Run Code Online (Sandbox Code Playgroud)

TL;DR:我需要一种在运行时向 gradle 的类路径或默认类加载器添加新条目的方法。

Kni*_*nta 5

如果有人关心,我最终通过检查compilejava任务的输出来获得项目类路径。

classpath = getProject().files();
    getProject()
        .getTasksByName("compileJava", true)
        .forEach(task -> classpath = Classpath.plus(((JavaCompile)task).getClasspath()));
classpath = Classpath.plus(getProject().getTasks().getByName("jar").getOutputs().getFiles());
Run Code Online (Sandbox Code Playgroud)