typescript-generator: Classloader issues cause maven plugin (v1.14.251) to fail when using classesFromAutomaticJaxrsApplication

Using 1.14.251 of this plugin, we’ve been running into sporadic maven build issues that appear to be related to the classloading mechanism that’s used when the classesFromAutomaticJaxrsApplication flag is set to true. When running our multi-module maven build in parallel, the plugin will occasionally attempt to load a @Path annotated class that is from another module that isn’t a direct dependency of the project running the plugin. When it attempts to load the class, a java.lang.ClassNotFoundException is thrown and the build fails.

We had attempted to add the package of the class to the excludeClassPatterns, but that didn’t help due to the fact that the Input/JaxrsApplicationScanner classes perform their classloading before any filtering occurs. This is problematic because the FastClasspathScanner is occasionally finding classes that aren’t available to the thread context class loader. I was thinking there might be a couple of ways to address this:

  1. Perform class exclusion filtering on the FastClasspathScanner using the constructor scan spec.
  2. Perform exclusion filtering on class names found by the FastClasspathScanner before attempting to load them
  3. Allow individual classloading failures to be suppressed without causing the entire plugin execution to fail

We can update to the latest version of the plugin, but from what I can tell, the classpath scanning/classloading mechanism hasn’t changed in a way that would prevent us from encountering this issue. This is the relevant stack trace from our CI server when this issue causes the build to fail:

12:20:30 org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal cz.habarta.typescript-generator:typescript-generator-maven-plugin:1.14.251:generate (generate) on project PROJECT: Execution generate of goal cz.habarta.typescript-generator:typescript-generator-maven-plugin:1.14.251:generate failed: Cannot load JAX-RS application. For more information see https://github.com/vojtechhabarta/typescript-generator/wiki/JAX-RS-Application.
12:20:30 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
12:20:30 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
12:20:30 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
12:20:30 	at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
12:20:30 	at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call(MultiThreadedBuilder.java:185)
12:20:30 	at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call(MultiThreadedBuilder.java:181)
12:20:30 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
12:20:30 	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
12:20:30 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
12:20:30 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
12:20:30 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
12:20:30 	at java.lang.Thread.run(Thread.java:745)
12:20:30 Caused by: org.apache.maven.plugin.PluginExecutionException: Execution generate of goal cz.habarta.typescript-generator:typescript-generator-maven-plugin:1.14.251:generate failed: Cannot load JAX-RS application. For more information see https://github.com/vojtechhabarta/typescript-generator/wiki/JAX-RS-Application.
12:20:30 	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145)
12:20:30 	at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
12:20:30 	... 11 more
12:20:30 Caused by: java.lang.RuntimeException: Cannot load JAX-RS application. For more information see https://github.com/vojtechhabarta/typescript-generator/wiki/JAX-RS-Application.
12:20:30 	at cz.habarta.typescript.generator.JaxrsApplicationScanner.scanJaxrsApplication(JaxrsApplicationScanner.java:32)
12:20:30 	at cz.habarta.typescript.generator.Input.fromJaxrsApplication(Input.java:63)
12:20:30 	at cz.habarta.typescript.generator.Input.fromClassNamesAndJaxrsApplication(Input.java:82)
12:20:30 	at cz.habarta.typescript.generator.maven.GenerateMojo.execute(GenerateMojo.java:331)
12:20:30 	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
12:20:30 	... 12 more
12:20:30 Caused by: java.lang.ClassNotFoundException: com.package.RestAPI
12:20:30 	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
12:20:30 	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
12:20:30 	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
12:20:30 	at cz.habarta.typescript.generator.JaxrsApplicationScanner.scanClasspathForJaxrsResources(JaxrsApplicationScanner.java:50)
12:20:30 	at cz.habarta.typescript.generator.JaxrsApplicationScanner.scanJaxrsApplication(JaxrsApplicationScanner.java:24)
12:20:30 	... 16 more

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (16 by maintainers)

Commits related to this issue

Most upvoted comments

@vojtechhabarta the update to v1.26.333 of the plugin was merged into our master last night and so far the issue hasn’t been seen again. I also searched through the logs and so far haven’t seen the statement for Cannot load class.

I just released v2.2.0 of FastClasspathScanner. It may solve the issue you are seeing with mvn clean install -T 12 – please let me know. If not, please test the other versions of FCS detailed in my comment on the bug report created by @vojtechhabarta, linked above. Thanks!

Since we sometimes get classes from fast-classpath-scanner that are not part of current module I think right solution would be to correctly configure fast-classpath-scanner so that we only get relevant classes. I asked an question how to do it in fast-classpath-scanner project.

If it will not work I would implement some mitigation of the problem like you proposed. My intent is to not force users to configure exclusion for classes that should not even be there so I would probably implement your 3rd point.