2017-03-01 27 views
3

当使用OpenSAML 3,您必须从opensaml-saml-impl神器第一负载元件与下面的代码行:如何堵塞opensaml-IMPL类型的java.util.ServiceLoader初始化停止Maven的遮阳帘插件

InitializationService.initialize(); 

This uses java.util.ServiceLoader to load any type which implements Initializer

当我写一个测试,并与mvn integration-test运行它,这工作得很好,我可以看到,一切都已经加载:

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

然而,我的项目使用maven-shade-plugin。如果我的代码打包成一个超级-罐的条件以上是真:

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

在这种情况下,我观​​察到只有9 unmarshallers已加载(那些在opensaml-core,而不是那些在opensaml-saml-impl然而,当我看的mvn package输出,我可以看到包括在阴影罐子类型:

[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相关位:

<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> 
+0

不要为'META-INF/services'使用'AppendingTransformer',你可以使用['ServicesResourceTransformer'](https://maven.apache.org/plugins/maven-shade-plugin/examples/资源transformers.html#ServicesResourceTransformer)。这可能是问题。您是否在“META-INF/services”下检查了胖JAR中的内容? – Tunaki

+0

只要将'AppendingTransformer'改为'ServicesResourceTransformer',就会出现错误:无法解析mojo org.apache.maven.plugins的配置:maven-shade-plugin:3.0.0:参数变换器的阴影:无法加载实现提示org .apache.maven.plugins.shade.resource.ServiceResourceTransformer'。 (也尝试更新以遮蔽3.0)我误解你了吗?对阴影我很天真,对不起! –

+0

你刚刚在'Services'(而不是'Service')中错过了's'。而且你也不需要它下面的''元素。 – Tunaki

回答

4

如果您使用的是与使用ServiceLoader API的依赖Maven的阴影插件,你应该使用ServicesResourceTransformer,这是专门为一起合并文件。如果插件是relocating classes,则它也将正确地重新定位每个服务文件中的类名称,与AppendingTransformer不同。

所以,你可以只是

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

替换当前AppendingTransformer这将确保您的依赖META-INF/services下的每个服务文件合并,而不需要声明它们。