openapi-generator gradle plugin output directory - java

I am using the openapi-generator Gradle plugin to generate model files from the open API schema.
With these settings in build.gradle script everything seems ok:
openApiGenerate {
globalProperties = [
apis: "false",
modelDocs: "false",
models: "Pet"
]
generatorName = "java"
generateModelTests = false
inputSpec = "$rootDir/src/main/resources/schema/my_schema.json".toString()
outputDir = "$rootDir".toString()
modelPackage = "org.openapi.example.model"
configOptions = [
dateLibrary: "java8",
serializationLibrary: "jackson",
library: "jersey1"
]
}
And the result classes are generated in the proper package:
The problem is here - I don't need them in my sources, I need them only at compile stage.
I want them to be generated in the build directory, to separate them from other logic.
But when I am changing the output-dir to "$buildDir/generated".toString() this happens:
Is there a way to get rid of the wrong packages "src.main.java"?

You can set the "sourceFolder" option to an empty string.
configOptions = [
sourceFolder: ""
]
This is an option of the generator not of the gradle plugin.
https://openapi-generator.tech/docs/generators/java

Related

Gradle: compile and run a single test

I have a separate task to run the test that generates open-api.yml specification for my application. Here is the Gradle configuration below:
task generateOpenApiYml(type: Test) {
group = 'verification'
useJUnitPlatform {
includeTags 'openApi'
}
testLogging {
showExceptions true
showStandardStreams = false
showCauses true
showStackTraces true
exceptionFormat "full"
events("skipped", "failed", "passed")
}
}
So, I have one test with openApi JUnit tag. It works very well, but there is a slight thing I want to approve.
The whole idea of this test is that the result open-api.yml file is used to generate Java client to invoke REST endpoints. This client is used in other tests in the project.
I want to put those generated Java classes to .gitgnore because they are generated anyway and there is no need to index those files. The problem is that the generateOpenApiYml task compiles all the tests in src/test/java directory. Therefore, some of them use generated classes. Which leads to compiling errors.
Is it possible to tune the generateOpenApiYml task to make it compile and run only the single test with openApi JUnit tag? Then I could easily put generated Java classes to .gitignore and don't bother about their temporary absence, because other tests won't be compiled.
I figured out the solution. Firstly, I installed the gradle-testsets-plugin.
Then I configured a separate source set like this:
testSets {
generateOpenApiYml
}
So, generateOpenApiYml is the new Gradle task that looks for sources in src/generatedOpenApiYml/java directory.
Afterwards, we need to tune all tasks of test type to bind them with JUnit 5 platform.
tasks.withType(Test) {
group = 'verification'
useJUnitPlatform()
testLogging {
showExceptions true
showStandardStreams = false
showCauses true
showStackTraces true
exceptionFormat "full"
events("skipped", "failed", "passed")
}
}
generateOpenApiYml.outputs.upToDateWhen { false }
I put the upToDateWhen option for convenience to make sure the generateOpenApiYml task is always run on demand and never cached.
Then I have the open-api-generator.
openApiGenerate {
inputSpec = "$buildDir/classes/java/generateOpenApiYml/open-api.json".toString()
outputDir = "$buildDir/generated/openapi".toString()
apiPackage = "..."
invokerPackage = "..."
modelPackage = "..."
configOptions = [
dateLibrary : "java8",
openApiNullable: "false",
]
generatorName = 'java'
groupId = "..."
globalProperties = [
modelDocs: "false"
]
additionalProperties = [
hideGenerationTimestamp: true
]
}
tasks.named('openApiGenerate') {
dependsOn generateOpenApiYml
}
Finally, I just need to run two commands to build and run tests for my whole project.
./gradlew openApiGenerate
./gradlew build
The first one creates the open-api.yml file and generates Java client according to the provided specification. The second one runs tests and build the project normally. The tests running during the build phase uses classes generated by openApiGenerate task. Therefore, I can put them to .gitignore safely.
Hope this will be helpful.

how to read test data file from outside src folder in java test via bazel

I am not able to read test data from outside the src folder of project using java code. I am using bazel for testing java code.
The project hierarchy is as below:
Parent
Project1
Project2
Project3
Subproject1
Subproject2
data
Subfolder
Xyzzy.spi
Xyzzy.spl
BUILD.bazel
Src/main/java
Src/test/java
Com.test.sometest
Test1.java
Test2.java
BUILD.bazel
data/subfolder/BUILD.bazel:
exports_files(["Xyzzy.spi", "Xyzzy.spl"])
src/test/java/Com/test/sometest/BUILD.bazel:
load(
"//bazel:defs.bzl",
"java_library",
"java_test",
"java_binary",
)
java_test(
name = “subproject2”,
test_library = "subproject2_lib",
)
java_binary(
name = "example",
data = [
“//project3/subproject2/data/subfolder: Xyzzy.spi",
“//project3/subproject2/data/subfolder: Xyzzy.spl”,
],
runtime_deps = [":subproject2_lib"],
)
java_library(
name = "subproject2_lib",
testonly = True,
srcs = glob(
[
"*.java",
],
),
deps = [
"//:lombok",
“Path to point to build bazel of main java code”,
"#maven//:com_google_guava_guava",
"#maven//:commons_io_commons_io",
"#bazel_tools//tools/java/runfiles:runfiles",
"#maven//:junit_junit",
],
)
And java code to get path to file:
private static File CURRENT_INDEX_FILE=Paths.get("data/subfolder/Xyzzy.spi").toFile();
I am getting FileNotFoundException when running bazel test. Not sure where am doing it wrong. I tried google about this but no similar cases i found, mostly they have Maven Standard hierarchy but what should i change for this folder structure to work with.
Thanks

How can I run a JavaFX program using Bazel?

I currently have a very trivial JavaFX "Hello, World!" application that I am trying to build and run with Bazel. I am using the maven_install() rule to install the JavaFX dependencies in my WORKSPACE files like so:
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "3.2"
RULES_JVM_EXTERNAL_SHA = "82262ff4223c5fda6fb7ff8bd63db8131b51b413d26eb49e3131037e79e324af"
http_archive(
name = "rules_jvm_external",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("#rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"org.openjfx:javafx-controls:mac:11.0.1",
"org.openjfx:javafx-graphics:mac:11.0.1",
"org.openjfx:javafx-base:mac:11.0.1",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
And then I try to build a java_binary in the BUILD file like so:
java_binary(
name = "app",
srcs = glob(["src/**/*.java"]),
main_class = "com.dylanpowers.Main",
deps = [
"#maven//:org_openjfx_javafx_controls_mac",
"#maven//:org_openjfx_javafx_graphics_mac",
"#maven//:org_openjfx_javafx_base_mac"
]
)
In this case, Main.java is actually the only file in my application, as I am trying to just get the program to run. The build seems to work fine with bazel build :app, but when I try to run it with bazel run :app, I get the following error:
Error: JavaFX runtime components are missing, and are required to run this application
Can somebody please help me resolve this?
https://github.com/deepinthink-pumpkin/pumpkin-chat-jfx/blob/master/main/BUILD.bazel#L21
Create another main class as javafx application entrance.

Reference external file (openapi spec) from gradle plugin (openapitools generator)

I am attempting to build an application that references an openapi spec that is already published in artifactory. That means I'll be pulling the foo.yaml in as a dependency, but I can't seem to figure out how to actually reference that file by the openapitools generator plugin.
Given that openapi specs can be used to generate both server code and client code, it makes perfect sense that it is published separately and simply pulled in and referenced by implementations.
com.company.bar-1.0.10 contains foo.yaml at the top level of the jar.
I've added the dependency at the top level of the build.gradle.kts file and I've also added it as a part of the plugin task itself.
task generateFooCode(type: org.openapitools.generator.gradle.plugin.tasks.GenerateTask) {
generatorName = "java"
apiPackage = 'com.ehi.gbo.openapiconnect.api.foo'
modelPackage = 'com.ehi.gbo.openapiconnect.model.foo'
invokerPackage = 'com.ehi.gbo.openapiconnect.common.invoker'
inputSpec = "foo.yaml".toString()
outputDir = "$buildDir/generated-sources/foo".toString()
configOptions = [
dateLibrary : "java8",
useTags : true,
interfaceOnly : true,
delegatePattern : false,
useBeanValidation : false,
performBeanValidation: false,
useOptional : false,
serviceImplementation: false,
serviceInterface : false,
java8 : false,
serializableModel : true,
skipDefaultInterface : true,
reactive : false,
]
configurations {
dependencies {
implementation 'com.company.bar:foo-api:1.0.10'
}
}
}
Results I'm getting:
* What went wrong:
Execution failed for task ':generateFooCode'.
There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).
| Error count: 1, Warning count: 0
Errors:
-unable to read location foo.yaml
After a lot of googling, I came across a very elegant solution.
configurations {
api
}
dependencies {
api 'somegroup:someArtifact:someVersion'
}
task extractApi(type: Sync) {
dependsOn configurations.api
from { // use of closure defers evaluation until execution time
configurations.api.collect { zipTree(it) }
}
into "$buildDir/api/"
}
Then I could just make the inputSpec reference $buildDir/api/spec.yaml

How to use Room Database in Android with Bazel?

I have lots of SQLite tables that has now become hard to manage at the app side because of multiple DAO classes. I am using Bazel as my build system but I can't figure out how to use Room DB with Bazel build system.
If you use a Maven artifact resolver like rules_jvm_external, it'll look something like this.
In your WORKSPACE file, add the dependency on the Room compiler:
load("#rules_jvm_external//:specs.bzl", "maven")
maven_install(
name = "maven",
artifacts = [
"androidx.room:room-runtime:2.1.0-alpha04",
"androidx.room:room-compiler:2.1.0-alpha04",
"com.google.guava:guava:28.1-android",
maven.artifact("com.google.auto", "auto-common", "0.10", neverlink = True),
# .. other artifacts
],
repositories = [
"https://maven.google.com",
"https://jcenter.bintray.com",
],
)
In a BUILD file (e.g. <project root>/BUILD), create the java_plugin target to expose the annotation processor for Room:
java_plugin(
name = "androidx_room_room_compiler_plugin",
processor_class = "androidx.room.RoomProcessor",
deps = ["#maven//:androidx_room_room_compiler"],
neverlink = True,
)
java_library(
name = "androidx_room_room_compiler_library",
exports = [
"#maven//:androidx_room_room_compiler",
],
exported_plugins = [
":androidx_room_room_compiler_plugin"
],
)
Finally, in your app's BUILD file, depend on the Room compiler and runtime:
android_library(
name = "lib_prod",
# ...
deps = [
"#maven//:androidx_room_room_runtime",
"//:androidx_room_room_compiler_library",
],
)
I have ported an Android sample app that uses the Room and Lifecycle libraries to build with Bazel here: https://github.com/jin/BasicRxJavaSample-Bazel

Categories