2017-03-01 43 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下的每個服務文件合併,而不需要聲明它們。