如何在Gradle Java应用程序中引入来自openapi-generator的客户端?

huangapple go评论81阅读模式
英文:

How to include the client from openapi-generator in a gradle java application?

问题

我想创建一个使用 openAPI 规范文件生成客户端并使用该客户端的 Gradle Java 应用程序。因此,我使用 gradle init 创建了一个 Java 应用程序(类型:application,语言:Java,DSL:groovy,测试框架:Junit Jupiter,项目名称:simple-java-app,包结构:a.aa)。

工作的小例子:

我可以创建一个新的源代码文件夹 second/loc/src/main/java,其中包含一个包 b.bb 和一个类 Foo。并且使用以下 build.gradle 文件:

plugins {
    id 'java'
    id 'application'
}

repositories {
    jcenter()
}

sourceSets {
    second {
        java {
            srcDir 'second/loc/src/main/java'
        }
    }
}

compileJava {
    source += sourceSets.second.java
}

dependencies {
    implementation 'com.google.guava:guava:29.0-jre'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}

application {
    mainClassName = 'a.aa.App'
}

test {
    useJUnitPlatform()
}

主类可以访问 Foo

package a.aa;

import b.bb.Foo;

public class App {

    public static void main(String[] args) {
        System.out.println(new Foo().sayFoo());
    }
}

不起作用的部分:

现在,我尝试对 openapi-generator 生成的代码执行相同的操作:

plugins 中,我添加了 id "org.openapi.generator" version "4.3.1"

并且我添加了一个新任务:

openApiGenerate {
    generatorName = "java"
    inputSpec = "$rootDir/specs/petstore.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "org.openapi.example.api"
    invokerPackage = "org.openapi.example.invoker"
    modelPackage = "org.openapi.example.model"
    configOptions = [
        dateLibrary: "java8"
    ]
}

然后,我执行任务 openApiGenerate,并在文件系统中确认已生成源代码(Eclipse 不会显示 build 文件夹)。现在我使用与上面相同的方法,生成以下 build.gradle 文件:

plugins {
    id 'java'
    id 'application'
    id "org.openapi.generator" version "4.3.1"
}

repositories {
    jcenter()
}

openApiGenerate {
    generatorName = "java"
    inputSpec = "$rootDir/specs/petstore.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "org.openapi.example.api"
    invokerPackage = "org.openapi.example.invoker"
    modelPackage = "org.openapi.example.model"
    configOptions = [
        dateLibrary: "java8"
    ]
}

sourceSets {
    client {
        java {
            srcDir '$buildDir/generated/src/main/java'
        }
    }
}

compileJava {
    source += sourceSets.client.java
}

dependencies {
    implementation 'com.google.guava:guava:29.0-jre'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}

application {
    mainClassName = 'a.aa.App'
}

test {
    useJUnitPlatform()
}

但是当我尝试使用这些类时:

package a.aa;

import org.openapi.example.model.Pet;

public class App {

    public static void main(String[] args) {
        Pet p = new Pet(0L);
        System.out.println(p.getId());
    }
}

无法解析 import 语句和 Pet 类。

> Task :compileJava FAILED
C:\...\simple-java-app\src\main\java\a\aa\App.java:6: error: package org.openapi.example.model does not exist
import org.openapi.example.model.Pet;
                                ^
C:\...\simple-java-app\src\main\java\a\aa\App.java:14: error: cannot find symbol
        Pet p = new Pet(0);
        ^
  symbol:   class Pet
  location: class App
C:\...\simple-java-app\src\main\java\a\aa\App.java:14: error: cannot find symbol
        Pet p = new Pet(0);
                    ^
  symbol:   class Pet
  location: class App
3 errors

FAILURE: Build failed with an exception.

我不知道如何调试这个问题,坦率地说,我不确定 source sets 是否是正确的方法。所有的 openapi-generator 教程似乎都在使用它们,我还没有尝试过子项目,openApiGenerate 任务似乎会创建一个带有 build.gradle 等内容的完整项目。

英文:

I want to create a gradle java application that generates a client from an openAPI specification file and uses that client.
So I created a java application with gradle init (type:application, language:Java, DSL:groovy, test-framework:Junit Jupiter, project-name:simple-java-app, package-structure:a.aa).

Small example of what works:

I can create a new source folder second/loc/src/main/java with a package b.bb and a class Foo.
And with the following build.gradle

plugins {
    id 'java'
    id 'application'
}

repositories {
    jcenter()
}

sourceSets {
    second {
        java {
            srcDir 'second/loc/src/main/java'
        }
    }
}

compileJava {
    source += sourceSets.second.java
}

dependencies {
    implementation 'com.google.guava:guava:29.0-jre'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}

application {
    mainClassName = 'a.aa.App'
}

test {
    useJUnitPlatform()
}

The main class can access Foo:

package a.aa;

import b.bb.Foo;

public class App {

    public static void main(String[] args) {
        System.out.println(new Foo().sayFoo());
    }
}

What doesn't work

Now I try the same for generated code by openapi-generator:

Under plugins I add id "org.openapi.generator" version "4.3.1"

And I add a new task:

openApiGenerate {
    generatorName = "java"
    inputSpec = "$rootDir/specs/petstore.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "org.openapi.example.api"
    invokerPackage = "org.openapi.example.invoker"
    modelPackage = "org.openapi.example.model"
     configOptions = [
        dateLibrary: "java8"
    ]
}

Then I execute the task openApiGenerate and confirm in the file system that the sources have been generated(eclipse won't show the build folder).
Now I use the same method as above resulting in below build.gradle

plugins {
    id 'java'
    id 'application'
    id "org.openapi.generator" version "4.3.1"
}

repositories {
    jcenter()
}

openApiGenerate {
    generatorName = "java"
    inputSpec = "$rootDir/specs/petstore.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = "org.openapi.example.api"
    invokerPackage = "org.openapi.example.invoker"
    modelPackage = "org.openapi.example.model"
    configOptions = [
        dateLibrary: "java8"
    ]
}

sourceSets {
    client {
        java {
            srcDir '$buildDir/generated/src/main/java'
        }
    }
}

compileJava {
    source += sourceSets.client.java
}

dependencies {
    implementation 'com.google.guava:guava:29.0-jre'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2'
}

application {
    mainClassName = 'a.aa.App'
}

test {
    useJUnitPlatform()
}

But when I try to use the classes now:

package a.aa;

import org.openapi.example.model.Pet;

public class App {

    public static void main(String[] args) {
        Pet p = new Pet(0L);
        System.out.println(p.getId());
    }
}

neither import nor Pet can be resolved.

> Task :compileJava FAILED
C:\...\simple-java-app\src\main\java\a\aa\App.java:6: error: package org.openapi.example.model does not exist
import org.openapi.example.model.Pet;
                                ^
C:\...\simple-java-app\src\main\java\a\aa\App.java:14: error: cannot find symbol
		Pet p = new Pet(0);
		^
  symbol:   class Pet
  location: class App
C:\...\simple-java-app\src\main\java\a\aa\App.java:14: error: cannot find symbol
		Pet p = new Pet(0);
		            ^
  symbol:   class Pet
  location: class App
3 errors

FAILURE: Build failed with an exception.

I don't know how to debug this, frankly I'm unsure if source sets are even the right way. All openapi-generator tutorials seem to use them, I haven't tried subprojects yet, the openApiGenerate task seems to create a complete project with build.gradle and everything.

答案1

得分: 7

你需要将生成的代码来源添加到你的项目中。以下是我项目中的一个示例:

sourceSets.main.java.srcDir "${buildDir}/generated/src/main/java"

生成代码后,确保刷新 Gradle 和项目。

英文:

You need to add the sources from the generated code to your project. One example from one of my projects:

sourceSets.main.java.srcDir "${buildDir}/generated/src/main/java"

After generation make sure you refresh gradle and project.

答案2

得分: 2

使用build.gradle.kts和Gradle 7+,我在Kotlin DSL中使用了以下代码:

configure<SourceSetContainer> {
    named("main") {
        java.srcDir("$buildDir/generated/src/main/java")
    }
}

将生成的Java源代码添加到项目的源代码中。

英文:

With build.gradle.kts and gradle 7+ I used in Kotlin DSL:

configure&lt;SourceSetContainer&gt; {
    named(&quot;main&quot;) {
        java.srcDir(&quot;$buildDir/generated/src/main/java&quot;)
    }
}

To add the java generated sources to the project's source.

huangapple
  • 本文由 发表于 2020年7月23日 20:42:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63054564.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定