【问题标题】:How to allow a gradle plugin to access classes in project dependencies如何允许 gradle 插件访问项目依赖项中的类
【发布时间】:2017-10-19 15:00:44
【问题描述】:

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

目前,我将project.compileJava.inputs.files 传递给我的任务并使用它来构造URLClassLoader。然后我将这些类传递给schema generator

为了确保正确生成 json 架构,我想使用目标应用程序中的 ObjectMapper。不幸的是,我的ObjectMapper 添加了jackson Hibernate5Module. 在该模块的深处,它试图检查我的类是否可以分配给HibernateProxy,,并且由于HibernateProxy 是使用Gradle 的类加载器加载的,并且我的类已加载有了URLClassLoader,一切都会爆炸。

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

供参考,下面是相关代码sn-ps:

目标项目的build.gradle

jsonSchema {
    classpath = project.compileJava.inputs.files
}

公共类 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();
}

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

【问题讨论】:

    标签: java gradle classpath jsonschema


    【解决方案1】:

    如果有人关心的话,我最终通过检查 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());
    

    【讨论】:

      猜你喜欢
      • 2020-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      相关资源
      最近更新 更多