swagger-gradle-plugin icon indicating copy to clipboard operation
swagger-gradle-plugin copied to clipboard

ClassNotFoundException when jaxrs classes extends and/implement from other modules

Open melowe opened this issue 4 years ago • 21 comments

I'm unsure if this is an issue with the plugin itself or my fumbling around with Gradle.

Previously I used swagger-maven-plugin to generate the swagger descriptors and I basically ported like for like configuration to this plugin.

I have an Application class that extends a super class defined in another module. When plugin uses its ClassFinder to look the class up refections can't find the super class in any of its class loaders..

melowe avatar Nov 13 '19 18:11 melowe

Having looked some more I can verify that project.configurations.compileClasspath.each { println it} prints the jar containing the supertclass. So this does seem to be related to how the plugin builds the classloader..

melowe avatar Nov 13 '19 20:11 melowe

I worked around by hand-cranking the dependency urls into the Buildscript dependencies in a task in my build file.

def urls = []
  def classpaths = [project.configurations.compileClasspath.resolve()]
  classpaths.flatten().each {
      urls += it.toURI().toURL()
  }
  urls.each {
      buildscript.classLoader.addURL it
  }

melowe avatar Nov 13 '19 22:11 melowe

This has been a long-standing issue with this plugin, there have been several issues opened regarding it, I believe this was the first one:

https://github.com/gigaSproule/swagger-gradle-plugin/issues/132

mjparme avatar Jan 23 '20 20:01 mjparme

Same error, is there at least a workaround ?

mrsarm avatar Feb 13 '20 14:02 mrsarm

The workaround from @melowe worked for me!

More details of how to add it into your gradle.build script (a simplified version):

task fixGenerateSwaggerDocumentation {
  doLast {
    project.configurations.compileClasspath.resolve()
           .collect { it.toURI().toURL() }
           .each { buildscript.classLoader.addURL it }
  }
}
generateSwaggerDocumentation.dependsOn fixGenerateSwaggerDocumentation

mrsarm avatar Feb 13 '20 15:02 mrsarm

If you fancy raising a PR to fix this rather than a work around, please do. I really don't get the time to dig into this kind of stuff at the moment (and won't do for a while yet).

gigaSproule avatar Feb 13 '20 22:02 gigaSproule

FWIW the above fix didn't work for me =(

jonnii avatar Feb 13 '20 22:02 jonnii

@jonnii That fix didn't work for me either

fedefigueroa avatar Feb 14 '20 11:02 fedefigueroa

The workaround mentioned above worked for me with the following environment:

$ ./gradlew --version

------------------------------------------------------------
Gradle 6.1.1
------------------------------------------------------------

Build time:   2020-01-24 22:30:24 UTC
Revision:     a8c3750babb99d1894378073499d6716a1a1fa5d

Kotlin:       1.3.61
Groovy:       2.5.8
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_242 (Private Build 25.242-b08)
OS:           Linux 5.3.0-29-generic amd64

And the following gradle.build (just part of it):

plugins {
    id 'org.springframework.boot' version "${springBootVersion}"
    id 'io.freefair.lombok' version '4.1.6'
    id 'com.benjaminsproule.swagger' version '1.0.7'
}

dependencies {
  runtimeOnly "org.postgresql:postgresql:42.0.0"
  implementation "org.springframework.boot:spring-boot-starter-web:${springBootVersion}"
  implementation "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}"
  ...
}
...
swagger {
    apiSource {
        springmvc = false
        locations = [ 'com.MYPACKAGENAME...' ]
        schemes = [ 'https' ]
        basePath = apiPath
        info {
            title = 'Pricing API'
            version = apiVersion
            description = 'Some description'
            contact {
                email = '[email protected]'
                name = 'Eng Team'
            }
        }
        swaggerDirectory = "${project.rootDir}/generated/swagger-ui"
    }
}

// Workaround for an issue in the generateSwaggerDocumentation plugin
// check https://github.com/gigaSproule/swagger-gradle-plugin/issues/158#issuecomment-585823379
task fixGenerateSwaggerDocumentation {
  doLast {
    project.configurations.compileClasspath.resolve()
           .collect { it.toURI().toURL() }
           .each { buildscript.classLoader.addURL it }
  }
}
generateSwaggerDocumentation.dependsOn fixGenerateSwaggerDocumentation

mrsarm avatar Feb 14 '20 12:02 mrsarm

By adding the flag to skip including super types and also adding the above work around my problems have been solved. Thanks all!

jonnii avatar Feb 14 '20 22:02 jonnii

Looks like the latest version 1.0.8 published a few days ago solve the issue, I could remove the workaround and now there is no more errors in the task.

mrsarm avatar Feb 18 '20 11:02 mrsarm

False positive 😞 , looks like I had a kind of cache even when I launch a clean task before generateSwaggerDocumentation, the issue persist in v1.0.8, but the workaround continue to work at least for me with that version too.

mrsarm avatar Feb 18 '20 11:02 mrsarm

This workaround does not work for me. After applying the workaround the classes in my project itself can't be found. Whereas before it just couldn't find any classes in my dependencies. Very weird. Can't quite put my finger on what is going wrong.

mjparme avatar Feb 26 '20 16:02 mjparme

By adding the flag to skip including super types and also adding the above work around my problems have been solved. Thanks all!

@jonnii Which flag are you referring to? Link to doc that mentions this flag?

mjparme avatar Feb 26 '20 16:02 mjparme

@jonnii Oh, I see you are referring to the expandSuperTypes = false

Including that plus the workaround does indeed work for me as well.

mjparme avatar Feb 26 '20 16:02 mjparme

The workaround alone does not fix the issue for me, and I am unable to update to version 1.0.8 of the plugin to use expandSuperTypes because of issue https://github.com/gigaSproule/swagger-gradle-plugin/issues/166

Has anyone who did not see their issue resolved with the workaround found any alternatives that do not require expandSuperTypes = false?

TylerMoser avatar Mar 26 '20 15:03 TylerMoser

In my case, the plugin was scanning a class which inherited from a class coming from an external jar. This made it throw such numerous reflection exceptions about my class (since it probably couldn't find the parent class which it inherits from). Upgraded to 1.0.8 and set that expandSuperTypes = false, and it solved my issue. Since my class in question didn't add anything to the swagger anyways, it had no effect on the outputted swagger after the change. I will have to check the other case and see how it affects the result.

thenorthernpole avatar Apr 02 '20 23:04 thenorthernpole

The workaround didn't work for me, I am getting Caused by: groovy.lang.MissingMethodException: No signature of method: org.gradle.internal.classloader.CachingClassLoader.addURL() is applicable for argument types: (URL) values: [file:/tmp/groovy-generated-5192057695015375752-tmpdir/caches/modules-2/files-2.1/io.swagger/swagger-jersey2-jaxrs/1.6.2/95c7bdbb60dd6c83c9db7da9e74b833d0b736f95/swagger-jersey2-jaxrs-1.6.2.jar] Possible solutions: dump() any ideas?

wakingrufus avatar Nov 11 '20 14:11 wakingrufus

@wakingrufus I see you are (hopefully) preparing a PR for this. Any luck?

gigaSproule avatar Nov 22 '20 22:11 gigaSproule

Looks like my PR was merged: https://github.com/gigaSproule/swagger-gradle-plugin/commit/99091a1d7474636e5aca93571342e3947f4569f4 :tada:

wakingrufus avatar Dec 08 '20 20:12 wakingrufus

Yeah, still trying to find the time to deal with CircleCI and it's OOM issues. The classic fun job of I can never replicate nor have the time to really look into it. I'm hoping to have some time this weekend to try it out.

gigaSproule avatar Dec 09 '20 08:12 gigaSproule