Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to package an Apache CXF application into a monolithic JAR with the Maven "shade" plugin

I am writing a console-based Java application, intended to be run by cron in a batch-processing manner. The batch-processing application makes calls to a SOAP web service, using the Apache CXF framework for JAX-WS.

To make deployment easier, and to prevent CLASSPATH issues, I would like to bundle up the application (with all its dependencies) into a single monolithic JAR file... using the "shade" plugin for Maven.

My application works just fine when I run it from my Eclipse workspace. However, when I try executing the shaded JAR file I get a stacktrace such as the following:

org.apache.cxf.service.factory.ServiceConstructionException: Could not resolve a binding for null 
            at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createBindingInfo(AbstractWSDLBasedEndpointFactory.java:404) 
            at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpointInfo(AbstractWSDLBasedEndpointFactory.java:258) 
            at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:146) 
            at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:52) 
            at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:102) 
            at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:115) 
            at com.example.gui.domain.Session.getService(Session.java:145) 
            at com.example.gui.domain.service.soap.AbstractServiceImpl.<init>(AbstractServiceImpl.java:23) 
            at com.example.gui.domain.service.soap.GetUserConsoleOrgsImpl.<init>(GetUserConsoleOrgsImpl.java:14) 
            at com.example.gui.domain.service.ServiceFactory.getGetUserConsoleOrgsService(ServiceFactory.java:443) 
            at com.example.gui.domain.AccessManager.getOrgs(AccessManager.java:62) 
            at com.example.gui.windows.ConsoleApplet.login (ConsoleApplet.java:1253) 
            at com.example.gui.windows.ConsoleApplet.init(ConsoleApplet.java:1227) 
            at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) 
            at java.lang.Thread.run(Unknown Source) 
Caused by: org.apache.cxf.BusException: No binding factory for namespace http://schemas.xmlsoap.org/soap/ registered. 
            at org.apache.cxf.binding.BindingFactoryManagerImpl.getBindingFactory(BindingFactoryManagerImpl.java:91) 
            at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createBindingInfo(AbstractWSDLBasedEndpointFactory.java:394) 
            ... 14 more 
java.lang.NullPointerException 
            at com.example.gui.domain.service.soap.GetUserConsoleOrgsImpl.getUserConsoleOrgs(GetUserConsoleOrgsImpl.java:29) 
            at com.example.gui.domain.AccessManager.getOrgs(AccessManager.java:64) 
            at com.example.gui.windows.ConsoleApplet.login (ConsoleApplet.java:1253) 
            at com.example.gui.windows.ConsoleApplet.init(ConsoleApplet.java:1227) 
            at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) 
            at java.lang.Thread.run(Unknown Source) 

In fact, if you check out this discussion board message, I'm having the exact same problem that this guy is having. As another person pointed out in that that thread, my issue is probably with the Maven "shade" plugin.

Apache CXF consists of numerous JAR file dependencies, and apparently more than one of those JAR's rely on contents within their META-INF directories. The Maven "shade" plugin is apparently collapsing all those META-INF directories into one, and overwriting necessary files rather than merging them together.

Someone in that discussion thread provided a link to this Maven POM file, showing that there are config options and transformers for making the "shade" plugin merge these CXF dependencies properly. I plugged these these settings into my own POM, like so:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>1.4</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.example.MainClass</mainClass>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer">
                        <projectName>Apache CXF</projectName>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/services/com.sun.tools.xjc.Plugin</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/cxf/cxf.extension</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/extensions.xml</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/cxf/extensions.xml</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/cxf/bus-extensions.txt</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/cxf/bus-extensions.xml</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/wsdl.plugin.xml</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/tools.service.validator.xml</resource>
                    </transformer>
                    <transformer implementation="org.apache.cxf.maven.PluginTransformer">
                        <resource>META-INF/tools-plugin.xml</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                        <resource>META-INF/cxf/java2wsbeans.xml</resource>
                    </transformer>
                    <transformer implementation="org.apache.cxf.maven.CXFAllTransformer" />
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

However, I can't find any real explanation for what these settings are doing... and I get the following error when running Maven with debug output enabled:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:14.357s
[INFO] Finished at: Tue Jul 26 11:10:43 EDT 2011
[INFO] Final Memory: 18M/59M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:1.4:shade (default) on project salestax-poster: Unable to parse configuration of mojo org.apache.maven.plugins:maven-shade-plugin:1.4:shade: ClassNotFoundException: Class name which was explicitly given in configuration using 'implementation' attribute: 'org.apache.cxf.maven.PluginTransformer' cannot be loaded -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:1.4:shade (default) on project salestax-poster: Unable to parse configuration of mojo org.apache.maven.plugins:maven-shade-plugin:1.4:shade: ClassNotFoundException: Class name which was explicitly given in configuration using 'implementation' attribute: 'org.apache.cxf.maven.PluginTransformer' cannot be loaded
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:221)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
...

It seems to complain that it can't find the org.apache.cxf.maven.PluginTransformer class, which seems to exist in the cxf-buildtools package. However, when I add that package to the POM's dependencies, I get yet another error in the build process:

Jul 26, 2011 10:44:02 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.apache.cxf.bus.spring.BusApplicationContext@3aa42c31: display name [org.apache.cxf.bus.spring.BusApplicationContext@3aa42c31]; startup date [Tue Jul 26 10:44:02 EDT 2011]; root of context hierarchy
Jul 26, 2011 10:44:02 AM org.apache.cxf.bus.spring.BusApplicationContext getConfigResources
INFO: No cxf.xml configuration file detected, relying on defaults.
Jul 26, 2011 10:44:02 AM org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.apache.cxf.bus.spring.BusApplicationContext@3aa42c31]: org.springframework.beans.factory.support.DefaultListableBeanFactory@47fe1e26
Jul 26, 2011 10:44:02 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@47fe1e26: defining beans [cxf,org.apache.cxf.bus.spring.BusApplicationListener,org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor,org.apache.cxf.bus.spring.Jsr250BeanPostProcessor,org.apache.cxf.bus.spring.BusExtensionPostProcessor,org.apache.cxf.resource.ResourceManager,org.apache.cxf.configuration.Configurer,org.apache.cxf.binding.BindingFactoryManager,org.apache.cxf.transport.DestinationFactoryManager,org.apache.cxf.transport.ConduitInitiatorManager,org.apache.cxf.wsdl.WSDLManager,org.apache.cxf.phase.PhaseManager,org.apache.cxf.workqueue.WorkQueueManager,org.apache.cxf.buslifecycle.BusLifeCycleManager,org.apache.cxf.endpoint.ServerRegistry,org.apache.cxf.endpoint.ServerLifeCycleManager,org.apache.cxf.endpoint.ClientLifeCycleManager,org.apache.cxf.transports.http.QueryHandlerRegistry,org.apache.cxf.endpoint.EndpointResolverRegistry,org.apache.cxf.headers.HeaderManager,org.apache.cxf.catalog.OASISCatalogManager,org.apache.cxf.endpoint.ServiceContractResolverRegistry]; root of factory hierarchy
[DEBUG] 
java.lang.AbstractMethodError: org.apache.xerces.dom.ElementNSImpl.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object;
    at org.apache.cxf.tools.validator.internal.Stax2DOM.startElement(Stax2DOM.java:173)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:135)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:95)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:76)
    at org.apache.cxf.tools.validator.internal.WSDL11Validator.getWSDLDoc(WSDL11Validator.java:91)
    at org.apache.cxf.tools.validator.internal.WSDL11Validator.isValid(WSDL11Validator.java:111)
    at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.validate(JAXWSDefinitionBuilder.java:201)
    at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.validate(JAXWSDefinitionBuilder.java:61)
    at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:132)
    at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:238)
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:83)
    at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:103)
    at org.apache.cxf.maven_plugin.WSDL2JavaMojo.processWsdl(WSDL2JavaMojo.java:360)
    at org.apache.cxf.maven_plugin.WSDL2JavaMojo.execute(WSDL2JavaMojo.java:257)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Jul 26, 2011 10:44:03 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.apache.cxf.bus.spring.BusApplicationContext@3aa42c31: display name [org.apache.cxf.bus.spring.BusApplicationContext@3aa42c31]; startup date [Tue Jul 26 10:44:02 EDT 2011]; root of context hierarchy
Jul 26, 2011 10:44:03 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@47fe1e26: defining beans [cxf,org.apache.cxf.bus.spring.BusApplicationListener,org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor,org.apache.cxf.bus.spring.Jsr250BeanPostProcessor,org.apache.cxf.bus.spring.BusExtensionPostProcessor,org.apache.cxf.resource.ResourceManager,org.apache.cxf.configuration.Configurer,org.apache.cxf.binding.BindingFactoryManager,org.apache.cxf.transport.DestinationFactoryManager,org.apache.cxf.transport.ConduitInitiatorManager,org.apache.cxf.wsdl.WSDLManager,org.apache.cxf.phase.PhaseManager,org.apache.cxf.workqueue.WorkQueueManager,org.apache.cxf.buslifecycle.BusLifeCycleManager,org.apache.cxf.endpoint.ServerRegistry,org.apache.cxf.endpoint.ServerLifeCycleManager,org.apache.cxf.endpoint.ClientLifeCycleManager,org.apache.cxf.transports.http.QueryHandlerRegistry,org.apache.cxf.endpoint.EndpointResolverRegistry,org.apache.cxf.headers.HeaderManager,org.apache.cxf.catalog.OASISCatalogManager,org.apache.cxf.endpoint.ServiceContractResolverRegistry]; root of factory hierarchy
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.152s
[INFO] Finished at: Tue Jul 26 10:44:03 EDT 2011
[INFO] Final Memory: 10M/59M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.cxf:cxf-codegen-plugin:2.2:wsdl2java (generate-sources) on project salestax-poster: org.apache.xerces.dom.ElementNSImpl.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object; -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.cxf:cxf-codegen-plugin:2.2:wsdl2java (generate-sources) on project salestax-poster: org.apache.xerces.dom.ElementNSImpl.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object;
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoExecutionException: org.apache.xerces.dom.ElementNSImpl.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object;
    at org.apache.cxf.maven_plugin.WSDL2JavaMojo.processWsdl(WSDL2JavaMojo.java:363)
    at org.apache.cxf.maven_plugin.WSDL2JavaMojo.execute(WSDL2JavaMojo.java:257)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: java.lang.AbstractMethodError: org.apache.xerces.dom.ElementNSImpl.setUserData(Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object;
    at org.apache.cxf.tools.validator.internal.Stax2DOM.startElement(Stax2DOM.java:173)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:135)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:95)
    at org.apache.cxf.tools.validator.internal.Stax2DOM.getDocument(Stax2DOM.java:76)
    at org.apache.cxf.tools.validator.internal.WSDL11Validator.getWSDLDoc(WSDL11Validator.java:91)
    at org.apache.cxf.tools.validator.internal.WSDL11Validator.isValid(WSDL11Validator.java:111)
    at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.validate(JAXWSDefinitionBuilder.java:201)
    at org.apache.cxf.tools.wsdlto.frontend.jaxws.wsdl11.JAXWSDefinitionBuilder.validate(JAXWSDefinitionBuilder.java:61)
    at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:132)
    at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:238)
    at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:83)
    at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:103)
    at org.apache.cxf.maven_plugin.WSDL2JavaMojo.processWsdl(WSDL2JavaMojo.java:360)
    ... 22 more

Has anyone ever used Apache CXF in the context of a Maven shaded JAR, and can provide some guidance as to how you make this work properly?

like image 208
Steve Perkins Avatar asked Jul 26 '11 14:07

Steve Perkins


3 Answers

In my case I needed to add only:

<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
     <resource>META-INF/cxf/bus-extensions.txt</resource>
</transformer>

If you take a look at this file with and without transformer tag there is a big difference (only one line vs ~50 lines), in particular lines:

org.apache.cxf.binding.soap.SoapBindingFactory::true
org.apache.cxf.binding.soap.SoapTransportFactory::true

are missing which I believe is causing the problem.

like image 92
Eugen Avatar answered Nov 20 '22 21:11

Eugen


The solution is to add the dependency for cxf-buildtools to the plugin element.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
        <version>1.4</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>## you name class name ##</mainClass>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/spring.handlers</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/spring.schemas</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/services/com.sun.tools.xjc.Plugin</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/cxf.extension</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/extensions.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/extensions.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.txt</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/bus-extensions.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/wsdl.plugin.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/tools.service.validator.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.cxf.maven.PluginTransformer">
                                <resource>META-INF/tools-plugin.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                                <resource>META-INF/cxf/java2wsbeans.xml</resource>
                            </transformer>
                            <transformer implementation="org.apache.cxf.maven.CXFAllTransformer" />
                        </transformers>
                        <shadedArtifactAttached>true</shadedArtifactAttached>
                        <shadedClassifierName>executable</shadedClassifierName>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-buildtools</artifactId>
                    <version>2.2.12</version>
                    <type>jar</type>
                    <scope>compile</scope>
                </dependency>
            </dependencies>
        </plugin>
like image 34
Corneil du Plessis Avatar answered Nov 20 '22 22:11

Corneil du Plessis


I solved the problem, more or less.

The Maven "shade" plugin comes with the concept of "transformers", which enable you to merge conflicting files together in the monolithic JAR rather than having one overwrite the other. There are different types of transformers... with the most common being:

  • org.apache.maven.plugins.shade.resource.AppendingTransformer -- simply appends one text file onto the end of another
  • org.apache.maven.plugins.shade.resource.XmlAppendingTransformer -- appends XML together while keeping the format sane

In my above POM snippet, I had taken a list of transformers from the example provided in that discussion board thread. It included two transformers that were NOT part of the default "shade" plugin out-of-the-box:

  • org.apache.cxf.maven.PluginTransformer
  • org.apache.cxf.maven.CXFAllTransformer

Apparently, these two are CXF-specific add-ons which do not come with the "shade" plugin, but must be provided separately by CXF JAR's.

My "solution" is incomplete, because I have not been able to work out how to get those dependencies in place. They seem to be part of the cxf-buildtools Maven dependency package... but as the above question documents, I've encountered problems no matter how I try to insert that dependency into my POM.

However, practically speaking my solution has been to simply remove those two transformers from the "shade" plugin configuration altogether. My shaded JAR application works perfectly fine without them. Perhaps those two specific transformers have a role in special edge cases, but for vanilla CXF service calls it appears that you can omit them.

like image 3
Steve Perkins Avatar answered Nov 20 '22 22:11

Steve Perkins