【问题标题】:classes not visible to gradle task swagger when using kongchen swagger-maven-plugin使用kongchen swagger-maven-plugin时对gradle task swagger不可见的类
【发布时间】:2017-07-04 12:28:42
【问题描述】:

当执行 gradle clean 然后 gradle swagger 抛出 ClassNotFoundException。如果再次运行 gradle swagger(基本上是在上次运行中完成 api 构建之后),它可以正常工作。

build.gradle 如下所示:

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'
    }
}

【问题讨论】:

  • 您应该编辑此问题并提供堆栈跟踪和其他支持信息,例如您运行 Gradle 的方式、工具版本等。

标签: gradle swagger swagger-maven-plugin


【解决方案1】:

您的构建脚本中有几个缺陷。

您不应该依赖构建脚本依赖项中的构建内容。这是一个鸡和蛋的问题。您需要执行构建以获取执行构建所需的类。如果有的话,这不能可靠地工作。

相反,您应该将它们声明为 buildscript 块之外的依赖项。 buildscript 块仅适用于构建脚本运行自身所需的依赖项,例如 Gradle 任务和 Gradle 插件或您在构建期间使用的类,例如在 buildscript 块中正确的 swagger-maven-plugin 内容。

除此之外,您在配置阶段而不是在执行阶段执行部分招摇的东西(实例化、执行和打印)。您在任务关闭中所做的一切,但在任何 doFirstdoLast 块之外执行的所有操作都在配置阶段运行,在配置构建时因此始终如此,无论您实际要执行什么任务,也不管任务是否可能已经是最新的,也可能不是。为了使最新检查正常工作并节省您的时间,您需要声明所有输入,例如可能在执行和您生成的所有输出之间发生变化的文件和属性,然后 Gradle 可以发挥它的魔力,仅在实际需要时执行任务.

您也不应该在构建脚本中使用println。这就像在 Java 程序中使用 System.out.println。相反,您应该直接使用提供的日志记录工具,例如。 G。正在做logger.info 'Swagger GenDoc task is completed'

【讨论】:

  • 谢谢,感谢您的意见。
  • 现在已经在 buildscript 之外添加了依赖项。但是,当我看到扫描的 URL 时,java 反射仍然缺少第一次运行时 api 类的路径。编辑了代码(它也错过了导致混乱的结束括号)。关于你对最新工作的建议,是的,我也会补充一下,首先我需要这个工作。有什么建议/指针吗?
  • 这是因为您使用files 解析实际文件。你不应该明确地这样做。如果没有手头的项目,很难描述如何正确地做到这一点。
  • 确实尝试使用路径(目录)而不使用文件,这也没有帮助
  • 这同样太早地解决了文件。您需要使用正确的依赖声明和引用。但正如我所说,如果没有手头的项目,除了阅读用户指南并学习如何正确操作之外,我不能说更多,抱歉。
【解决方案2】:

buildscript.classloader 是我要找的。​​p>

下面是有效的代码:

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'
    }
}

【讨论】:

    猜你喜欢
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 1970-01-01
    相关资源
    最近更新 更多