How to run XJC with Java 11 and maven? - maven

To generate java classes from XSD (for reading XML files), we used jaxb2-maven-plugin and Java8.
For java 11, we get many issues...
What libraries and plugins do work (today), allowing to generate java code from XSD using java 11 and maven? If possible point out different solutions, such as with cxf-xjc-plugin, jaxb2-Maven-Plugin and others.

I've just investigated the same topic. The best way for Java 11 is to use cxf-xjc-plugin. It's a Maven plugin. No other Maven plugin is able to work under Java 11 without annoying workarounds.
I've published a complete example with cxf-xjc-plugin here: https://artofcode.wordpress.com/2019/02/28/generating-classes-from-xsd-under-java-11-the-right-way/

I was able to get Jaxb2-maven-plugin to work with Java 11. By default the generated classes will be created in the generated classes package. My only gripe is that it doesn't implement toString methods. If I ever figure that out i'll update this.
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
</dependency>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.5.0</version>
<executions>
<execution>
<id>xjc-foo</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sourceType>wsdl</sourceType>
<sources>
<!-- if you put path only, it will read any wsdl or xsd file -->
<!-- if you have xsd that is imported in wsdl, then make sure you point it wsdl file -->
<source>${project.basedir}/src/main/resources/schemas/foo.wsdl</source>
</sources>
<clearOutputDir>false</clearOutputDir>
<packageName>foo</packageName>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation.api</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</plugin>

Related

swagger-codegen-maven-plugin best practices

I'm using the swagger-codegen-maven-plugin within my pom to generate a client. Here is my plugin info:
<plugins>
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.4.9</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/api.json</inputSpec>
<language>java</language>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Using:
java version "1.8.0_221"
Apache Maven 3.6.1
I had many errors when running mvn compile, as the package names could not be found in my repo e.g.
[ERROR]
//target/generated-sources/swagger/src/main/java/io/swagger/client/model/.java:[18,23]
package com.google.gson does not exist
To overcome the errors and enable a successful mvn compile, I have had to name the missing packages within my pom's dependencies e.g.
<dependencies>
<dependency>
<groupId>io.gsonfire</groupId>
<artifactId>gson-fire</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
I don't believe this is best practice, as I have to specify the version myself without knowing the actual version that the source has used.
My question is, what is the best practice for generating a client using maven when there are packages which can't be resolved by the swagger-codegen-plugin? Alternatively, please advise if the resolution I have found to overcome the issue is actually the best practice in this scenario?
Thanks.

Using Spring Boot without the parent POM [duplicate]

Is there a specific recommended approach to the inclusion of the spring-boot parent pom into projects that already have a required parent POM?
What do you recommend for projects that need to extend from an organizational parent (this is extremely common and even something many/most projects published to Maven central depending on the feeder repos they come from). Most of the build stuff is related to creating executable JARs (e.g. running embedded Tomcat/Jetty). There are ways to structure things so that you can get all the dependencies without extending from a parent (similar to composition vs. inheritance). You can't get a build stuff that way though.
So is it preferable to include all of the spring-boot parent pom inside of the required parent POM or to simply have a POM dependency within the project POM file.
Other options?
TIA,
Scott
You can use the spring-boot-starter-parent like a "bom" (c.f. Spring and Jersey other projects that support this feature now), and include it only in the dependency management section with scope=import.That way you get a lot of the benefits of using it (i.e. dependency management) without replacing the settings in your actual parent.
The 2 main other things it does are
define a load of properties for quickly setting versions of dependencies that you want to override
configure some plugins with default configuration (principally the Spring Boot maven plugin). So those are the things you will have to do manually if you use your own parent.
Example provided in Spring Boot documentation:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Update 2022-05-29 with 1.5.9.RELEASE.
I have full code and runable example here https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/9_spring-boot-no-parent (see README.txt to see that you can try)
You need this as a basic
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springframework.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
But that is not enough, you also need explicitly define goal for spring-boot-maven-plugin (If you use Spring Boot as parent, you do not have to explicitly define this)
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springframework.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Otherwise you cannot build as executable jar or war.
Not yet, if you are using JSP, you need to have this:
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
Otherwise, you will get this error message:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project spring-boot-09: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executi
ng in update mode) -> [Help 1]
NO NO , this is still not enough if you are using Maven Profile and Resource Filter with Spring Boot with "#" instead of "${}" (like this example https://www.surasint.com/spring-boot-maven-resource-filter/). Then you need to explicitly add this in
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
And this in
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
See the example in the link https://www.surasint.com/spring-boot-with-no-parent-example/.
As per Surasin Tancharoen's answer, you may also want to define maven surefire plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
and possibly include fail-fast plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>

How to build a project with AspectJ plugin which also has dependencies on querydsl plugin

I have Aspects defined in project A which can be referred from project B without any compilations issues because project A has project B as dependency. However project B needs AspectJ plugin so that aspects can be weaved via compilation/build.
Issue : My project B is using com.mysema.querydsl plugin to generate Q files for database entities. When I compile using AspectJ in eclipse (command clean aspectj:compile install) it does NOT auto generate these Q files and thus the compilation fails and weaving is not processed, overall build fails.
I have tried so many combinations of adding this dependency in AspectJ plugin but nothing works.
Please refer the pom part below:
<!-- AspectJ Maven Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>3.6.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<complianceLevel>1.7</complianceLevel>
<!-- <aspectLibraries>
<aspectLibrary>
<groupId>projectA.groupId</groupId>
<artifactId>projectA.artifactId</artifactId>
</aspectLibrary>
</aspectLibraries> -->
</configuration>
<executions>
<execution>
<!-- <phase>generate-sources</phase> -->
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- AspectJ Maven Plugin -->
What should be done here? I really dont want to create individual aspects in each project. All in all how to build projects with aspectj plugins which have querydsl plugin code references?

maven/apt generated classes in eclipse

Using following configuration in master pom, some classes (metamodel FYI) are generated for all child projects having jpa entities under target/generated-sources, as expected.
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.2.4</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>4.3.10.Final</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
</plugin>
This works perfectly from Maven and Netbeans.
Some team members still use Eclipse. There, generated classes aren't found automatically. They can be opened if added manually to the "build path" (whatever it means as this is redundant to pom.xml). However, that's not stable and will be reset whenever they "update the project" (shouldn't even be needed but...) to reflect project's maven configuration.
My question is, how to configure Eclipse to use this project's configuration automatically? I don't want to change the project's pom.xml too much, as they are perfectly legal and work well outside of Eclipse, which I just want to be taught to behave correctly.
UPDATE: M2Eclipse is installed and doesn't solve this, which is basically our problem.
There ist a project/Eclipse-Plugin called M2Eclipse (link).
The plugin includes the following feature:
Dependency management for Eclipse build path based on Maven's pom.xml

using QueryDSL in osgi

I have been trying to use querydsl in a project which is an osgi bundle.
my pom.xml has the following dependencies:
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>2.5.0</version>
</dependency>
As well as the plugin
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>0.3.2</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.ops4j</groupId>
<artifactId>maven-pax-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<!-- | the following instructions build a simple set of public/private
classes into an OSGi bundle -->
<configuration>
<instructions>
<Import-Package>com.mysema.query.jpa,*</Import-Package>
<Export-Package>com.mypackage.package.*;version="${project.version}"</Export-Package>
</instructions>
</configuration>
</plugin>
Still when I try to start the bundle I get:
Error executing command: Unresolved constraint in bundle com.mypackage.package [163]: Unable to resolve 163.0: missing requirement [163.0] package; (&(package=com.mysema.query.jpa)(version>=2.5.0)(!(version>=3.0.0)))
I was using an older version of querydsl but apparently they fixed some stuff about osgi recently so I upgraded. The problem persists.
What I am missing for querydsl to work inside osgi?
Installing each dependency by hand will be a pain, but AFAIK there's nothing that will take a maven artifact and chain back of all dependencies - this would fail as where would it stop?
You could end up with every version of every logging framework (even if you had pax-logging installed), or the wrong implementation.
Alas in maven's case there's currently no way of applying semantic versioning or higher level requirement and capability. (Though BND (maven-bundle-plugin, bndtools) makes some sensible assumptions at a code level)
Karaf features (see the PDF manual in distribution's ${KARAF_HOME}) can do a lot to alleviate this but it can take some work to setup. There's a(t least) couple of ways to generate features files;
Use the features-maven-plugin
Use the maven-build-helper plugin to publish an XML file that you handcraft (laborious but you can maintain versions using resource filtering).

Resources