英文:
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<SourceSetContainer> {
named("main") {
java.srcDir("$buildDir/generated/src/main/java")
}
}
To add the java generated sources to the project's source.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论