jooby icon indicating copy to clipboard operation
jooby copied to clipboard

openapi maven plugin seems to fail for multi-module projects

Open agentgt opened this issue 3 years ago • 3 comments

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).

agentgt avatar Dec 16 '20 13:12 agentgt

Anyway I'll try on my end modifying the plugin with a filter of excluding files that aren't there.

agentgt avatar Dec 16 '20 13:12 agentgt

are you going to send a PR with a fix?

jknack avatar Dec 17 '20 00:12 jknack

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.

agentgt avatar Dec 17 '20 18:12 agentgt