使用 Maven Shade 构建应用程序 jar 时,排除所有 META-INF/versions directories/files 是否安全?

When building an application jar with Maven Shade, is it safe to exclude all META-INF/versions directories/files?

我相信版本文件夹可以支持多个 Java 版本。我们总是为一个非常具体的版本(此时是 11)构建。在创建我们的单个应用程序 jar 时排除那些 directories/files 是否有危险? 例如

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<configuration>
    <transformers>
        <transformer
            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${start-class}</mainClass>
            <manifestEntries>
                <Class-Path>./</Class-Path>
                <Implementation-Version>${ourSoftware.revision}</Implementation-Version>
            </manifestEntries>
        </transformer>
    </transformers>
    <filters>
        <filter>
            <artifact>*:*</artifact>

            <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>

                <exclude>META-INF/versions/**</exclude> <!-- IS THIS SAFE? -->
            </excludes>
        </filter>
    </filters>
    <finalName>${project.artifactId}App</finalName>
</configuration>
<executions>
    <execution>
        <phase>package</phase>
        <goals>
            <goal>shade</goal>
        </goals>
    </execution>
</executions>

谢谢!

是的,这些版本文件夹用于支持多版本 Jar 文件(参见 JEPS 238)。

如果您在 MANIFEST.MF[=23= 中明确地将 multi-release 属性设置为 false ] 文件。

工作原理如下:

In a JDK that does not support MRJARs, only the classes and resources in the root directory will be visible, and the two packagings will be indistinguishable. In a JDK that does support MRJARs, the directories corresponding to any later Java platform release would be ignored; it would search for classes and resources first in the Java platform-specific directory corresponding to the currently-running major Java platform release version, then search those for lower versions, and finally the JAR root. On a Java 9 JDK, it would be as if there were a JAR-specific class path containing first the version 9 files, and then the JAR root; on a Java 8 JDK, this class path would contain only the JAR root. (Ref: JEPS 238)

这种基于版本的打包机制会选择性地忽略非相关版本的文件夹,即使里面有内容。禁用该机制应该解决忽略所有版本文件夹(如果它们存在)并且如果它们不存在则完全回退到 JEPS 238 之前存在的行为。