I have following open-api spec
...
departureTime:
description: Start time of your trip request. Defaults to current time if omitted.
format: date-time
type: string
...
The maven swagger codegen plugin generates the model class with the org.threeten.bp.OffsetDateTime library but I have the requirement to use java.time.OffsetDateTime.
I've tried following configuration
<configuration>
...
<typeMappings>
<typeMapping>org.threeten.bp.OffsetDateTime=java.time.OffsetDateTime</typeMapping>
</typeMappings>
<importMappings>
<importMapping>org.threeten.bp.OffsetDateTime=java.time.OffsetDateTime</importMapping>
</importMappings>
...
</configuration>
This at least added the requiered library java.time.OffsetDateTime to my generated model classed, but now both imports are present which leads to a import conflict
...
import org.threeten.bp.OffsetDateTime;
import java.time.OffsetDateTime;
...
I've also tried adding this to my configuration, since I've read it's needed in some cases. But after adding it, maven has generated nothing anymore.
...
<configOptions>
<java8>true</java8>
<dateLibrary>custom</dateLibrary>
</configOptions>
...
How can I properly change the used libraries for generated sources?
Related
I tried to generate interfaces from a swagger file we need to implement. It's provided from an external source. I usually use contract first, but didn't do that in a long time with java/kotlin.
I already have a project set up and want to have as much control of my code as possible. I tried to use openapi-generator-gradle-plugin with kotlin-spring or spring generator, to generate the interfaces (the import part).
Best would be Interfaces with spring related annotations (RequestMappings etc.) and at least just the interfaces. But it seems, the generator also generates a "little application" (with gradle/maven file, SpringBootApp, README.md ...).
I don't have the code anymore, but was pretty sure, the last time I did this, it was easy possible to just generate interfaces, but can't remember which generator or plugin I used.
So my question is, did I miss something or is just creating interfaces not an issue anymore? Does everyone wants to do scaffolding here?
I use the openapi-generator-maven-plugin with <interfaceOnly>true</interfaceOnly> configOption. It should be similar in gradle with kotlin-spring generator
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.0.0-beta</version>
<executions>
<execution>
<id>1</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>openapi.json</inputSpec>
<generatorName>spring</generatorName>
<modelPackage>modelPackage</modelPackage>
<apiPackage>apiPackage</apiPackage>
<invokerPackage>invokerPackage</invokerPackage>
<configOptions>
<sourceFolder>target</sourceFolder>
<interfaceOnly>true</interfaceOnly>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
I added the following properties to my openApiGenerate task:
globalProperties =[
apis: '',
models: '',
]
which solved the issue for me.
If you are using gradle with a build.gradle.kts you can use this openapi-generator plugin task to generate the swagger code.
It does the same thing as the swagger codegen plugin:
plugins {
id("org.openapi.generator") version "5.1.1"
}
openApiGenerate {
generatorName.set("spring")
inputSpec.set("$rootDir/src/main/resources/petstore.yaml")
outputDir.set("$buildDir/generated/")
configFile.set("$rootDir/src/main/resources/api-config.json")
globalProperties.set(mapOf(
Pair("apis", ""), //no value or comma-separated api names
Pair("models", ""), //no value or comma-separated api names
))
}
The apis generated from the paths in your swagger. The api-config.json has the settings of your generator.
and then you need to add the generated classes to your sourceSet by doing:
configure<SourceSetContainer> {
named("main") {
java.srcDir("$buildDir/generated/src/main/java")
}
}
Finally make sure you generate the swagger files before compiling:
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
dependsOn("openApiGenerate")
kotlinOptions.jvmTarget = "11"
}
I'm trying to import a proto file from a java file in IntelliJ IDEA.
I have a file called A.proto and a file called B.java. I try to import a class Info from the A.proto file in the B.java file like this:
import A.Info;
However, IntelliJ IDEA doesn't look to support proto files and says my class doesn't exist. I installed both plugins Protobuf Support and Protocol Buffer Editor. But it still doesn't work. Any idea?
Problem
IntelliJ recognizes protocol buffer files, but they are not Java, so the Java Compiler doesn't know what to do with them.
Solution with Maven
You can compile those protocol buffers to Java files, which is the step you are currently missing. The best way I know is to use a Maven plugin to do this.
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>3.11.4</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<protocVersion>3.0.0</protocVersion> <!-- 2.4.1, 2.5.0, 2.6.1, 3.0.0 -->
<includeDirectories>
<include>src/main/resources/protobuf</include>
</includeDirectories>
<inputDirectories>
<include>src/main/resources/protobuf/</include>
</inputDirectories>
</configuration>
</execution>
</executions>
</plugin>
And dependency for the Protocol Buffer classes:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.4</version>
</dependency>
With this plugin, Intellij will find the created Java classes, after having initially created the sources. This way, only your Protocol Buffer files need to be in Source Control. You let the plugin take care of the compilation to Java.
After creation of the Java classes, you can use them in the rest of your code. You can even view the generated Java classes in the target/generated-sources folder in your Maven Project.
Here's what the mapping between Protocol Buffers and Java looks like:
DistanceWalked.proto
package example;
message DistanceWalked {
string userId = 1;
double distance = 2;
}
DistanceWalkedOuterClass.DistanceWalked.java (generated)
package example;
public class DistanceWalked {
//properties This class isn't pretty...
}
(Full code example with protocol buffers and Maven plugin can be found here: https://github.com/TomCools/protocol-buffers-example)
Link to plugin source: https://github.com/os72/protoc-jar-maven-plugin
Solution without Maven
Without Maven, you have to download the command-line compiler. Documentation on that can be found here: https://developers.google.com/protocol-buffers/docs/javatutorial#compiling-your-protocol-buffers
The proto file is just the description of the message format. It does not contain code that can be interpreted directly in a java context.
The idea of the proto file is to provide a generic, language agnostic specification of the message format.
Based on the proto file, you can generate the corresponding java code. This code can then be used and imported in your java project.
Have a look here on how to generate code from a proto file: https://developers.google.com/protocol-buffers/docs/javatutorial#compiling-your-protocol-buffers
Incase anyone is still stuck -
I found that specifying the path to Intellij fixes the problem:
Preferences -> Languages and Frameworks -> Protocol Buffer -> Uncheck "Configure automatically"
And then add the path to the file.
It should be good for xolstice or os72!
I've tried to add more information on my Swagger documentation, but I'm having some issues with the #ApiPropertyModel annotation in specific.
It doesn't matter what I try to do, it just doesn't work. The plugin is generating the Swagger.json correctly, all the #ApiOperation annotations are working for the REST resources, but for the model part, it only introspects the model classes' properties and doesn't look at the annotations above them.
Here is how the plugin is configured:
<plugin>
<groupId>com.github.kongchen</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>3.1.5</version>
<configuration>
<apiSources>
<apiSource>
<locations>
<location>com.example.rest.resources</location>
<location>com.example.rest.model</location>
</locations>
<swaggerDirectory>${project.build.directory}/generated-sources</swaggerDirectory>
<basePath>/path/to/the/api</basePath>
<info>
<title>My RESTful API Documentation</title>
<version>${project.version}</version>
</info>
</apiSource>
</apiSources>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
If I have for example:
#ApiModelProperty(example = "test example")
public String test;
It will generate the test property but it won't create any example or any other property that I set up in that annotation. The same is happening when using it in a getter, so I think that's not the problem.
Am I doing anything wrong? Also, I looked at Kongchen's example project and I couldn't see anything special to make it work.
I was trying to mess with the code again, and I've found that the problem is on the structure of the project. It has different modules, and it has a profile for the general development and a profile just for the RESTful API documentation.
I was distracted for a while and started to build the projects using mvn clean package, and as it had a version of the project installed, it was using it to create the documentation, and that's why it was never changing, after I used mvn clean install in the main source code I could see the annotation make any effect.
I'm sorry guys, it was beyond any information I could give about the documentation project, since it was something about the whole structure I'm using. But at least I'll keep this answer so the next person may be aware about this.
Thank you for your attention!
Maybe you forgot the #ApiModel annotation on your Model classes?
Like:
#ApiModel
public class PostRequest {
#ApiModelProperty(example = "test example")
public String test;
}
or your model package does not match what's given in the pom.xml.
I'm building (multiple) complex webservice with base XSD types from all kinds of standards (GML, SWE, XLINK, etc). Now, I would like to break up the compilation into more steps, preferrably one for each of the standards I'm using.
Advantages:
1) I can add create tooling libraries that I can re-use in all of my webservices on each of the standards.
2) I can make use of the power of JAXB2 basics plugin, which seems to work very nicely with the maven-jaxb2-plugin (org.jvnet.jaxb2.maven2) and create for instance interface bindings. This in contrast with the jaxws-maven-plugin plugin.
The final step would be using the org.jvnet.jax-ws-commons:maven-jaxb2-plugin to create the actual web service that I can implement in an EJB (or call as a client).
Now, the org.jvnet.jaxb2.maven2:maven-jaxb2-plugin plugin allows me to refer to episodes by means of their maven coordinate, as part of its like this:
<episodes>
<episode>
<groupId>org.example</groupId>
<artifactId>jaxb2-basics-test-episodes-a</artifactId>
</episode>
</episodes>
How can I do this by means of the org.jvnet.jax-ws-commons:maven-jaxb2-plugin? I've searched a lot, and experimented like this:
<plugin>
<groupId>org.jvnet.jax-ws-commons</groupId>
<artifactId>>maven-jaxb2-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<wsdlDirectory>src/main/resources/</wsdlDirectory>
<wsdlFiles>
<wsdlFile>example.wsdl</wsdlFile>
</wsdlFiles>
<xjcArgs>
<xjcArg>-b</xjcArg>
<xjcArg>../cpt-xsd/target/generated-sources/xjc/META-INF/sun-jaxb.episode</xjcArg>
</xjcArgs>
<verbose>true</verbose>
</configuration>
</plugin>
Which takes the episode file from the target dir of the (compiled) JAXB dependend project. This sometimes even fails in the maven build (why I did not figure out yet).
I've tried to use catalog files to make a mapping but (I think I saw somewhere a catalog mapping that took maven coordinates as destination), but haven't succeeded yet.
Are you aware of the OGC Schemas and Tools Project? (Disclaimer: I'm the author.)
Now, to your question. My guess would be that org.jvnet.jax-ws-commons:maven-jaxb2-plugin does not support the "Maven coordinates" as you call them. This was a feature I've specifically implemented for my org.jvnet.jaxb2.maven2:maven-jaxb2-plugin (disclaimer: I'm the author).
From the other hand, episode file is nothing but a JAXB binding file. So you can simply extract this file from the JAR artifact (for instance using the maven-dependency-plugin) and then include it more or less like you do it already. Just don't point to directories in other modules, this is not reliable.
I'm looking to convert a WSDL version 1.1 into a WSDL 2.0 format as part of our maven build process.
I've come across the Woden Converter utility which uses XSL to do this conversion, and would like to use it. However, there seems to be no documentation or examples (that I can find) on how to configure or use the related maven plugin: woden-converter-maven-plugin
Does anyone have experience with this, and could they please share the maven plugin config details?
Justification (for those that require it):
We have a contract-first Web Service and have a recent requirement to expose our WSDL in 2.0 format to one particular client. To save on maintaining two identical WSDLs, we'd like to maintain the 1.1 wsdl and have the build process auto-generate the 2.0 version.
Here are the sources for the plugin. There's not much you can set. Check the fields. You can set those up in the <configuration/> section of your plugin.
Consider this:
<plugin>
<groupId>org.apache.woden</groupId>
<artifactId>woden-converter-maven-plugin</artifactId>
<version>1.0M9</version>
<executions>
<execution>
<id>convert</id>
<goals>
<goal>convert</goal>
</goals>
<configuration>
<wsdl><!-- File or URL of wsdl1.1 document.Also multiple
WSDL files can be specified as a comma separated
list. -->
</wsdl>
<targetNS>
<!-- New target namespace for WSDL2.0 document. -->
</targetNS>
<targetDir>
<!-- Target directory for output, default
location is project build directory. -->
</targetDir>
<sourceDir><!-- Source directory for output. --></sourceDir>
<verbose><!-- Verbose mode --></verbose>
<overwrite><!-- Overwrite existing files. --></overwrite>
</configuration>
</execution>
</executions>
</plugin>