J'écris un plugin Gradle pour générer un json-schema
pour les beans dans mon projet. Mon objectif est d'avoir le schéma généré et publié dans le cadre du processus de construction, donc je n'ai pas besoin de le mettre à jour manuellement.Comment autoriser un greffon Gradle à accéder aux classes dans les dépendances de projet
Actuellement, je passe project.compileJava.inputs.files
à ma tâche et l'utilise pour construire un URLClassLoader
. Ensuite, je passe ces classes à un schema generator.
Afin de garantir que le schéma json est généré correctement, je souhaite utiliser le ObjectMapper
à partir de l'application cible. Malheureusement, mon ObjectMapper
ajoute le jackson Hibernate5Module.
Dans les profondeurs de ce module, il essaie de vérifier si ma classe est assignable à un HibernateProxy,
et puisque le HibernateProxy
est chargé avec le chargeur de classe de Gradle et que ma classe est chargée du URLClassLoader
tout explose.
Je pourrais supprimer le module Hibernate, mais cela laisse toujours le bug être déclenché dans d'autres situations similaires, et cela rend mon plugin moins distribuable. J'ai donc besoin d'un moyen d'ajouter de nouvelles entrées au classpath de gradle ou au chargeur de classe par défaut lors de l'exécution.
Pour référence, voici les extraits de code relevent:
build.gradle du projet cible
jsonSchema {
classpath = project.compileJava.inputs.files
}
WriteJsonSchema public class étend 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: J'ai besoin d'un moyen t o soit ajouter de nouvelles entrées au classpath de gradle, soit au loader de classe par défaut à l'exécution.