6

I've been trying to run Hibernate 5.2.11 application in Java 9/Spring Boot 1.5.x/Maven project but I'm failing at missing class:

Caused by: java.lang.NoClassDefFoundError: javax/transaction/SystemException
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:375)
    at org.jboss.logging.Logger$1.run(Logger.java:2554)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2529)
    at org.jboss.logging.Logger.getMessageLogger(Logger.java:2516)
    at org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:28)
    at org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:24)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<clinit>(EntityManagerFactoryBuilderImpl.java:115)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:54)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 33 more

Has anyone encountered this exception and knows a workaround? I tried adding --add-modules for javax.bind or java.se.ee but they didn't help.

The above error shows in a mavan-failsafe (2.20.1) integration test that starts Spring context with Hibernate. Application doesn't have any Java 9 specific code.

Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
  • 1
    I uses failsafe 2.20.1 – Krzysztof Krasoń Oct 01 '17 at 18:52
  • 3
    I don't know anything about the failsafe plugin but there was a recent change to the surefire plugin where it was changed to use `--add-modules java.se.ee`, exactly the wrong thing when trying to override a standard module with the Java EE version of the component. There is an issue tracking this for the surefire plugin ( https://issues.apache.org/jira/browse/SUREFIRE-1424). – Alan Bateman Oct 01 '17 at 19:46
  • @AlanBateman Thanks, strangely it fails with javax.xml.bind in case of 2.20 (and 2.19.1) although I have `--add-modules java.xml.bind` added – Krzysztof Krasoń Oct 02 '17 at 07:33
  • The only way I got this to work is after reading Alan's comment. – Tom Silverman Nov 01 '17 at 17:20
  • The only way I got this to work on 9+181 with maven is after reading Alan's comment and downgrading maven surefire plugin from 2.20.1 to 2.20 but I still need a maven dependency on javax.xml.bind:jaxb-api:2.2.11. The Eclipse (Oxygen 1a) JUnit plugin, by the way, could run my test once java.se.ee module was added to the explicitly included modules pane in the java build path dialog that opens once editing "Is Modular" in the JRE System library 9 tree. – Tom Silverman Nov 01 '17 at 17:27

2 Answers2

3

According to the migration guide and the java docs, since the module java.transaction which exports the package javax.transaction has been marked as @Deprecated.

You should ideally migrate your code to be using javaee/javax.transaction instead. Currently, you can do so using automatic module converted from the dependency:

<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>javax.transaction-api</artifactId>
    <version>1.2</version>
</dependency>

and adding to the module-info.java the following:-

requires javax.transaction.api;

Additionally while using the maven-failsafe-plugin, make sure you are using the minimum compatible version 2.20.1 or above as mentioned in the progress document of Maven.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.20.1</version>
</plugin>

@Deprecated(forRemoval="after OP's confirmation")

On the other hand, a temporary workaround (since eventually these modules will be removed from the JDK) could be to make use of:-

--add-modules java.transaction

As mentioned in the comments, since the required dependency for javax.transaction-api is already available on the classpath, you shouldn't be required to add any compiler option or else you would end up overriding the current package with the java.transaction module's exported javax.transaction package which ideally for your use case doesn't consist of SystemException.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • I get the same error with that dependency (and empty `--add-modules`) – Krzysztof Krasoń Oct 01 '17 at 18:02
  • I don't add any module, I just to run application that works on Java 8, to run on Java 9. – Krzysztof Krasoń Oct 01 '17 at 18:04
  • 1
    @KrzysztofKrasoń It's not your specific code, but Java 9, that marks the feature as deprecated. – Naman Oct 01 '17 at 18:08
  • `--add-modules java.transaction` doesn't help (as the one from JDK doesn't have SystemException at all) – Krzysztof Krasoń Oct 01 '17 at 19:05
  • 1
    @KrzysztofKrasoń If that's the case, the ideal solution should be to migrate to the javaee/javax.transaction artifact as mentioned in the answer. – Naman Oct 01 '17 at 19:08
  • Actually I'm using that dependency already (it is a transitive one from other dependencies), and when I add it I see the same error, when I create module-info.java and add requires I get a lot of error messages `is declared in the unnamed module, but module `, I'm reluctant in fixing those (100 errors) to finally findout that it didn't help either. – Krzysztof Krasoń Oct 01 '17 at 19:11
  • @KrzysztofKrasoń If that's the case, what happens when you don't use the compiler option as well as no requires? Are you able tom import the SystemException then? – Naman Oct 01 '17 at 19:14
  • 1
    Yes, project compiles fine when I do `import javax.transaction.SystemException` (passes compile, testCompile, tests phases, fails on integration-test phase) – Krzysztof Krasoń Oct 01 '17 at 19:22
  • 1
    In which case that should solve your issue since the package with SystemException is already available on your classpath. Adding `--add-modules` would override the package with its own implementation which doesn't have the desired class. – Naman Oct 01 '17 at 19:24
0

This is what I think: --add-modules java.se.ee according to Modules Shared with Java EE Not Resolved by Default will resolve all Java EE modules, used for resolving internal APIs. Therefore, developers don't need to add specific module one by one. On the other side, JDK9 is also separating EE from SE. javax.transaction.SystemException is no longer in JDK9 library, but it is in EE library. As in java.se.ee module-info:

@SuppressWarnings({"deprecation", "removal"})
@Deprecated(since="9", forRemoval=true)
module java.se.ee {

    requires transitive java.se;

    // Upgradeable modules for Java EE technologies
    requires transitive java.activation;
    requires transitive java.corba;
    requires transitive java.transaction;
    requires transitive java.xml.bind;
    requires transitive java.xml.ws;
    requires transitive java.xml.ws.annotation;

}

But for module java.transaction it has only: InvalidTransactionException, TransactionRequiredException, TransactionRolledbackException

Community
  • 1
  • 1
Tiina
  • 4,285
  • 7
  • 44
  • 73