如何阻止Maven-shade-plugin阻止opensaml-impl类型的java.util.ServiceLoader初始化 [英] How to stop maven-shade-plugin from blocking java.util.ServiceLoader initialization of opensaml-impl types

查看:86
本文介绍了如何阻止Maven-shade-plugin阻止opensaml-impl类型的java.util.ServiceLoader初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用OpenSAML 3时,必须首先使用以下代码行从opensaml-saml-impl项目中加载组件:

When using OpenSAML 3, you must first load components from the opensaml-saml-impl artifact with the following line of code:

InitializationService.initialize();

使用java.util.ServiceLoader加载实现了 .

当我编写测试并使用mvn integration-test运行它时,它工作正常,并且可以看到所有内容都已加载:

When I write a test and run it with mvn integration-test, this works fine, and I can see that everything has loaded:

Assert.assertTrue(
    XMLObjectProviderRegistrySupport
        .getUnmarshallerFactory()
        .getUnmarshallers()
        .size() > 400);

但是,我的项目使用的是maven-shade-plugin.如果我将代码打包到uber-jar中,则上述条件为 not true:

However, my project uses maven-shade-plugin. The condition above is not true if I package the code into an uber-jar:

mvn package
java -jar /path/to/my.jar

在这种情况下,我观​​察到仅加载了9个解组器(opensaml-core中的解组器,与opensaml-saml-impl中的解组器相反.但是,当我观察mvn package的输出时,我可以看到类型包括在阴影罐中:

In this case I observe that only 9 unmarshallers have loaded (those in opensaml-core, as opposed to those in opensaml-saml-impl. However, when I watch the output of mvn package, I can see that the types are included in the shaded jar:

[INFO] Including org.opensaml:opensaml-saml-impl:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-profile-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-messaging-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-saml-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-xmlsec-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-soap-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-storage-api:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-security-impl:jar:3.2.0 in the shaded jar.
[INFO] Including org.opensaml:opensaml-security-api:jar:3.2.0 in the shaded jar.

我可以使用以下哑代码解决此问题:

I can work around this issue with the following dumb code:

private static void initManuallyInsteadOfWithInitializationServiceSoThatMavenShadePluginDoesNotRemoveThem() throws InitializationException {
    new ApacheXMLSecurityInitializer().init();
    new ClientTLSValidationConfiguratonInitializer().init();
    new GlobalAlgorithmRegistryInitializer().init();
    new GlobalParserPoolInitializer().init();
    new GlobalSecurityConfigurationInitializer().init();
    new JavaCryptoValidationInitializer().init();
    new SAMLConfigurationInitializer().init();
    new org.opensaml.core.xml.config.XMLObjectProviderInitializer().init();
    new org.opensaml.xmlsec.config.XMLObjectProviderInitializer().init();
    new XMLObjectProviderInitializer().init();
}

这完全打败了插件系统,但确实允许我的程序运行.

This utterly defeats the point of the plugin system, but it does allow my program to function.

作为参考,这是pom.xml的相关位:

For reference, here's the relevant bits of pom.xml:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <manifestEntries>
                            <Main-Class>com.example.Server</Main-Class>
                        </manifestEntries>
                    </transformer>
                    <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/services/io.vertx.core.spi.VerticleFactory</resource>
                    </transformer>
                </transformers>
                <artifactSet>
                </artifactSet>
                <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
                </outputFile>
                <filters>
                    <filter>
                        <!-- Fix java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
                             when server starts inside Docker container due to inclusion of OpenSAML and use of
                             uber-jar / maven-shade-plugin. See http://stackoverflow.com/a/6743609 -->
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                    <filter>
                        <!-- This was one of my attempts to fix the problem.
                             Unfortunately, it doesn't work. -->
                        <artifact>org.opensaml:opensaml-saml-impl</artifact>
                        <includes>
                            <include>**</include>
                        </includes>
                    </filter>
                </filters>
            </configuration>
        </execution>
    </executions>
</plugin>

推荐答案

使用带有ServiceLoader API的依赖关系的Maven Shade插件时,应使用重定位类,它将还可以在中正确地重新定位每个服务文件中的类名.

When you're using the Maven Shade Plugin with dependencies using the ServiceLoader API, you should use the ServicesResourceTransformer, which is dedicated to merge together the files. If the plugin is relocating classes, it will also relocate properly the class names in each service file, unlike the AppendingTransformer.

因此,您只需将当前的AppendingTransformer替换为

So you can just replace your current AppendingTransformer with

<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>

这将确保合并依赖项中META-INF/services下的每个服务文件,而无需全部声明它们.

It will make sure that every service file under META-INF/services of your dependencies are merged, without the need to declare them all.

这篇关于如何阻止Maven-shade-plugin阻止opensaml-impl类型的java.util.ServiceLoader初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆