Spring-boot: Support Java 9

Created on 26 Oct 2016  路  26Comments  路  Source: spring-projects/spring-boot

Spring Boot master (2.0.0.BUILD-SNAPSHOT) doesn't currently build with JDK9, see the dedicated job

  • [x] AgentAttacher does not work on JDK9 #9139
  • [x] Antlib support is broken with JDK9 #9140
  • [x] ModifiedClassPathRunner is broken with JDK9 #9142
enhancement

Most helpful comment

@juanmbellini There are multiple ways to fix this issue but I preferred explicitly declaring these dependencies in my project.

    <jaxb.version>2.3.0</jaxb.version>
    <jaxws.version>2.3.0</jaxws.version>

and

      <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>${javax-annotation.version}</version>
      </dependency>
      <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>${jaxb.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>${jaxb.version}</version>
      </dependency>
      <dependency>
        <groupId>javax.xml.ws</groupId>
        <artifactId>jaxws-api</artifactId>
        <version>${jaxws.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>${jaxws.version}</version>
      </dependency>

As you stated these modules are part of java ee and will be removed in the future. In the future you will need to definitely add these dependencies.

I have not tested in a detailed way but spring boot 1.5.x seems working with JDK9 as well. Please note that I have not added module info files yet. I had just added some dependencies.

All 26 comments

The current build doesn't exhibit the same issue. I'll investigate that a bit more.

We need to find a different way to extract the default values for the meta-data as we're using a proprietary API.

java.lang.IllegalAccessException: class org.springframework.boot.configurationprocessor.fieldvalues.javac.Trees cannot access class com.sun.tools.javac.api.JavacTrees (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @5a7fe64f
[ERROR] /Users/snicoll/workspace/pivotal/spring-boot/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/tunnel/server/RemoteDebugPortProvider.java:[51,43] cannot find symbol
  symbol:   class VMSupport
  location: package sun.misc

java.lang.IllegalAccessException: class org.springframework.boot.configurationprocessor.fieldvalues.javac.Trees cannot access class com.sun.tools.javac.api.JavacTrees (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @5a7fe64f

Yikes, this might be an issue. It might be worth asking on the JDK mailing list if there's any official way to do this.

I've created a thread on jigsaw-dev about this.

There are also additional runtime issues (see #7565 for more details)

LaunchedURLClassLoaderTests#resolveFromNested does not work with Java9 since nested.jar!/3.dat isn't identified as a valid resource anymore. I haven't found any information about this yet.

IJ also (wrongly) refuses to compile SignalUtils. I've reported IDEA-167758

LaunchedURLClassLoaderTests#resolveFromNested fails because org.springframework.boot.loader.jar.Handler isn't being used. This is the class that we configure to be the URLStreamHandler for jar: URLs. Unfortunately, this due to an optimisation for jar:file: URLs. It creates a java.util.jar.JarFile directly from a File rather than going via a JarURLConnection. Similar logic appears to be in Java 8 so it's not yet clear why the behaviour has changed.

This commit introduced the change in behaviour. The optimisation I described above is in JarLoader. That's what's used in Java 9 due to this change. In Java 8 and earlier a Loader is used.

Issue for the Loader-related regression: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8174151

The JDK issue has been fixed and the two tests are passing now. We have more issues down the road but I think it is related to the maven plugin we're using. I am going to review that with the latest ea

It looks like we're affected by https://github.com/cglib/cglib/issues/93~~

Actually we're not adding the proper version of Spring Framework in our integration tests. That's #8947

Ok we're further now. Next is we need to switch to Maven assembly plugin 3.0.1 but we need to make the release happen first. I am on it.

Friendly ping :). What's the status of this?

Will Spring boot 1.5.x support java 9 ?

@douglarek No

@robinst The status is all on this page. The issue is open and scheduled for 2.0 M5.

Don't know if this comment should be here or where, but I have just upgrade to java 9 and couldn't run a Spring Boot Application.
This is a Spring Boot Application using Jersey, Data and Security starters.

First of all the following was printed in the console when trying to run the app.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by ...to field ...
WARNING: Please consider reporting this to the maintainers of  org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Then the app didn't start, printing the following stacktrace

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer]: Factory method 'resourceConfigCustomizer' threw exception; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlElement
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 57 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlElement
    at com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector.<init>(JaxbAnnotationIntrospector.java:139)
    at com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector.<init>(JaxbAnnotationIntrospector.java:126)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer$ObjectMapperCustomizer.addJaxbAnnotationIntrospector(JerseyAutoConfiguration.java:266)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer$ObjectMapperCustomizer.access$200(JerseyAutoConfiguration.java:262)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer.addJaxbAnnotationIntrospectorIfPresent(JerseyAutoConfiguration.java:258)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer.resourceConfigCustomizer(JerseyAutoConfiguration.java:244)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer$$EnhancerBySpringCGLIB$$a15c1d0c.CGLIB$resourceConfigCustomizer$0(<generated>)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer$$EnhancerBySpringCGLIB$$a15c1d0c$$FastClassBySpringCGLIB$$3126cdea.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
    at org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration$JacksonResourceConfigCustomizer$$EnhancerBySpringCGLIB$$a15c1d0c.resourceConfigCustomizer(<generated>)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 58 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlElement
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:466)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:563)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:94)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
    ... 74 common frames omitted

Making some research on google I found that Java EE modules must be explicitly included, so I created the module-info.java file, including the corresponding module. But after that, any class of Spring couldn't be located.

@juanmbellini There are multiple ways to fix this issue but I preferred explicitly declaring these dependencies in my project.

    <jaxb.version>2.3.0</jaxb.version>
    <jaxws.version>2.3.0</jaxws.version>

and

      <dependency>
        <groupId>javax.annotation</groupId>
        <artifactId>javax.annotation-api</artifactId>
        <version>${javax-annotation.version}</version>
      </dependency>
      <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>${jaxb.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>${jaxb.version}</version>
      </dependency>
      <dependency>
        <groupId>javax.xml.ws</groupId>
        <artifactId>jaxws-api</artifactId>
        <version>${jaxws.version}</version>
      </dependency>
      <dependency>
        <groupId>com.sun.xml.ws</groupId>
        <artifactId>jaxws-rt</artifactId>
        <version>${jaxws.version}</version>
      </dependency>

As you stated these modules are part of java ee and will be removed in the future. In the future you will need to definitely add these dependencies.

I have not tested in a detailed way but spring boot 1.5.x seems working with JDK9 as well. Please note that I have not added module info files yet. I had just added some dependencies.

spring support java 9 ,It will take some time to support! so wait wait wait.....

One important piece at this point is to update AspectJ as 1.9 is not GA yet and is definitely required to run with Java 9

<aspectj.version>1.9.0.BETA-7</aspectj.version>

(available from repo.spring.io/milestone)

Unless we manage to get a workaround, it looks like there is a bug in Maven that prevents us to property test with Java9. I've opened SUREFIRE-1424.

Liquibase does not work with Java9 yet. I've created CORE-3114

With well identified limitations the build now passes with Java 9. I've started a wiki page to gathers some of the gotchas.

@juanmbellini you can try by adding the modules.

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <jvmArguments>--add-modules java.xml.bind,java.xml.ws,java.xml.ws.annotation</jvmArguments>
  </configuration>
</plugin>
Was this page helpful?
0 / 5 - 0 ratings