Empty methods noticeably slower in Java 11 than Java 8 - java-8

I was comparing the performance of JDK 8 and 11 using jmh 1.21 when I ran across some surprising numbers:
Java version: 1.8.0_192, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.emptyMethod avgt 25 0.362 ± 0.001 ns/op
Java version: 9.0.4, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.emptyMethod avgt 25 0.362 ± 0.001 ns/op
Java version: 10.0.2, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.emptyMethod avgt 25 0.723 ± 0.001 ns/op
Java version: 11.0.1, vendor: Oracle Corporation
Benchmark Mode Cnt Score Error Units
MyBenchmark.emptyMethod avgt 25 0.724 ± 0.002 ns/op
OpenJDK 11 and 12 perform similar to OracleJDK 11. I have omitted their numbers for the sake of brevity.
I understand that microbenchmarks do not indicate the performance behavior of real-life applications. Still, I'm curious where this difference is coming from. Any ideas?
Here is the benchmark in its entirety:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jmh</groupId>
<artifactId>empty-method</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>JMH benchmark sample: Java</name>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jmh.version>1.21</jmh.version>
<javac.target>1.8</javac.target>
<uberjar.name>benchmarks</uberjar.name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>3.0</version>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerVersion>${javac.target}</compilerVersion>
<source>${javac.target}</source>
<target>${javac.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${uberjar.name}</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<!--
Shading signed JARs will fail without this.
http://stackoverflow.com/questions/999489/invalid-signature-file-when-attempting-to-run-a-jar
-->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6.1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
src/main/java/jmh/MyBenchmark.java:
package jmh;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import java.util.concurrent.TimeUnit;
#BenchmarkMode(Mode.AverageTime)
#OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark
{
#Benchmark
public void emptyMethod()
{
}
}
Here is the Windows-specific script I use. It should be trivial to translate it to other platforms:
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_192
call mvn -V -Djavac.target=1.8 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\jdk-9.0.4
call mvn -V -Djavac.target=9 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\jdk-10.0.2
call mvn -V -Djavac.target=10 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
set JAVA_HOME=C:\Program Files\Java\oracle-11.0.1
call mvn -V -Djavac.target=11 clean install
"%JAVA_HOME%\bin\java" -jar target\benchmarks.jar
My runtime environment is:
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T14:41:47-04:00)
Maven home: C:\Program Files\apache-maven-3.6.0\bin\..
Default locale: en_CA, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
More specifically, I am running Microsoft Windows [Version 10.0.17763.195].

You are measuring empty benchmarks, not empty methods. In other words, measuring the minimal infrastructure code that handles the benchmark itself. This is easy to dissect, because you'd expect only a few instructions on the hot path. JMH's -prof perfasm or -prof xperfasm would give you those hottest instructions in seconds.
I think the effect is due to Thread-Local Handshakes (JEP 312), see:
8u191: 0.389 ± 0.029 ns/op
[so far so good]
3.60% ↗ ...a2: movzbl 0x94(%r8),%r10d
0.63% │ ...aa: add $0x1,%rbp
32.82% │ ...ae: test %eax,0x1765654c(%rip) ; global safepoint poll
58.14% │ ...b4: test %r10d,%r10d
╰ ...b7: je ...a2
11.0.2: 0.585 ± 0.014 ns/op [oops, regression]
0.31% ↗ ...70: movzbl 0x94(%r9),%r10d
0.19% │ ...78: mov 0x108(%r15),%r11 ; reading the thread-local poll addr
25.62% │ ...7f: add $0x1,%rbp
35.10% │ ...83: test %eax,(%r11) ; thread-local safepoint poll
34.91% │ ...86: test %r10d,%r10d
╰ ...89: je ...70
11.0.2, -XX:-ThreadLocalHandshakes: 0.399 ± 0.048 ns/op [back to 8u perf]
5.64% ↗ ...62: movzbl 0x94(%r8),%r10d
0.91% │ ...6a: add $0x1,%rbp
34.36% │ ...6e: test %eax,0x179be88c(%rip) ; global safepoint poll
54.79% │ ...74: test %r10d,%r10d
╰ ...77: je ...62
I think this is largely visible mostly in tight loops like this one.
UPD: Hopefully, more details here.

Related

Tomcat deploys older version of webapp

This might be a duplicate, cause I can't image that we're the first to encounter this, but I can't seem to find it.
So, we are deploying WAR files to a tomcat 8.5 server with gitlab ci using maven. Issue is that tomcat messes up the versions when we moved from 0.2.9 to 0.2.10. Apparendly the server deploys the WARs in alphabetical order and 0.2.10 lies between 0.2.1 and 0.2.2 and the running version is still 0.2.9 even while 0.2.10 was correctly deployed to the server.
Full webapp name looks like: WebappName##0.2.10-SNAPSHOT_201901010000.war
We thought about renaming our versions to 0.2.009 and 0.2.010 but that seems like a rather dirty work-around. Of cause older versions will be deleted from time to time so it's not a permanent problem, but it's just somewhat annoying and any hints on how to solve this would be great.
From the pom.xml
<version>0.2.10-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.install.skip>true</maven.install.skip>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
[..]
<profile>
<id>deploy-stage</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<war.name>WebappName##${project.version}_${timestamp}</war.name>
<tomcat.url>http://[..]/manager/text</tomcat.url>
<tomcat.server>[..]</tomcat.server>
<tomcat.webpath>/${war.name}</tomcat.webpath>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>default-war</id>
<goals>
<goal>manifest</goal>
<goal>war</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<warName>${war.name}</warName>
<failOnMissingWebXml>true</failOnMissingWebXml>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<forced>true</forced>
<manifest>
<addClasspath>true</addClasspath>
<packageName>true</packageName>
<useUniqueVersions>true</useUniqueVersions>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Archetype>${archetypeArtifactId}</Archetype>
<Archetype-Version>${archetypeVersion}</Archetype-Version>
</manifestEntries>
</archive>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<warFile>${project.build.directory}/${war.name}.war</warFile>
<url>${tomcat.url}</url>
<server>${tomcat.server}</server>
<path>${tomcat.webpath}</path>
</configuration>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
From gitlab-ci.yml
variables:
MAVEN_OPTS: "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
# Cache downloaded dependencies and plugins between builds.
cache:
paths:
- /root/.m2/repository/
stages:
- build
- deploy
# Run deploy
deploy:staging:
stage: deploy
script:
- 'mvn $MAVEN_CLI_OPTS -Dsonar.branch=$CI_COMMIT_REF_NAME deploy -am -P deploy-stage'
only:
- staging
image: maven:3.3.9-jdk-8
As the Apache Tomcat documentation says:
String comparisons are used to determine version order.
This is simply not the same as comparison of Maven artifact versions. A version of 2.0.2 is always larger by String comparison than 2.0.10 or even 2.0.15000 etc.
I guess you have something like this in your pom.xml:
<properties>
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
</properties>
<build>
<finalName>${project.artifactId}##${project.version}_${maven.build.timestamp}</finalName>
</build>
You can change that to:
<finalName>${project.artifactId}##${maven.build.timestamp}_${project.version}</finalName>
which yields a file name like WebappName##201901010000_0.2.10-SNAPSHOT.war.
This way the most current build by timestamp will be deployed as currently active application version.
Alternatively you can keep your version schema of the .war file name and instead have your app deployed using a versioned file name for your context.xml:
apache-tomcat/conf/Catalina/localhost/WebappName##201901010000.xml
with the content:
<Context docBase="/path/to/WebappName##0.2.10-SNAPSHOT_201901010000.war" path="/WebappName"/>
In Apache Tomcat Manager this will show up as version 201901010000 in application version column. Again the most current build by timestamp will be deployed as currently active application version independent of the Maven artifact version as the deployment version String is taken from the .xml file name instead of the .war file name.

Proguard with JDK 10 / JDK 11 and maven pugin

Ho do I run Proguard with JDK 10 / JDK 11 and setup maven plugin?
Migration issues concerning OpenJDK 11 & OpenJFX 11 (& Proguard)
First of all, Proguard 6.0.3 does not run on Java 11 yet
(#188 Support Java 11, see https://sourceforge.net/p/proguard/feature-requests/188/).
Your sources can be compiled with JDK 11. For proguard plugin we have to use JDK 10.
In maven-compiler-plugin, set version to JDK 10:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>10</source>
<target>10</target>
<compilerArgs>
<arg>--add-modules=[required modules]</arg>
</compilerArgs>
</configuration>
</plugin>
Property for JDK 10 (OpenJDK is fine):
<properties>
<java.home.openjdk10>[pathtoJDK20]\jdk-10.0.2</java.home.openjdk10>
</properties>
proguard-maven-plugin:
<plugin>
<groupId>com.github.dingxin</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>1.0.3</version>
<executions>
<execution>
<id>process-classes-with-proguard</id>
<phase>test</phase>
<goals>
<goal>proguard</goal>
</goals>
<configuration>
<options>
<option>[proguarg options]</option>
</options>
<libs>
<lib>${java.home.openjdk10}/lib/jrt-fs.jar</lib>
<lib>${java.home.openjdk10}/jmods/java.base.jmod(!.jar;!module-info.class)</lib>
<lib>${java.home.openjdk10}/jmods/java.compiler.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.corba.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.datatransfer.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.desktop.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.instrument.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.logging.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.management.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.management.rmi.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.naming.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.prefs.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.rmi.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.scripting.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.se.ee.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.se.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.security.jgss.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.security.sasl.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.smartcardio.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.sql.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.sql.rowset.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.transaction.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.xml.bind.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.xml.crypto.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.xml.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.xml.ws.annotation.jmod</lib>
<lib>${java.home.openjdk10}/jmods/java.xml.ws.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.accessibility.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.aot.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.attach.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.charsets.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.compiler.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.crypto.cryptoki.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.crypto.ec.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.crypto.mscapi.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.dynalink.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.editpad.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.hotspot.agent.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.httpserver.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.incubator.httpclient.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.ed.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.jvmstat.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.le.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.opt.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.vm.ci.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.vm.compiler.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.internal.vm.compiler.management.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jartool.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.javadoc.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jcmd.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jconsole.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jdeps.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jdi.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jdwp.agent.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jlink.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jshell.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jsobject.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.jstatd.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.localedata.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.management.agent.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.management.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.naming.dns.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.naming.rmi.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.net.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.pack.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.rmic.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.scripting.nashorn.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.scripting.nashorn.shell.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.sctp.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.security.auth.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.security.jgss.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.unsupported.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.xml.bind.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.xml.dom.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.xml.ws.jmod</lib>
<lib>${java.home.openjdk10}/jmods/jdk.zipfs.jmod</lib>
</libs>
</configuration>
</execution>
</executions>
</plugin>

Can maven-antrun-plugin generate a HTML report showing the exception errors?

I have a Maven Surefire report that generates 3 files:
TESTS-TestSuites.xml - shows only passing tests. no info about fails or errors.
TEST-me.qa.MyTest.xml - see below
me.qa.MyTest.txt - file containing console output showing exceptions
Each failing test, shows an error in the TEST-me.qa.MyTest.xml file like this:
<testcase name="testIPcheckCanCalculate" classname="me.qa.TestLogChecks" time="0.016">
<failure message="Average is too low: 0.5357142857142857. Min: 20.0"
type="java.lang.AssertionError">java.lang.AssertionError: Average is too low:
0.5357142857142857. Min: 20.0
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.assertTrue(Assert.java:41)
at me.qa.TestLogChecks.testIPcheckCanCalculate(TestLogChecks.java:230)
</failure>
<system-out>Testing InPreparer.getInv().getSomething().checkCanCalculate() ...
</system-out>
</testcase>
Can maven-antrun-plugin generate a HTML report showing the exception errors (and fails) ? Currently, the JUNit output file, called junit-noframes.html , only shows information in the TESTS-TestSuites.xml and so no failure information at all is being shown (even though my include is for *.xml). My workaround is to also look inside the me.qa.MyTest.txt file to see what the errors are, but I want those errors to appear on my report and also show a failed total number of tests on the report.
Here is my Maven config:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>test-reports</id>
<phase>test</phase>
<configuration>
<tasks>
<junitreport todir="target/surefire-reports">
<fileset dir="target/surefire-reports">
<include name="**/*.xml" />
</fileset>
<report format="frames" todir="target/surefire-reports" />
</junitreport>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>ant</groupId>
<artifactId>ant-junit</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-trax</artifactId>
<version>1.8.0</version>
</dependency>
</dependencies>
</plugin>
OR, am I doing this all wrong and can Surefire itself generate a suitable report?
I solved it. Iinstead of using the maven-antrun-plugin I am now using the maven-surefire-report plugin along with the goal site maven-surefire:report . NOTE: You need to run the site goal first in order to generate the CSS files for the report.
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
<configuration>
<showSuccess>false</showSuccess>
<outputDirectory>${basedir}/target/surefire-reports</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>2.1</version>
<configuration>
<outputDirectory>${basedir}/target/surefire-reports</outputDirectory>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

How to generate classes from wsdl using Maven and wsimport?

When I attempt to run "mvn generate-sources" this is my output :
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building gensourcesfromwsdl 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.104s
[INFO] Finished at: Tue Aug 20 15:41:10 BST 2013
[INFO] Final Memory: 2M/15M
[INFO] ------------------------------------------------------------------------
I do not receive any errors but there are no java classes generated from the wsdl file.
Here is my pom.xml file that I'm running the plugin against :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>gensourcesfromwsdl</groupId>
<artifactId>gensourcesfromwsdl</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlLocation>http://mysite/firstwsdl.asmx?wsdl</wsdlLocation>
<packageName>com</packageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
What am I doing wrong ? The package com exists in the project 'gensourcesfromwsdl' and the wsdl location is valid.
When I run wsimport via the command line : >wsimport -keep -verbose http://mysite/firstwsdl.asmx?wsdl the class is generated.
To generate classes from WSDL, all you need is build-helper-maven-plugin and jaxws-maven-plugin in your pom.xml
Make sure you have placed wsdl under folder src/main/resources/wsdl and corresponding schema in src/main/resources/schema, run command "mvn generate-sources" from Project root directory.
C:/Project root directory > mvn generate-sources
generated java classes can be located under folder
target/generated/src/main/java/com/raps/code/generate/ws.
pom.xml snippet
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals><goal>add-source</goal></goals>
<configuration>
<sources>
<source>${project.build.directory}/generated/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<configuration>
<wsdlDirectory>${project.basedir}/src/main/resources/wsdl</wsdlDirectory>
<packageName>com.raps.code.generate.ws</packageName>
<keep>true</keep>
<sourceDestDir>${project.build.directory}/generated/src/main/java</sourceDestDir>
</configuration>
<executions>
<execution>
<id>myImport</id>
<goals><goal>wsimport</goal></goals>
</execution>
</executions>
</plugin>
Here is an example of how to generate classes from wsdl with jaxws maven plugin from a url or from a file location (from wsdl file location is commented).
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
<plugins>
<!-- usage of jax-ws maven plugin-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>wsimport-from-jdk</id>
<goals>
<goal>wsimport</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- using wsdl from an url -->
<wsdlUrls>
<wsdlUrl>
http://myWSDLurl?wsdl
</wsdlUrl>
</wsdlUrls>
<!-- or using wsdls file directory -->
<!-- <wsdlDirectory>src/wsdl</wsdlDirectory> -->
<!-- which wsdl file -->
<!-- <wsdlFiles> -->
<!-- <wsdlFile>myWSDL.wsdl</wsdlFile> -->
<!--</wsdlFiles> -->
<!-- Keep generated files -->
<keep>true</keep>
<!-- Package name -->
<packageName>com.organization.name</packageName>
<!-- generated source files destination-->
<sourceDestDir>target/generatedclasses</sourceDestDir>
</configuration>
</plugin>
</plugins>
</build>
Even though this is bit late response, may be helpful for someone. Look like you have used pluginManagement. If you use pluginManagement
, it will not pick the plug-in execution.
It should be under
<build>
<plugins>
<plugin>
Try to wrap wsdlLocation in wsdlUrls
<wsdlUrls>
<wsdlLocation>http://url</wsdlLocation>
</wsdlUrls>
I see some people prefer to generate sources into the target via jaxws-maven-plugin AND make this classes visible in source via build-helper-maven-plugin. As an argument for this structure
the version management system (svn/etc.) would always notice changed
sources
With git it is not true. So you can just configure jaxws-maven-plugin to put them into your sources, but not under the target folder. Next time you build your project, git will not mark these generated files as changed. Here is the simple solution with only one plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<dependencies>
<dependency>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-fluent-api</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-tools</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<packageName>som.path.generated</packageName>
<xjcArgs>
<xjcArg>-Xfluent-api</xjcArg>
</xjcArgs>
<verbose>true</verbose>
<keep>true</keep> <!--used by default-->
<sourceDestDir>${project.build.sourceDirectory}</sourceDestDir>
<wsdlDirectory>src/main/resources/META-INF/wsdl</wsdlDirectory>
<wsdlLocation>META-INF/wsdl/soap.wsdl</wsdlLocation>
</configuration>
</execution>
</executions>
</plugin>
Additionally (just to note) in this example SOAP classes are generated with Fluent API, so you can create them like:
A a = new A()
.withField1(value1)
.withField2(value2);
The key here is keep option of wsimport. And it is configured using element in
About keep from the wsimport documentation :
-keep keep generated files
i was having the same issue while generating the classes from wsimport goal. Instead of using jaxws:wsimport goal in eclipse Maven Build i was using clean compile install that was not able to generate code from wsdl file. Thanks to above example.
Run jaxws:wsimport goal from Eclipse ide and it will work

Generating Multiple TLDs With Maven Javadoc Plugin & TLDGen

I've got a taglib project that I use the TLDGen library to help build my TLD files from annotations in my classes. I've then got it plugged into the Maven JavaDoc plugin to have it build the TLD files via the javadoc:javadoc Maven goal. Pom portion that handles this is as follows:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<doclet>org.tldgen.TldDoclet</doclet>
<docletArtifact>
<groupId>com.google.code.tldgen</groupId>
<artifactId>tldgen-all</artifactId>
<version>1.0.0</version>
</docletArtifact>
<show>private</show>
<additionalparam>-name test
-uri "http://www.mycompany.com/tags/wibble"
-tldFile ..\..\..\src\main\resources\META-INF\w.tld
</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
<author>false</author>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
And this works fantastically. Trouble is that I know want to create 2 TLD's from this project. I can pass a -subpackages attribute in th addtionalparam element so I can produce a TLD with exactly what I want.
But I can only have one configuration element at that point. I've tried moving the configuration into the reporting section in my pom with two reportsets to see if that helps but no luck.
Has anyone ever attempted this before and can help point me in the right direction for getting it right? Cheers!
It's been a while since this question was posted, but here's how I did multiple tld generation with TLDGen. I started from your question, since the guys over at the project used your answer as a reference :).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<includes>
<include>**</include>
</includes>
<doclet>org.tldgen.TldDoclet</doclet>
<docletArtifacts>
<!-- listing all dependencies for tldgen:
the tldgen library, commons-logging, commons-io,
commons-lang, geronimo-jsp_2.1_spec, log4j, saxon, stax
not sure if they have to be listed here, will have to check; if I
don't set them I get class not found errors, but I'm guessing I
have a misconfiguration -->
</docletArtifacts>
<show>private</show>
<additionalparam>
-htmlFolder ${basedir}/target/docs
-tldFolder ${basedir}/src/main/java/META-INF
-license NONE
</additionalparam>
<useStandardDocletOptions>true</useStandardDocletOptions>
<author>false</author>
<encoding>utf-8</encoding>
</configuration>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jsr173_api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
</executions>
</plugin>

Resources