jooby
jooby copied to clipboard
openapi maven plugin seems to fail for multi-module projects
If you have a multi module project and one of the deep children uses the openapi Mojo you will get the following exception if you do a clean and complete rebuild. It will eventually build correctly if you build all the other modules and then go to the specific project directory and build it OR you build without running openapi (perhaps using profiles) and then rebuild with it turned on (without cleaning).
The exception is below:
[ERROR] Failed to execute goal io.jooby:jooby-maven-plugin:2.9.4:openapi (default) on project some-project-child: execution of openapi resulted in exception: Cannot invoke "java.io.File.toString()" because "it" is null -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal io.jooby:jooby-maven-plugin:2.9.4:openapi (default) on project snaphop-v2-idm-login: execution of openapi resulted in exception
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:190)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:186)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:515)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:630)
at java.lang.Thread.run (Thread.java:832)
Caused by: org.apache.maven.plugin.MojoFailureException: execution of openapi resulted in exception
at io.jooby.maven.BaseMojo.execute (BaseMojo.java:83)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:190)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:186)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:515)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:630)
at java.lang.Thread.run (Thread.java:832)
Caused by: java.lang.NullPointerException: Cannot invoke "java.io.File.toString()" because "it" is null
at io.jooby.maven.BaseMojo.lambda$jars$6 (BaseMojo.java:189)
at java.util.stream.ReferencePipeline$2$1.accept (ReferencePipeline.java:176)
at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:195)
at java.util.Iterator.forEachRemaining (Iterator.java:133)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining (Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:484)
at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:474)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential (ReduceOps.java:913)
at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect (ReferencePipeline.java:578)
at io.jooby.maven.BaseMojo.jars (BaseMojo.java:191)
at io.jooby.maven.BaseMojo.classpath (BaseMojo.java:239)
at io.jooby.maven.BaseMojo.classpath (BaseMojo.java:223)
at io.jooby.maven.BaseMojo.createClassLoader (BaseMojo.java:216)
at io.jooby.maven.OpenAPIMojo.doExecute (OpenAPIMojo.java:47)
at io.jooby.maven.BaseMojo.execute (BaseMojo.java:78)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:190)
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call (MultiThreadedBuilder.java:186)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:515)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:630)
at java.lang.Thread.run (Thread.java:832)
The issue is the jar lookup for classloading:
protected Set<Path> jars(MavenProject project) throws DependencyResolutionException {
Set<org.apache.maven.artifact.Artifact> artifacts = project.getArtifacts();
if (artifacts.isEmpty()) {
// ADAM GENT: I think you need to run this all the time for openapi
DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
request.setMavenProject(project);
request.setRepositorySession(session.getRepositorySession());
DependencyResolutionResult result = dependenciesResolver.resolve(request);
return result.getDependencies().stream()
.filter(it -> !it.isOptional())
.map(Dependency::getArtifact)
.filter(it -> it.getExtension().equals("jar"))
.map(org.eclipse.aether.artifact.Artifact::getFile)
.map(File::toPath)
.collect(Collectors.toCollection(LinkedHashSet::new));
} else {
return artifacts.stream()
.map(org.apache.maven.artifact.Artifact::getFile)
.filter(it -> it.toString().endsWith(".jar"))
.map(File::toPath)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
}
Basically I think Set<org.apache.maven.artifact.Artifact> artifacts = project.getArtifacts();
is just not complete enough in a multimodule project. The files aren't there yet but that maybe because the reactor hasn't done them yet. The thing is the module probably doesn't need those as I think project.getArtifacts is pulling artifacts that aren't even direct dependencies (might be wrong about this).
Anyway I'll try on my end modifying the plugin with a filter of excluding files that aren't there.
are you going to send a PR with a fix?
Yes... sorry its a little chaotic here in the US right now (daycare cancellations etc) and I haven't had a chance to try out the change and do a PR. I will take care of it though and send a PR/fix since. I just filed it here for bookkeeping.