I need to migrate a maven project to gradle. The maven project uses the maven-jaxb2-plugin like this (version for the plugin is set in a root pom.xml):
<plugin>
<groupId>...</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>package for generated classes</generatePackage>
<schemaDirectory>directory containing XSD files</schemaDirectory>
<includeSchemas>
<includeSchema>XSD file name</includeSchema>
<includeSchema>XSD file name</includeSchema>
...
</includeSchemas>
<strict>true</strict>
<verbose>true</verbose>
<extension>true</extension>
</configuration>
<plugin>
So, I wanted to achieve the same functionality in gradle, and this is what I have:
plugins {
id "com.github.jacobono.jaxb" version "1.3.5"
}
dependencies {
jaxb "org.glassfish.jaxb:jaxb-runtime:2.2.11"
jaxb "org.glassfish.jaxb:jaxb-xjc:2.2.11"
}
jaxb {
xsdDir = "directory containing XSD files"
xjc {
taskClassname = "com.sun.tools.xjc.XJC2Task"
generatedPackage = "package for generated classes"
}
}
compileJava.dependsOn xjc
This project is part of a multi-project build with dependencies on other projects etc., but I don't think those are relevant.
Am I on the right track?? I'm asking because the behavior doesn't seem to be the same when I do mvn clean install and gradle clean build
Question:
Is there a way to specify the XSD file names we want to use in gradle (as we do using includeSchema in maven)?
My problem:
This is how I achieved this task after doing the research. This worked as expected. Add followings to your build file.
buildscript {
dependencies {
classpath 'com.github.jacobono:gradle-jaxb-plugin:1.3.5'
}
}
apply plugin: 'com.github.jacobono.jaxb'
dependencies {
jaxb 'com.sun.xml.bind:jaxb-xjc:2.2.7-b41'
jaxb 'com.sun.xml.bind:jaxb-impl:2.2.7-b41'
jaxb 'javax.xml.bind:jaxb-api:2.2.7'
jaxb "org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.6.5"
jaxb "org.jvnet.jaxb2_commons:jaxb2-basics:0.6.4"
jaxb "org.jvnet.jaxb2_commons:jaxb2-basics-annotate:0.6.4"
jaxb "org.jvnet.jaxb2_commons:jaxb2-value-constructor:3.0"
}
jaxb {
System.setProperty('javax.xml.accessExternalSchema', 'all') //To solve external schema dependencies
xsdDir = "src/main/resources/schema/" //xsd directory
xjc {
taskClassname = "org.jvnet.jaxb2_commons.xjc.XJC2Task" // This is for setter plugin
args = ["-Xsetters","-Xsetters-mode=direct"]
}
}
you should run 'gradle xjc' to generate related java files from xsd files.
Related
I implement my custom code generation for https://github.com/OpenAPITools/openapi-generator
but i have no idea how to add this to gradle plugin. I need to add it to classpath while gradle perform openapi tasks
For maven i can easily add my custom implementation com.my.generator:customgenerator:1.0-SNAPSHOT in plugin dependency block,
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-maven-plugin-version}</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<templateDirectory>myTemplateDir</templateDirectory>
<apiPackage>${default.package}.handler</apiPackage>
<modelPackage>${default.package}.model</modelPackage>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.my.generator</groupId>
<artifactId>customgenerator</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
but in gradle i have no idea how to do it
The solution is simple if you know how Gradle plugins work. Here are steps how to do it:
You need to add your custom generator class to the classpath of the plugin. But, you can not use there any module of the Gradle project, in which you want to use the generator plugin, because Gradle plugins are applied before the whole compilation of the project and also before dependencies are resolved. So, you must use the already compiled jar file. For example, create a new Gradle project where you place custom generator code and publish it to maven local repository (How to publish source into local maven repository with Gradle?). Then you can add it to plugins classpath like this:
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.openapitools:openapi-generator:4.3.0"
classpath "some.custom.openapi:generator:0.0.1"
}
}
Openapi generator use Java service loader to load generators (https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html). So, in your custom generator project create file org.openapitools.codegen.CodegenConfig with content
some.custom.openapi.CustomJavaCodegen
(Here must be the name of the custom generator class) and place it to folder src/main/resources/META-INF/services/.
In your custom generator class override method getName with your generator name, which you will use in the configuration of openApiGenerator in the Gradle file.
I get this working with these steps. If I forget something to write it here, comment, and I will try to fill missing information.
I'm new bee to Gradle. Have custom JUnit Listener, which reads the custom annotation data and generates report and need to configure it as part of Gradle. Is there anyway to configure below surefire plugin in Gradle 4.4.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>my.company.MyRunListener</value>
</property>
</properties>
</configuration>
</plugin>
I understand that, it may not possible to use maven plugin as is in gradle. I checked TestListener, it doesn't have support to read annotations to proceed with that.
I would like to understand the way to configure my JUnit Listener in Gradle.
The JUnit Foundation library enables you to declare your listeners in a service provider configuration file, which are then attached automatically - regardless of execution environment. Details can be found here.
Gradle Configuration for JUnit Foundation
// build.gradle
...
apply plugin: 'maven'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
...
}
dependencies {
...
compile 'com.nordstrom.tools:junit-foundation:12.2.0'
}
ext {
junitFoundation = configurations.compile.resolvedConfiguration.resolvedArtifacts.find { it.name == 'junit-foundation' }
}
test.doFirst {
jvmArgs "-javaagent:${junitFoundation.file}"
}
test {
// debug true
// not required, but definitely useful
testLogging.showStandardStreams = true
}
ServiceLoader provider configuration file
# src/main/resources/META-INF/services/com.nordstrom.automation.junit.JUnitWatcher
com.example.MyRunListener
With this configuration, the listener implemented by MyRunListener will be automatically attached to the RunNotifier supplied to the run() method of JUnit runners. This feature eliminates behavioral differences between the various test execution environments like Maven, Gradle, and native IDE test runners.
I’m afraid, there is currently no support for JUnit RunListeners in Gradle. There is only an open ticket requesting that feature: https://github.com/gradle/gradle/issues/1330
As someone has mentioned in the comments on that ticket, “the primary issue […] is the absence of TestDescriptor.getAnnotations()” in Gradle; otherwise you might have been able to rewrite your RunListener as a Gradle TestListener. So unless I’ve missed something when skimming through the ticket, it seems that you are mostly out of luck at the moment :-(
I'm new bee to Gradle. Have custom JUnit Listener, which reads the custom annotation data and generates report and need to configure it as part of Gradle. Is there anyway to configure below surefire plugin in Gradle 4.4.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>my.company.MyRunListener</value>
</property>
</properties>
</configuration>
</plugin>
I understand that, it may not possible to use maven plugin as is in gradle. I checked TestListener, it doesn't have support to read annotations to proceed with that.
I would like to understand the way to configure my JUnit Listener in Gradle.
The JUnit Foundation library enables you to declare your listeners in a service provider configuration file, which are then attached automatically - regardless of execution environment. Details can be found here.
Gradle Configuration for JUnit Foundation
// build.gradle
...
apply plugin: 'maven'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenLocal()
mavenCentral()
...
}
dependencies {
...
compile 'com.nordstrom.tools:junit-foundation:12.2.0'
}
ext {
junitFoundation = configurations.compile.resolvedConfiguration.resolvedArtifacts.find { it.name == 'junit-foundation' }
}
test.doFirst {
jvmArgs "-javaagent:${junitFoundation.file}"
}
test {
// debug true
// not required, but definitely useful
testLogging.showStandardStreams = true
}
ServiceLoader provider configuration file
# src/main/resources/META-INF/services/com.nordstrom.automation.junit.JUnitWatcher
com.example.MyRunListener
With this configuration, the listener implemented by MyRunListener will be automatically attached to the RunNotifier supplied to the run() method of JUnit runners. This feature eliminates behavioral differences between the various test execution environments like Maven, Gradle, and native IDE test runners.
I’m afraid, there is currently no support for JUnit RunListeners in Gradle. There is only an open ticket requesting that feature: https://github.com/gradle/gradle/issues/1330
As someone has mentioned in the comments on that ticket, “the primary issue […] is the absence of TestDescriptor.getAnnotations()” in Gradle; otherwise you might have been able to rewrite your RunListener as a Gradle TestListener. So unless I’ve missed something when skimming through the ticket, it seems that you are mostly out of luck at the moment :-(
I'm using Eclipse m2e in my development environment, and I have a spring-boot maven project(can be viewed as a standard maven jar project with runnable main class in this context) which depends on another maven project in the same workspace(workspace artifact, let's call it moduleB, a sibling of the spring-boot project), when I run the maven goal clean package(the appassembler:assemble goal can be ommited because I configured the execution section of the plugin, see the configuration detail below), the generated assembly in the target directory seems fine, except that the jar of moduleB is missing in the repo. It seems that the plugin is trying to copy every file under the class folder in moduleB according to the log:
...
[INFO] Installing artifact ...
[INFO] Installing artifact /foo/bar/moduleB/target/classes to /foo/bar/repo/groupid/artifactid/0.0.1-SNAPSHOT/moduleB-0.0.1-SNAPSHOT.jar
[INFO] Installing ...
...
How to resolve this? Do I have to install moduleB into the maven local repository before running the assemble? Is there any way to bypass this step because I don't want to mess up the repository with unstable artifacts.
P.S. configuration of the plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<configurationDirectory>conf</configurationDirectory>
<configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
<assembleDirectory>${project.build.directory}/someApp</assembleDirectory>
<extraJvmArguments>-Xms128m</extraJvmArguments>
<logsDirectory>logs</logsDirectory>
<repositoryLayout>default</repositoryLayout>
<repositoryName>repo</repositoryName>
<showConsoleWindow>true</showConsoleWindow>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
<binFileExtensions>
<unix>.sh</unix>
</binFileExtensions>
<programs>
<program>
<mainClass>someClass</mainClass>
<id>app</id>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
</program>
</programs>
</configuration>
<executions>
<execution>
<id>assemble</id>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
Update #1:
I bypass the spring-boot:repackage goal because it encapsulates everything in one jar, including the configuration files which I want to be conveniently editable in production environment. Here's the earlier question I asked: Alternatives to distribute spring-boot application using maven (other than spring-boot:repackage)
I would like to specify the below maven plugin in gradle. How to specify the configuration in gradle?
<build>
<plugins>
<plugin>
<groupId>com.github.kongchen</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>${swagger-maven-plugin-version}</version>
<configuration>
<apiSources>
<apiSource>
test
</apiSource>
</apiSources>
</configuration>
</plugin>
</plugins>
In general, it's impossible to use Maven plugin 'as is' in Gradle. Maven plugins internally depend on some classes that exist only in Maven universe.
So, the best approach would be porting the plugin to Gradle.
In your particular case there is a Gradle port of Swagger Maven plugin. I haven't used it by myself, but quick googling reveals this:
Gradle Swagger plugin
I aggree with Mark Bramnik answer but you can try what can work by comparing documentation of both repositories : https://github.com/dave-ellis/gradle-swagger-plugin and https://github.com/kongchen/swagger-maven-plugin. All name identified in table called "Configuration for apiSource" of the former one could be a variable inside swagger block for gradle.
buildscript {
repositories {
mavenLocal()
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
classpath group: 'com.github.gradle-swagger', name: 'gradle-swagger-plugin', version: '1.0.1-SNAPSHOT'
}
}
apply plugin: 'maven'
apply plugin: 'swagger'
apply plugin: 'java'
swagger {
endPoints = [
'com.foo.bar.apis',
'com.foo.bar.apis.internal.Resource'
]
apiVersion = 'v1'
basePath = 'http://www.example.com'
mustacheFileRoot = "${projectDir}/src/main/resources/"
outputTemplate = "${mustacheFileRoot}/strapdown.html.mustache"
swaggerDirectory = "${buildDir}/site/api-docs"
outputPath = "${buildDir}/site/swagger/strapdown.html"
}