gradleswaggerswagger-maven-plugin

classes not visible to gradle task swagger when using kongchen swagger-maven-plugin


When performing gradle clean and then gradle swagger a ClassNotFoundException is thrown. If gradle swagger is then run again (basically after the api build is done in previous run), it works fine.

build.gradle looks as below:

buildscript {
    repositories {
        maven { url hydraMavenRepo }
        maven { url hydraPluginsRepo }
    }
    dependencies {
        classpath "com.github.kongchen:swagger-maven-plugin:3.1.4"
    }
}

apply plugin: 'java'

configurations {
    addclasspath
}

dependencies {
    addclasspath files(project(':api:desktop-api').configurations['runtime'].files)
    addclasspath files(project(':api:desktop-api').sourceSets['main'].output)
    addclasspath files(project(':api:desktop-api').sourceSets.main.output.classesDir)

    runtime project(':api:desktop-api')
}

sourceSets {
    main {
        runtimeClasspath += files(project(':api:desktop-api').sourceSets['main'].output)
        runtimeClasspath += files(project(':api:desktop-api').sourceSets['main'].output.classesDir)
        runtimeClasspath += files(project(':api:desktop-api').configurations['runtime'].files)
    }
}


import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo
import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource
import io.swagger.models.Info

task swagger(dependsOn: [':api:desktop-api:build']) {
    doLast {
        logger.info 'Swagger GenDoc...'
        project.file(reportsDir).mkdirs()

        // a trick to have all needed classes in the classpath
        def customClassLoader = new GroovyClassLoader()

        buildscript.configurations.classpath.each {
            //println it.toURI().toURL()
            customClassLoader.addURL(it.toURI().toURL())
        }

        configurations.addclasspath.each {
            customClassLoader.addURL(it.toURI().toURL())
        }

        // the same settings as in the swagger-maven-example/pom.xml
        final ApiDocumentMojo mavenTask = Class.forName('com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo', true, customClassLoader).newInstance(
                apiSources: [
                        new ApiSource(
                                springmvc: false,
                                locations: ['com/vmware/vdi/hydra'],
                                schemes: ['http', 'https'],
                                host: 'vmware.com',
                                basePath: '/api',
                                info: new Info(
                                        title: "Hydra DS-REST API's",
                                        version: 'v100',
                                        description: "Hydra DS-REST API's",
                                ),
                                swaggerDirectory: reportsDir
                        )
                ]
        )
        mavenTask.execute()
        logger.info 'Swagger GenDoc task is completed'
    }
}

Solution

  • buildscript.classloader is what I was looking for.

    Below is the code that works:

    buildscript {
        repositories {
            maven { url mavenRepo }
        }
        dependencies {
            classpath "com.github.kongchen:swagger-maven-plugin:3.1.4"
        }
    }
    
    import com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo
    import com.github.kongchen.swagger.docgen.mavenplugin.ApiSource
    import io.swagger.models.Info
    
    
    task swagger(dependsOn: ':api:build') {
        doLast {
            logger.info 'Swagger GenDoc...'
            project.file(<dir>).mkdirs()
    
            FileCollection apiRuntimeFiles = files(project(':api').configurations['runtime'].files)
            apiRuntimeFiles.each {
                buildscript.classLoader.addURL(it.toURI().toURL())
            }
    
            FileCollection apiClassFiles =files(project(':api').sourceSets['main'].output)
            apiClassFiles.each {
                buildscript.classLoader.addURL(it.toURI().toURL())
            }
    
            final ApiDocumentMojo mavenTask = Class.forName('com.github.kongchen.swagger.docgen.mavenplugin.ApiDocumentMojo', true, buildscript.classLoader).newInstance(
                    apiSources: [
                            new ApiSource(
                                    springmvc: false,
                                    locations: ['<loc>'],
                                    schemes: ['http', 'https'],
                                    host: '<host>',
                                    basePath: '/api',
                                    info: new Info(
                                            title: "REST API's",
                                            version: 'v1',
                                            description: "REST API's",
                                    ),
                                    swaggerDirectory: <dir>
                            )
                    ]
            )
            mavenTask.execute()
            logger.info 'Swagger GenDoc task is completed'
        }
    }