I'm a newcomer for graphql java client development. Recently I meet a problem that how to generate a java entity through the graphql schema definition. Since in my side, the schema is always changing by another side, so I want a method to generate the java entity class automatically instead of reading the schema manually then change the code. If there are any practices on such a requirement? Thanks.
You could look into the following maven plugin. It would help you generate Java classes from your .graphqls files.
Assuming you have only one file defining your GraphQL model, named myGraphqls, I would use this plugin as follow:
<build>
<plugins>
<plugin>
<groupId>io.github.kobylynskyi</groupId>
<artifactId>graphql-codegen-maven-plugin</artifactId>
<version>1.2.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<graphqlSchemaPaths>
<graphqlSchemaPath>${project.basedir}/src/main/resources/graphql/myGraphqls.graphqls</graphqlSchemaPath>
</graphqlSchemaPaths>
<outputDir>${project.build.directory}/generated-sources/graphql</outputDir>
<packageName>com.graphql.model</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
After running maven, you would be able to find in the generated-sources folder, a folder named graphql with the classes generated under the package com.graphql.model.
Related
I am working on generation of model classes by Open API Maven plugin which I need to use in my business logic. The api is generated by other team and given to us. It has lot of model classes specification but I need only generation of 3 model classes from the api.yaml template
How this can be achieved?
The plugin configuration
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-java-client</id>
<configuration>
<inputSpec>
${project.build.directory}/../../../../../../../../../component/service/app/src/main/resources/api/v1/api-v1.yaml
</inputSpec>
**<modelPackage>com.example.editing.model</modelPackage>**
<generateSupportingFiles>false</generateSupportingFiles>
<generateApis>false</generateApis>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
</configuration>
</execution>
</executions>
</plugin>
According to the github readme of the openapi-generator-maven-plugin, there is a configuration option called modelsToGenerate which does exactly what you want:
A comma separated list of models to generate. All models is the default.
I'm confused about the way I'm compelled to create a SOAP service in spring boot. I wrote many SOAP services in Java in the past, simply writing down the java code and not a line of XML. A very easy and error less approach.
All the tutorial I read for Spring Boot has the need to write an XSD document, form which maven will read and build the needed classes.
Is there a way, supported by Spring Boot, to bypass the XSD file and write directly the needed java classed instead?
Just to give you some example of what I read, here are some links to the tutorials I'm referring to:
https://www.concretepage.com/spring-boot/spring-boot-soap-web-service-example
https://howtodoinjava.com/spring-boot/spring-boot-soap-webservice-example/
https://www.javainuse.com/spring/springbootsoapwebservice
I believe that writing the XML code to generate the Java one is very error prone and a really difficult to maintain code, when you're developing big services or services with a lot of objects. All works fine if you have a small project, that is not my case.
What I did was to write the classes and then generate the xsd file using schemagen.
This is the configuration in maven pom I added:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>schemagen</id>
<goals>
<goal>schemagen</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectory>${basedir}/src/main/resources/xsds/</outputDirectory>
<transformSchemas>
<transformSchema>
<uri>http://test/test-ws/MyTestSchema</uri>
<toPrefix>test</toPrefix>
<toFile>test.xsd</toFile>
</transformSchema>
</transformSchemas>
<sources>
<source>${basedir}/src/main/java/my/classes/</source>
</sources>
<verbose>true</verbose>
</configuration>
</plugin>
I have two projects:
A
/src/main/resources/schema.xsd
pom.xml
B
/src/main/gen
pom.xml
I want in B project generate classes from XSD, that exists in A Project
In pom.xml of B project I have:
<dependencies>
<dependency>
<groupId>test</groupId>
<artifactId>A</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/resources</schemaDirectory>
<outputDirectory>src/main/gen</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
But xsd file is not found in classpath:
Failed to execute goal org.codehaus.mojo:jaxb2-maven-plugin:1.5:xjc (xjc) on project B: No schemas have been found
How can I use xsd from another project?
My maven-jaxb2-plugin supports separate schema compilation.
How to do this:
Add your artifact a as episode.
If a.xsd is imported into b.xsd, you have to make this schema available to JAXB when compiling b:
One way to do this is to extract a.xsd from the artifact a using Maven dependency plugin, for instance.
Another way would be to use a catalog file to rewrite the location of a.xsd into the artifact a
See this test project for example.
The project a is totally unspectacular. Just compiles the schema a.xsd.
The project b is more interesting. Let's take a look.
pom.xml:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<configuration>
<catalog>src/main/resources/catalog.cat</catalog>
<episodes>
<episode>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a</artifactId>
</episode>
</episodes>
</configuration>
</plugin>
The configuration says use the artifact a as episode. So when JAXB/XJC meets classes compiled in a, it will reuse them instead of generating new ones.
By the way, you can use the useDependenciesAsEpisodes instead of configuring individual episodes. In this case all the dependencies will be treated as episodes which is very convenient (less configuration).
The configuration also says to use the catalog file:
REWRITE_SYSTEM "http://www.ab.org" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!"
This instructs JAXB/XJC to rewrite all schema URLs starting with http://www.ab.org to start with maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::! instead. The latter will be processed by the maven-jaxb2-plugin and finally resolved to the resource in a.
Let's take a closer look. The schema b.xsd imports http://www.ab.org/a.xsd:
<import namespace="urn:a" schemaLocation="http://www.ab.org/a.xsd"/>
This will be rewritten to maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd which will be resolved to the a.xsd inside the JAR of the project a. So, finally, JAXB/XJC will be able to read this schema from the a's JAR artifact.
You can also use PUBLIC instead of REWRITE_SYSTEM to reference a.xsd per namespace URI instead of schema location (which is logically better):
PUBLIC "urn:a" "maven:org.jvnet.jaxb2.maven2:maven-jaxb2-plugin-tests-MAVEN_JAXB2_PLUGIN-82-a:jar::!/a.xsd"
However there's a bug in JAXB/XJC this does not work if you have schemaLocation in your xs:import.
This would work at the moment:
<xsd:import namespace="urn:a"/>
This won't work at the moment:
<xsd:import namespace="urn:a" schemaLocation="a.xsd"/>
I've sent Oracle a pull request which fixes that but it's not applied yet.
The explanation above applies to the maven-jaxb2-plugin and works in versions 0.10.0 and higher.
Your original question is about jaxb2-maven-plugin from Codehaus which is a different Maven plugin. This plugin does not have all the features I've described above, but at least episodes should work via arguments. Catalogs must also work, but I believe, jaxb2-maven-plugin does not support resolving schemas in Maven artifacts. You can use the maven-dependency-plugin to extract a.xsd from artifact a instead.
SO disclaimer: I am the author of the maven-jaxb2-plugin.
Note for reviewers: it is NOT my intention here to push/advertise my plugin, I just want to provide a solution to the asked question. And it appears that my project offers the best/most elegant and full solution.
The problem with this configuration is that <schemaDirectory> expects a File name/path. The thing about File is that it looks for files on the file system, searching from the current working directory. In which case the project root. But the resource from project A is not in the src/main/resources of the project B. It is a classpath resource, of which (when build in maven), the src/main/resources doesn't even exist anymore.
I've never tried to do with with the jaxb2-maven-plugin, so I am not sure if it is possible.
But with the maven-jaxb2-plugin, it allows Compiling a schema from a Maven artifact. You could so something like
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.9.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemas>
<schema>
<dependencyResource>
<groupId>projecta.groupid</groupId>
<artifactId>project-a</artifactId>
<version>${project.version}</version>
<resource>/schema.xsd</resource>
</dependencyResource>
</schema>
</schemas>
<generateDirectory>src/main/gen/</generateDirectory>
<generatePackage>mypackage</generatePackage>
</configuration>
</plugin>
In which case, it's resource (schema.xsd) is in the src/main/resources of project A. The plugin will generate the class files to the mypackage package and sources the src/main/gen
We can also use as below in pom.xml file
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>id1</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<outputDirectory>src/main/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
<packageName>com.subu.xsd.model</packageName>
<schemaDirectory>src/main/java/schemadir</schemaDirectory>
<schemaFiles>XYZ.xsd</schemaFiles>
</configuration>
</execution>
</executions>
</plugin>
I am having a WSDL (lets say one.wsdl ) from which I want to generate JAXB artifacts using maven plugin. one.wsdl imports another wsdl (two.wsdl ) . When I am running the maven plugin to generate the JAXB artifacts , looks like its not recognizing two.wsdl and not generating the JAXB artifacts.
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.5</version>
<executions>
<execution>
<id>DataBindings_XJC_generate</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/wsdl/</schemaDirectory>
<schemaIncludes>
<include>one.wsdl</include>
</schemaIncludes>
<generateDirectory>src/main/java/</generateDirectory>
<generatePackage></generatePackage>
<readOnly>true</readOnly>
<removeOldOutput>true</removeOldOutput>
<verbose>true</verbose>
<extension>false</extension>
<forceRegenerate>true</forceRegenerate>
<episode>false</episode>
</configuration>
</execution>
</executions>
</plugin>
one.wsdl is refering to two.wsdl like this (both are in same directory).
<wsdl:import namespace="http://namespce:uri" location="two.wsdl"/>
However If i give the two.wsdl (in the include tag) in plugin , its able to generate the jaxb artifacts successfully.
Can anyone please suggest what might have gone wrong with the plugin when it comes to recognizing the imported WSDL ?
maven-jaxb2-plugin is just a wrapper for XJC. It does not do any schema processing on it own, it just calls XJC.
Please send me a test case as a PR request here:
https://github.com/highsource/maven-jaxb2-plugin/tree/master/tests
I'll check if this has something to do with the plugin (unlikely) or forward it to Oracle.
I think, this might be also by design - if your one.wsdl does not use anything from two.wsdl then nothing for the two.wsdl will be generated.
I use Spring Object-Xml mapping with Jibx to convert some xsd files to Java source files. Jibx is called by jibx-maven-plugin in the build process. My schema files (.xsd) have a namespace "a.b.com" but I want that the generated Java sources are under package "a.com" because the rest of the Java code is organized like that.
I noticed Java packages are determined automatically based on xsd's namespace. Therefore, the question: is it possible to set the java package of output Java source files in xsd->Java transform when using the Jibx Maven plugin when a namespace was defined in the the schema files?
Proposed solutions so far:
1) Use build executions
Proposed below.
Problems:
xsd->Java transform is run every build. I want to manually run it or that is only run when I change xml schemas.
prefer-inline attribute in customization.xml acts differently with this setup, inlining attributes of an object reference
2) Use customization xml to set Java package
Proposed here: Jibx Codegen: customization file - package per schema
Problem: It did not work.
3) modular schema
Proposed here: Jibx Maven plugin: cross-reference among schemas when they are converted in different build executions
Problem: Too complicated to setup one pom for each schema, generating a jar for each schema and importing the jar in other schemas.
Was anybody successful to solve these issues and was able to set custom Java packages in a xsd->Java conversion when namespace is defined in the xml schemas?
Thanks in advance.
Based on the documentation it can be done like the following:
<plugin>
<groupId>org.jibx</groupId>
<artifactId>jibx-maven-plugin</artifactId>
<version>1.2.4.5</version>
<configuration>
<schemaLocation>src/main/conf</schemaLocation>
<includeSchemas>
<includeSchema>myschema.xsd</includeSchema>
</includeSchemas>
<options>
<package>my.package</package>
</options>
</configuration>
<executions>
<execution>
<goals>
<goal>schema-codegen</goal>
</goals>
</execution>
</executions>
</plugin>
But you should be carefull about using the packagename instead of the defaults which are coming from the xsd-namespaces, cause it can happen that you will get clashes within the generated source if you have multiple namespaces.
You can define multiple executions to have different schematas having different package names.
<plugin>
<groupId>org.jibx</groupId>
<artifactId>jibx-maven-plugin</artifactId>
<version>1.2.4.5</version>
<executions>
<execution>
<id>schemata-a</id>
<goals>
<goal>schema-codegen</goal>
</goals>
<configuration>
<schemaLocation>src/main/conf-a</schemaLocation>
<includeSchemas>
<includeSchema>myschema.xsd</includeSchema>
</includeSchemas>
<options>
<package>my.package.a</package>
</options>
</configuration>
</execution>
<execution>
<id>schemata-b</id>
<goals>
<goal>schema-codegen</goal>
</goals>
<configuration>
<schemaLocation>src/main/conf-b</schemaLocation>
<includeSchemas>
<includeSchema>xyz.xsd</includeSchema>
</includeSchemas>
<options>
<package>my.package.b</package>
</options>
</configuration>
</execution>
</executions>
</plugin>
If you can change the namespaces in your xsd files makes life easier.