Reputation: 45732
I have module-info.java
file that looks like:
module server {
...
// split package issue: lot of java classes within packages with the same name
requires hbase.common;
requires hbase.client;
...
}
Problem can't be solved by maven-shader-plugin
, because it doesn't know groupId, only package name. Means shader will rename the same packages from both: hbase.common
and hbase.client
- split package problem remains.
I also tried to create some shader
middlelayer module, to throw away unneeded packages and resolve split package issue. But this solution also does not work.
shader/module-info.java:
module shader {
requires hbase.common;
// exports only packages I do need at my code. Shade unneded packages
// IS THERE ANY WAY TO MAKE IT WORK?
// Got: X module reads package org.apache.hadoop.hbase.util from both shader and hbase.common
exports org.apache.hadoop.hbase.util;
}
server/module-info.java
module server {
requires shader;
requires hbase.client;
}
Are there any Maven plugins for combining split-package jars?
Upvotes: 3
Views: 3232
Reputation: 45732
Important this approach does not work when the same package exposes different classes from different modules and both of them are required. It only works if different packages are used, so you can filter-out packages from conflicting JARs.
So, the problem - two dependencies (maybe transitive) with the same package name. It's not compatible with JMPS and failfast during compilation. The solution of this problem is to manually (with maven-shade-plugin)exclude conflicting packages from one of the dependencies.
maven-shade-plugin has per-class or per-package include/exclude functionality. Here is documentation.
The problem was that this approach doesn't work at first glance. If you will put the plugin at the same pom.xml
where you imported both conflicting JARs - compilation will fail due "module X reads package org.apache.hadoop.hbase.util from both hbase.client and hbase.common "
. JPMS is run at compilation phase (before package phase where plugin is launched). Here is an example:
server/
|-src/
| |-main/
| |-java/
| |-com.somapackage
| |-module-info.java
| [
| module server {
| requires java.base;
| requires hbase.common; //they have lots of conflicting packages
| requires hbase.client; //they have lots of conflicting packages
| }
| ]
|-pom.xml
[
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>${hbase.common.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>${hbase.client.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<filters>
<filter>
<artifact>org.apache.hbase:hbase-client</artifact>
<excludes>
<exclude>org/apache/hadoop/hbase/util/ **</exclude>
</excludes>
</filter>
<filter>
<artifact>org.apache.hbase:hbase-common</artifact>
<includes>
<include>org/apache/hadoop/hbase/util/ **</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
]
To make JPMS split package validation work after shading we have to move conflicting dependencies to separate submodule. Moreover, we have to manually resolve packages conflict (exclude the same package from one dependency and include into another dependency) - that means we have to create to different sumbodules: shader1
and shader2
. Here is the code:
server/
|-src/
| |-main/
| |-java/
| |-com.somapackage
| |-module-info.java
| [
| module server {
| requires java.base;
| requires shader1;
| requires shader2;
| }
| ]
|-pom.xml
[
<dependency>
<groupId>com.organization.proj</groupId>
<artifactId>shader1</artifactId>
<version>${proj.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/../shader/target/shader1-0.0.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.organization.proj</groupId>
<artifactId>shader2</artifactId>
<version>${proj.version}</version>
<scope>system</scope>
<systemPath>${project.basedir}/../shader2/target/shader2-0.0.1.jar</systemPath>
</dependency>
]
|
|
shader1
|-src/
| |-main/
| |-java/
| |-com.somapackage
| |-module-info.java
| [
| module shader1 {
| requires java.base;
| requires transitive hbase.client;
| }
| ]
|-pom.xml
[
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>${hbase.client.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<filters>
<filter>
<artifact>org.apache.hbase:hbase-client</artifact>
<excludes>
<exclude>org/apache/hadoop/hbase/util/ **</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
]
|
|
shader2
|-src/
| |-main/
| |-java/
| |-com.somapackage
| |-module-info.java
| [
| module shader2 {
| requires java.base;
| requires transitive hbase.common;
| }
| ]
|-pom.xml
[
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>${hbase.common.version}</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<filters>
<filter>
<artifact>org.apache.hbase:hbase-common</artifact>
<includes>
<include>org/apache/hadoop/hbase/util/ **</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
]
require transitive
at shader submodulesUpvotes: 2