2017-07-04 1 views
0

Bei der Durchführung von Gradle Clean und dann Gradle Swagger wird eine ClassNotFoundException geworfen. Wenn groll Swagger dann wieder ausgeführt wird (grundsätzlich nachdem der API-Build im vorherigen Lauf erstellt wurde), funktioniert es gut.Klassen, die nicht sichtbar sind, um Aufgabe aufzupassen, wenn Swagger bei der Verwendung von kongchen verwendet wird swagger-maven-plugin

build.gradle sieht wie folgt:

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

Sie diese Frage bearbeiten sollte und eine Stack-Trace und andere unterstützende Informationen zur Verfügung stellen, wie, wie Sie Gradle laufen, Werkzeug Versionen usw. – jdv

Antwort

0

buildscript.classloader ist, was ich gesucht habe.

Unten ist der Code, das funktioniert:

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

Sie haben mehrere Mängel in Ihrem Build-Skript.

Sie sollten nicht auf Build-Dinge in Build-Skript-Abhängigkeiten angewiesen sein. Dies ist ein Problem mit Henne und Ei. Sie müssen den Build ausführen, um die Klassen abzurufen, die zum Ausführen des Builds erforderlich sind. Dies kann nicht funktionieren, wenn überhaupt.

Stattdessen sollten Sie sie als Abhängigkeiten außerhalb des buildscript Blocks deklarieren. Der buildscript Block ist nur für Abhängigkeiten, die von Ihrem Buildskript benötigt werden, um sich selbst auszuführen, wie Gradle Tasks und Gradle Plugins oder Klassen, die Sie während des Builds verwenden, wie swagger-maven-plugin Sachen, die im buildscript Block korrekt sind.

Darüber hinaus führen Sie einen Teil Ihrer Swagger-Sachen (Instanciation, Ausführung und Drucken) während der Konfigurationsphase statt während der Ausführungsphase aus. Alles, was Sie in einem Task-Closure tun, aber außerhalb von doFirst oder doLast Blöcken wird während der Konfigurationsphase ausgeführt, wenn der Build konfiguriert ist und somit immer, egal welche Aufgaben Sie tatsächlich ausführen wollen und egal ob der Task bereits aktiv ist bis jetzt oder nicht. Damit die aktuelle Prüfung funktioniert und Zeit gespart wird, müssen Sie alle Eingaben wie Dateien und Eigenschaften deklarieren, die sich zwischen den Ausführungen und allen von Ihnen generierten Ausgaben ändern können. Dann kann Gradle nur die Aufgabe ausführen, wenn es wirklich notwendig ist .

Auch sollten Sie nicht println in Build-Skripten verwenden. Das ist wie in Java-Programmen System.out.println zu verwenden. Stattdessen sollten Sie die bereitgestellte Protokollierungsfunktion direkt verwenden, z. G. tun logger.info 'Swagger GenDoc task is completed'.

+0

Dank, Dank für Ihre Eingaben . – Ukeshava

+0

Habe jetzt Abhängigkeiten außerhalb von Buildscript hinzugefügt. Wenn ich jedoch sehe, dass die URLs gescannt werden, fehlt bei Java-Reflektionen immer noch der Pfad für API-Klassen beim ersten Start. Bearbeitet den Code (der auch eine schließende Klammer verpasste, die Verwirrung verursacht). In Bezug auf Ihren Vorschlag auf dem neuesten Stand zu arbeiten, ja, wird das auch hinzufügen, zuerst brauche ich dieses eine zu arbeiten. Irgendwelche Vorschläge/Hinweise? – Ukeshava

+0

Dies liegt daran, dass Sie die eigentlichen Dateien mit 'files' auflösen. Sie sollten dies nicht explizit tun. Es ist schwer zu beschreiben, wie man es richtig macht, ohne das Projekt zur Hand zu haben. – Vampire

Verwandte Themen