2017-10-19 159 views
0

我正在編寫一個gradle插件來爲我的項目中的bean生成json-schema。我的目標是將架構生成併發布爲構建過程的一部分,因此我不需要手動更新它。如何允許gradle插件訪問項目依賴關係中的類

目前,我通過project.compileJava.inputs.files到我的任務,並用它來構造一個URLClassLoader。然後我將這些類傳遞給schema generator

爲了確保json模式生成正確,我想使用來自目標應用程序的ObjectMapper。不幸的是,我ObjectMapper增加了傑克遜Hibernate5Module.在該模塊的深處,它試圖檢查我的課被分配給一個HibernateProxy,而且由於HibernateProxy裝載有搖籃的類加載器和我的課裝有URLClassLoader一切爆炸。

我可以刪除Hibernate模塊,但仍然會導致在其他類似情況下觸發該錯誤,並且使得我的插件的可分配性降低。所以我需要一種方法在運行時將新條目添加到Gradle的類路徑或默認的類加載器。

僅供參考,這裏有培訓相關的代碼片段:

目標項目的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:我需要一種方法o在運行時添加新的條目到gradle的類路徑或默認的類加載器。

回答

0

如果有人在乎,我最終通過檢查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());