Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Maven shade plugin remove module-info.class?

I try to use maven-shade-plugin for a modular jar:

<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>
        </execution>
    </executions>
    <configuration>
        <minimizeJar>true</minimizeJar>
        <artifactSet>
            <includes>
                <include>javax.xml.bind:jaxb-api</include>
                <include>com.sun.xml.bind:jaxb-impl</include>
            </includes>
        </artifactSet>
        <relocations>
            <relocation>
                <pattern>javax.xml.bind</pattern>
                <shadedPattern>org.update4j.javax.xml.bind</shadedPattern>
            </relocation>
            <relocation>
                <pattern>com.sun.xml.bind</pattern>
                <shadedPattern>org.update4j.com.sun.xml.bind</shadedPattern>
            </relocation>
        </relocations>
    </configuration>
</plugin>

But Maven will remove my module-info.class from the shaded jar, with a warning:

[WARNING] Discovered module-info.class. Shading will break its strong encapsulation.

How can I configure it to leave it?

EDIT: the warning actually happens when it removes the shaded jar's module descriptor, not my own.

like image 395
Mordechai Avatar asked Aug 08 '18 16:08

Mordechai


People also ask

What does the maven shade plugin do?

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

What is module info class?

module-info. It declares the dependencies within the module system and allows the compiler and the runtime to police the boundaries/access violations between the modules in your application.

What does shaded mean in Maven?

Together literally it means "jar-over-all-other-jars". "Shading" is the same as "package reallocation" which is needed for classes or resources that collide. – dma_k.

What is a dependency reduced POM?

The dependency-reduced-pom. xml removes transitive dependencies which are already in your shaded jar. This prevents consumers from pulling them in twice.


1 Answers

Because of module-info's in the JPMS world dictate the exposure of a module, shading items in may cause that nasty "Package is read from two different modules" error.

I've solved it the following way

  • Shading in, filtering out module-info across all modules
  • Then adding in the module-info (which may or may not be valid, THANK YOU MODITECT, you have no idea how useful that is)
  <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <configuration>
          <artifactSet>
            <excludes>
              <exclude>module-info.java</exclude>
            </excludes>
          </artifactSet>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.moditect</groupId>
        <artifactId>moditect-maven-plugin</artifactId>
        <executions>
          <execution>
            <id>add-module-infos</id>
            <phase>package</phase>
            <goals>
              <goal>add-module-info</goal>
            </goals>
            <configuration>
              <overwriteExistingFiles>true</overwriteExistingFiles>
              <module>
                <moduleInfoFile>
                  src/main/java/module-info.java
                </moduleInfoFile>
              </module>
            </configuration>
          </execution>
        </executions>
      </plugin>

This is a really annoying thing, and from everything I've read they have no intention of removing it or adding a flag to bypass it.

like image 182
Marc Magon Avatar answered Oct 22 '22 02:10

Marc Magon