如何阻止maven-shade-plugin阻止opensaml-impl类型的java.util.ServiceLoader初始化

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

 InitializationService.initialize(); 

这使用java.util.ServiceLoader来加载任何实现Initializer类型 。

当我编写测试并使用mvn integration-test运行它时,这很好用,我可以看到所有内容都已加载:

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

但是,我的项目使用maven-shade-plugin 。 如果我将代码打包到超级jar中,则上述条件正确:

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

在这种情况下,我观​​察到只有9个unmarshallers已经加载(那些在opensaml-core ,而不是那些在opensaml-saml-impl 。但是,当我观察mvn package的输出时,我可以看到类型包含在阴影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. 

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

 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(); } 

这完全违背了插件系统的要点,但它确实允许我的程序运行。

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

  org.apache.maven.plugins maven-shade-plugin 2.3   package  shade      com.example.Server    META-INF/services/io.vertx.core.spi.VerticleFactory     ${project.build.directory}/${project.artifactId}-${project.version}-fat.jar     *:*  META-INF/*.SF META-INF/*.DSA META-INF/*.RSA     org.opensaml:opensaml-saml-impl  **        

当您使用ServiceLoader API将Maven Shade插件与依赖项一起使用时,您应该使用ServicesResourceTransformer ,它专用于将文件合并在一起。 如果插件重定位类 ,它还将正确地重新定位每个服务文件中的类名,这与AppendingTransformer不同。

所以你可以用你的当前AppendingTransformer替换

  

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