3
votes

The Java 9 application I am building compiles and works well from IntelliJ IDE. On IDE, I have tried configuring as both Spring Boot application as well as plain Application and both configuration work well.

While executing maven build, I encounter RuntimeException with below stacktrace.

Caused by: java.lang.RuntimeException
    at org.springframework.asm.ClassVisitor.visitModule(ClassVisitor.java:148)
    at org.springframework.asm.ClassReader.readModule(ClassReader.java:762)
    at org.springframework.asm.ClassReader.accept(ClassReader.java:663)
    at org.springframework.asm.ClassReader.accept(ClassReader.java:527)
    at org.springframework.boot.loader.tools.MainClassFinder.createClassDescriptor(MainClassFinder.java:267)
    at org.springframework.boot.loader.tools.MainClassFinder.doWithMainClasses(MainClassFinder.java:223)
    at org.springframework.boot.loader.tools.MainClassFinder.findSingleMainClass(MainClassFinder.java:203)
    at org.springframework.boot.loader.tools.Repackager.findMainMethod(Repackager.java:365)
    at org.springframework.boot.loader.tools.Repackager.findMainMethodWithTimeoutWarning(Repackager.java:354)
    at org.springframework.boot.loader.tools.Repackager.buildManifest(Repackager.java:325)
    at org.springframework.boot.loader.tools.Repackager.repackage(Repackager.java:255)
    at org.springframework.boot.loader.tools.Repackager.repackage(Repackager.java:248)
    at org.springframework.boot.loader.tools.Repackager.repackage(Repackager.java:193)
    at org.springframework.boot.maven.RepackageMojo.repackage(RepackageMojo.java:221)
    at org.springframework.boot.maven.RepackageMojo.execute(RepackageMojo.java:208)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    ... 22 more

On analyzing, its being caused because of the ASM api level provided. With direct execution, it is org.springframework.asm.Opcodes#ASM6, but when using maven build it is Opcodes#ASM4 which is causing the issue.

Further analysis reveals that the instances are created as below - Maven Build - https://github.com/spring-projects/spring-boot/blob/d3c34ee3d1bfd3db4a98678c524e145ef9bca51c/spring-boot-project/spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/MainClassFinder.java#L301

IDE Execution - https://github.com/spring-projects/spring-framework/blob/43b5e21947f3ad9682ae39cd8b8b5ae4b8f72c14/spring-core/src/main/java/org/springframework/core/type/classreading/ClassMetadataReadingVisitor.java#L71

Let me know if I need to report this as an issue with Spring Framework or if any workarounds exist.

Maven Version: 3.5.0

Spring Boot: 2.0.0.M5

Its a modular build and POM files are here: https://gist.github.com/techpavan/faa81d46321004cd50e7403b03d70a2e

A simpler reproducer is available here - https://github.com/techpavan/java9-maven-spring-boot

With this reproducer, you can find that maven build fails readily. But when put a breakpoint at org.springframework.asm.ClassVisitor > line 78 (Constructor) and update the api value during execution to 393216 (ASM6), you'll find that the build completes successfully. By default the value is set to 262144 (ASM4) which fails at line 147.

Update: The issue is accepted as bug by Spring community and should be fixed in Milestone 6 release - https://github.com/spring-projects/spring-boot/issues/10647

Update: The issue is fixed in the spring-boot master branch on Oct 17, 2017. Should be a part of M6 release.

2
What version of maven? what dependencies and what command of execution? good if you share pom.xml. The question has very less information as of now. Why would the execution differ unless you've manually modified some configuration on either of the platforms? And to add to it ASM_6.x is compatible with Java9 and no other version prior to it. - Naman
@nullpointer Updated Maven and spring boot versions in the question. All latest. Dependencies include guava and commons-lang3, but switched to Jetty instead of Tomcat. Apart from these, I have some exclusions to resolve issues like module M reads package x.y from both M1 and M2 resolved here - stackoverflow.com/questions/44697738/… Is there any way we can force Maven build to use ASM_6 ? - Pavan Kumar
That's the latest milestone release - github.com/spring-projects/spring-boot/releases Updated the question with POM file details - Pavan Kumar

2 Answers

4
votes

Your mvn dependency:tree describes it as follows:-

➜[main] [INFO] +- org.springframework.boot:spring-boot-starter-jetty:jar:2.0.0.M5:compile
 [main] [INFO] |  +- org.eclipse.jetty:jetty-servlets:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty:jetty-continuation:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty:jetty-http:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty:jetty-util:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  \- org.eclipse.jetty:jetty-io:jar:9.4.7.v20170914:compile
 [main] [INFO] |  +- org.eclipse.jetty:jetty-webapp:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty:jetty-xml:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  \- org.eclipse.jetty:jetty-servlet:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |     \- org.eclipse.jetty:jetty-security:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |        \- org.eclipse.jetty:jetty-server:jar:9.4.7.v20170914:compile
 [main] [INFO] |  +- org.eclipse.jetty.websocket:websocket-server:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty.websocket:websocket-common:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  |  \- org.eclipse.jetty.websocket:websocket-api:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty.websocket:websocket-client:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  |  \- org.eclipse.jetty:jetty-client:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  \- org.eclipse.jetty.websocket:websocket-servlet:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |     \- javax.servlet:javax.servlet-api:jar:3.1.0:compile
 [main] [INFO] |  +- org.eclipse.jetty.websocket:javax-websocket-server-impl:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  +- org.eclipse.jetty:jetty-annotations:jar:9.4.7.v20170914:compile
 [main] [INFO] |  |  |  +- org.eclipse.jetty:jetty-plus:jar:9.4.7.v20170914:compile
➜[main] [INFO] |  |  |  +- org.ow2.asm:asm:jar:5.1:compile
 [main] [INFO] |  |  |  \- org.ow2.asm:asm-commons:jar:5.1:compile
 [main] [INFO] |  |  |     \- org.ow2.asm:asm-tree:jar:5.1:compile

This clearly reflects that the dependency on spring-boot-starter-jetty for your project relies on asm:5.1 and the version of asm is not compatible with the latest Java release. You can try upgrading to 6.0_BETA version of it.


To what I got to know from this issue, jetty didn't upgrade to the latest version because of its incompatibility with OSGI version number. I'd faced that issue while trying to make vaadin8 application work with Java 9 wherein the solution I could achieve was to build jetty locally and then use a custom version in my project as stated in the answer -

This was attained after overcoming the #jetty.project/1758 by upgrading to the 6.0_BETA of asm and asm-commons libraries and using the custom 9.4.7-SNAPSHOT built on my local used in the project(commit - #e34415.)


Update: This indeed is a bug in spring-boot milestone as confirmed in the edited question as well.

0
votes

Thanks to wilkinsona on GitHub whose workaround helped me on this issue. Just adding a spring-boot-maven-plugin configuration with mainClass entry can solve this problem on M5 release. Expected to have a proper fix on M6.

         <plugin>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-maven-plugin</artifactId>
+            <configuration>
+                <mainClass>com.test.TestMain</mainClass>
+            </configuration>
         </plugin>