2

I'm writing a client (library) to consume a REST service in order to give users of the library simple get and set methods to work with, hiding complexities of REST APIs.

I'm using jackson 2.4.0 and jersey 2.6 to consume the REST service.

The goal is to create a uber.jar which will be a self-contained jar file with all the dependencies resolved. To achieve this, I'm using Maven shade plugin. i'm also relocating all the dependent classes using the shade plugin.

My pom file is as below :

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <jackson.version>2.4.0</jackson.version>
    <jersey.version>2.6</jersey.version>
</properties>

<build>
    <plugins>
    <!-- Shade plugin -->
        <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>
                        <relocations>
                            <relocation>
                                <pattern>org</pattern>
                                <shadedPattern>shaded.org</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>com</pattern>
                                <shadedPattern>shaded.com</shadedPattern>
                                <excludes>
                                    <exclude>com.example.*</exclude>
                                </excludes>
                            </relocation>
                            <relocation>
                                <pattern>javax</pattern>
                                <shadedPattern>shaded.javax</shadedPattern>
                                <excludes>
                                    <exclude>javax.xml.*</exclude>
                                </excludes>
                            </relocation>
                            <relocation>
                                <pattern>jersey</pattern>
                                <shadedPattern>shaded.jersey</shadedPattern>
                            </relocation>
                            <relocation>
                                <pattern>javassist</pattern>
                                <shadedPattern>shaded.javassist</shadedPattern>
                            </relocation>
                        </relocations>
                        <transformers>                      
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                <resource>META-INF/.*</resource>                                    
                            </transformer>
                        </transformers>                     
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!-- Shade plugin -->
    </plugins>
</build>

<dependencies>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>${jersey.version}</version>
    </dependency>


    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.3.2</version>
    </dependency>
</dependencies>

If i write a test class within the same project in which this library is, everything works fine. But, if i when i use this shaded library in a separate standalone project (which is what the goal is), i get following exception :

Feb 06, 2015 5:28:07 PM shaded.org.glassfish.hk2.internal.ServiceLocatorFactoryImpl getGenerator
WARNING: Cannot find a default implementation of the HK2 ServiceLocatorGenerator
Feb 06, 2015 5:28:08 PM shaded.org.glassfish.jersey.internal.Errors logErrors
WARNING: The following warnings have been detected: WARNING: HK2 service reification failed for [shaded.org.glassfish.jersey.message.internal.DataSourceProvider] with an exception:
MultiException stack 1 of 2
java.lang.NoClassDefFoundError: shaded/javax/activation/DataSource
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
    at java.lang.Class.getDeclaredConstructors(Unknown Source)
    at shaded.org.jvnet.hk2.internal.Utilities$7.run(Utilities.java:1316)
    at shaded.org.jvnet.hk2.internal.Utilities$7.run(Utilities.java:1312)
    at java.security.AccessController.doPrivileged(Native Method)
    at shaded.org.jvnet.hk2.internal.Utilities.getAllConstructors(Utilities.java:1312)
    at shaded.org.jvnet.hk2.internal.Utilities.findProducerConstructor(Utilities.java:1233)
    at shaded.org.jvnet.hk2.internal.DefaultClassAnalyzer.getConstructor(DefaultClassAnalyzer.java:78)
    at shaded.org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:143)
    at shaded.org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:203)
    at shaded.org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:147)
    at shaded.org.jvnet.hk2.internal.ClazzCreator.initialize(ClazzCreator.java:200)
    at shaded.org.jvnet.hk2.internal.SystemDescriptor.internalReify(SystemDescriptor.java:649)
........
........
Caused by: java.lang.ClassNotFoundException: shaded.javax.activation.DataSource
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 65 more
MultiException stack 2 of 2
java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
    implementation=shaded.org.glassfish.jersey.message.internal.DataSourceProvider
    contracts={shaded.javax.ws.rs.ext.MessageBodyWriter,shaded.javax.ws.rs.ext.MessageBodyReader}
    scope=shaded.javax.inject.Singleton
    qualifiers={}
    descriptorType=CLASS
    descriptorVisibility=NORMAL
    metadata=
    rank=0
    loader=shaded.org.glassfish.hk2.utilities.binding.AbstractBinder$2@4fb64261
    proxiable=null
    proxyForSameScope=null
    analysisName=null
    id=10
    locatorId=1
    identityHashCode=1113619023
    reified=false)
    at shaded.org.jvnet.hk2.internal.SystemDescriptor.reify(SystemDescriptor.java:615)
    at shaded.org.jvnet.hk2.internal.ServiceLocatorImpl.reifyDescriptor(ServiceLocatorImpl.java:405)
    at shaded.org.jvnet.hk2.internal.ServiceLocatorImpl.narrow(ServiceLocatorImpl.java:2046)
    at shaded.org.jvnet.hk2.internal.ServiceLocatorImpl.access$700(ServiceLocatorImpl.java:116)
    at shaded.org.jvnet.hk2.internal.ServiceLocatorImpl$8.compute(ServiceLocatorImpl.java:1207)
    at shaded.org.jvnet.hk2.internal.ServiceLocatorImpl$8.compute(ServiceLocatorImpl.java:1202)

Any help will be appreciated.

Thanks.

Adhyatmik
  • 1,038
  • 11
  • 19
  • `java.lang.ClassNotFoundException` is thrown on Runtime when requested class is not available in classpath. [This](http://en.wikipedia.org/wiki/Classpath_(Java)) will shed some light to java and classpath. – FrAn Feb 06 '15 at 13:24
  • I found the issue : because of use of `javax` in my pom to relocate classes, the shade plugin was even relocating the java language classes **!!** I had to individually relocate the library classes by including their specific packages for eg. `javax.annotation.security` instead of `javax`. There seems to be no other around it, as sadly, element does not take a regex. – Adhyatmik Feb 08 '15 at 19:31
  • I have a similar question. https://stackoverflow.com/questions/54586595/building-an-osgi-plugin-bundlewith-transitive-dependencies-using-maven-on-ecli Can you help? – Hariny Murli Feb 08 '19 at 05:51

0 Answers0