gigaSproule / swagger-gradle-plugin

JAX-RS & SpringMVC supported gradle build plugin to generate Swagger documentation
Apache License 2.0
97 stars 52 forks source link

ClassNotFoundException when jaxrs classes extends and/implement from other modules #158

Open melowe opened 4 years ago

melowe commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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
    }
mjparme commented 4 years ago

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

mrsarm commented 4 years ago

Same error, is there at least a workaround ?

mrsarm commented 4 years ago

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
gigaSproule commented 4 years ago

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

jonnii commented 4 years ago

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

fedefigueroa commented 4 years ago

@jonnii That fix didn't work for me either

mrsarm commented 4 years ago

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 = 'eng@mail.com'
                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
jonnii commented 4 years ago

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

mrsarm commented 4 years ago

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 commented 4 years ago

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.

mjparme commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

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

TylerMoser commented 4 years ago

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?

thenorthernpole commented 4 years ago

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.

wakingrufus commented 3 years ago

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?

gigaSproule commented 3 years ago

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

wakingrufus commented 3 years ago

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

gigaSproule commented 3 years ago

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.