Java 9, Hibernate and java.sql/javax.transaction - java

I've tried to "upgrade" a project using Hibernate to Java 9, but I am having problems getting the module to function properly.
The relevant part of my module-info.java looks like this:
module test {
...
requires java.base;
requires hibernate.core;
requires javax.transaction;
requires java.sql;
}
and the relevant dependencies in my POM are
org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec, 2.0.0.Alpha1
org.hibernate:hibernate-core, 5.2.12.Final
javax.transaction:javax.transaction-api, 1.2
The problem is, if I run the program, I get a NoClassDefFoundError for javax.transaction.SystemException. I looked into this, and quite obviously, my module is missing a requires on javax.transaction.
So I add a module dependency on javax.transaction-api. I then go on and attempt to run the program again - now I'm missing java.sql.SQLException.
Here is what I am having a problem with: if I add a dependency on the module java.sql, which contains this class, I end up with a conflict:
module reads package javax.transaction.xa from both java.sql and javax.transaction.api
java.sql and javax.transaction.api contain different packages, and have one in common (javax.transaction.xa), but I require all of them.
How do I deal with this? Is there something simple I am missing?

Use version 1.3 instead of 1.2 of javax.transaction-api, in this version javax.transaction.xa has been removed.
Maven dependency:
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.3</version>
</dependency>

Related

java 11 and spring boot error: this_class should be module-info

I have created a simple Spring boot application, and I'm trying to move it to a newer jdk version. My plan was to use jlink and distribute it as a complete package. But I'm getting this error:
this_class should be module-info
When I try to compile it with maven. If I remove the module-info it works (and it generates the self contained jar as expected). Am I missing something else?
module-info.java:
module operations {
requires static lombok;
requires commons.beanutils;
requires opencsv;
requires commons.net;
requires spring.data.mongodb;
requires spring.data.commons;
requires java.validation;
requires org.mongodb.bson;
requires spring.web;
requires spring.context;
requires spring.core;
requires spring.boot;
requires spring.beans;
requires org.apache.logging.log4j;
requires spring.context.support;
requires java.mail;
requires thymeleaf;
requires org.apache.commons.lang3;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires java.annotation;
requires org.apache.commons.collections4;
requires spring.boot.autoconfigure;
requires java.ws.rs;
requires spring.security.core;
requires spring.messaging;
requires spring.websocket;
requires java.management;
requires spring.security.web;
requires org.apache.tomcat.embed.core;
requires spring.security.config;
requires java.security.sasl;
exports com.testapp.operations;
}
project structure:
src/main/java/
...module-info.java
.../com/testapp/operations/(all classes)
pom.xml
The issue seems to be in certain dependencies which prevents the module from compiling correctly. In my case the problem was with the cglib library on the classpath (maven dependency):
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
In my case the solution was to update the library to latest version 3.3.0
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
The best way to find the offending library is to comment out the dependencies one by one and run the build after each such action. Once the code compiles correctly the problematic libary is identified. Try updating it or, if there is no update avilable, exclude it.
If exclusion is not an option, the possible solutionis to extract the code using the library to the separate module. This new module could be compiled as automatic module (without module-info.java).

How to add Spark dependencies in spring-boot multi module Java 11 project

Whenever I am adding a module-info.java in my multi-module project I cannot import my Spark dependencies - everything else seems to be working
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.0.0-preview2</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.12</artifactId>
<version>3.0.0-preview2</version>
</dependency>
IntelliJ tries to readd Maven Dependency without any result.
My module-info looks like:
module common {
exports [...]
requires lombok;
requires spring.data.jpa;
requires spring.data.commons;
requires org.apache.commons.lang3;
requires spring.context;
requires spring.web;
requires spring.security.core;
requires com.google.common;
requires org.json;
requires spring.core;
requires spring.beans;
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires spring.jcl;
requires spring.webmvc;
requires mongo.java.driver;
requires org.hibernate.orm.core;
requires com.fasterxml.jackson.dataformat.csv;
requires java.sql;
}
It is not possible to add org.apache.* in my module-info.java either.
Is it possible that Spark is not ready for Jigsaw modules and Java 9+?
Is it possible that spark is not ready for Jigsaw modules and Java 9+?
It does hold true for spark. Two straight reasons that I can vouch for are:
They do not have an entry for
Automatic-Module-Name: <module-name>
in the artifact's MANIFEST.MF file.
If you try describing their artifacts using the jar tool
jar --describe-module --file=<complete-path>/spark-core_2.12-3.0.0-preview2.jar
This would fail to derive the module descriptor for a similar reason as mentioned in this answer.
Few resources that might be useful once you reach here:
The reason why deriving automatic module name fails for spark artifacts
A way to update a jar manually with the MANIFEST entry
Spark's progress to Build and Run on JDK-11

Java 9 ORMLite conflict in module-info

I have a Java 9 (or higher) project in which I want to include ORMLite with a H2 database. Therefore I need the two maven dependencies
<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-core</artifactId>
<version>5.1</version>
</dependency>
<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-jdbc</artifactId>
<version>5.1</version>
</dependency>
...
(+ the h2 dependency.)
Since I am using Java 9 I have to add them to my module-info.java:
module my.module {
exports my.package.to.export;
requires ormlite.core;
requires ormlite.jdbc;
...
But now I cannot compile the project anymore because both core and jdbc have the same package com.j256.ormlite.db.
[ERROR] module ormlite.core reads package com.j256.ormlite.db from both ormlite.core and ormlite.jdbc
I understand that this is as it should be, because split packages are not allowed. But how do I handle this, since this is not within my power? At least not in a clean way. I want to keep everything in maven and dont want to combine the packages as suggested in another post.
How can I solve this clean?
(I see that this is already an open issue in the orm-lite Github, but I do want to use it now)

package com.fasterxml.jackson.annotation is not visible

When I compile my Spring Boot application in Java 9, it fails after a couple of messages such as this one:
package com.fasterxml.jackson.annotation is not visible
(package com.fasterxml.jackson.annotation is declared in the unnamed module, but module com.fasterxml.jackson.annotation does not read it)
Can someone tell me what is going on here? As I understand it, any pre-Java 9 code not in a Java-9 module will be part of the unnamed module where anything is exposed.
I'm using this as an annotation like this in my module:
#JsonIgnore
public Week getNextWeek()
{
Calendar instance = this.getFirstDay();
instance.set(Calendar.WEEK_OF_YEAR, this.week + 1);
return new Week(instance);
}
So if this is the case with the com.fasterxml.jackson.annotation package, why is the error referring to a module with that name, and why is it a problem that it does not read it?
Quoting from the JigSaw Spec:
The unnamed module exports all of its packages. This enables flexible migration, as we shall see below. It does not, however, mean that code in a named module can access types in the unnamed module. A named module cannot, in fact, even declare a dependence upon the unnamed module.
What you're looking for are Automatic Modules. In automatic modules, a jar can be placed on the module path and will automatically derive the module name from the jar itself. In case you're using Maven, that should be the artifactId.
As such, if you are using jackson-annotations in maven as following:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.0.0</version>
</dependency>
You'd still require to define it inside your module-info.java:
module example {
requires jackson.annotations;
}
After that, you're free to use the annotations within your module.

Java9 Multi-Module Maven Project Test Dependencies

I have a multi-module maven project with three modules core, utils and test-utils
Core has the following dependencies definition
<dependency>
<groupId>my.project</groupId>
<artifactId>utils</artifactId>
</dependency>
<dependency>
<groupId>my.project</groupId>
<artifactId>test-utils</artifactId>
<scope>test</scope>
</dependency>
I have added Java 9 module-info.java definitions for all three modules and core's looks like this:
module my.project.core {
requires my.project.utils;
}
However I cannot figure out how to get core's test classes to be able to see the test-utils classes during test execution. When maven-surefire-plugin attempts the test run I get class not found.
If I add a requires my.project.testutils; to core's module-info.java:
module my.project.core {
requires my.project.utils;
requires my.project.testutils; //test dependency
}
Then at compile time I get an error that the my.project.testutils module can't be found (presumably because it's only brought in as a test dependency).
How does one work with test dependencies in a Java 9 modular world? For obvious reason's I don't want my main code to pull in test dependencies. Am I missing something?
With maven and java9, if your my.project.testutils is a test scope dependency, you don't need to explicitly include(requires) it in the module descriptor.
The test dependencies are taken care via the classpath itself. So you can simply remove the testutils and it would be patched by maven while executing tests.
module my.project.core {
requires my.project.utils;
}
Refer to the slide 30 pertaining to maven-compiler-plugin.
I would also suggest you take a look at Where should I put unit tests when migrating a Java 8 project to Jigsaw and this comment by Robert confirming on the implementation that maven follows.
Edit: Created a sample project drawing an analogy that the main module is same as your core, the dependency on guava is same as your utils and the junit dependency is same as your testutils.

Categories

Resources