0

I'm trying to create a WS REST using Dropwizard for getting a Hive result of a query and presenting in XML format. Each separated part of this could be done without error.

When I joined everything I reach a incompatibility between Dropwizard and hive-jdbc. Apparently hive-jdbc has jersey 1 as dependency and Dropwizard has jersey 2.

I'm not sure if this is the problem. I'd tried to exclude dependency in pom.xml, but didn't solve.

I tried to make an application just putting hive-jdbc as dependency in pom.xml file without using or importing in any part of the code, and the error still happening.

POM.XML

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <prerequisites>
        <maven>3.0.0</maven>
    </prerequisites>

    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>ws-test</artifactId>
    <version>1.0.0</version>
    <name>ws-test</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <dropwizard.version>1.0.5</dropwizard.version>
        <mainClass>test.TestApp</mainClass>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.dropwizard</groupId>
                <artifactId>dropwizard-bom</artifactId>
                <version>${dropwizard.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard</groupId>
            <artifactId>dropwizard-forms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-core</artifactId>
            <version>1.2.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.1</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <transformers>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>${mainClass}</mainClass>
                        </transformer>
                    </transformers>
                    <!-- exclude signed Manifests -->
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>${mainClass}</mainClass>
                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

TestApp.java

package test;

import io.dropwizard.Application;
import io.dropwizard.forms.MultiPartBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;

public class TestApp extends Application<TestConf> {

    public static void main(String[] args){
        try {
            new TestApp().run(args);
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getName() {
        return "ID Generator Server";
    }

    @Override
    public void initialize(final Bootstrap<TestConf> bootstrap) {
        bootstrap.addBundle(new MultiPartBundle());
    }

    @Override
    public void run(final TestConf configuration,
                    final Environment environment) {
        final TestRes resource = new TestRes(
                configuration.getTemplate(),
                configuration.getDefaultName()
            );
            environment.jersey().register(resource);
    }

}

TestConf.java

package test;

import io.dropwizard.Configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.hibernate.validator.constraints.*;

public class TestConf extends Configuration {

    @NotEmpty
    private String template;

    @NotEmpty
    private String defaultName = "MarineTraffic";

    @JsonProperty
    public String getTemplate() {
        return template;
    }

    @JsonProperty
    public void setTemplate(String template) {
        this.template = template;
    }

    @JsonProperty
    public String getDefaultName() {
        return defaultName;
    }

    @JsonProperty
    public void setDefaultName(String name) {
        this.defaultName = name;
    }
}

TestRes.java

package test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Path("/hive")
public class TestRes {

    protected final static Logger LOGGER = LoggerFactory.getLogger(TestRes.class);
    protected final static String HEADER = "GroupService::";

    public TestRes(String template, String defaultName) {
        LOGGER.info(HEADER + "init: PostConstruct");
    }

    @GET
    @Path("/test")
    @Produces(MediaType.TEXT_PLAIN)
    public String getNewID() {

        return "works";
    }
}

The error I got was like:

WARN  [2017-08-10 21:50:21,444] org.glassfish.jersey.internal.Errors: The following warnings have been detected: WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 2
java.lang.NullPointerException
    at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.setConfiguration(AbstractJAXBProvider.java:107)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
    at test.TestApp.main(TestApp.java:12)
MultiException stack 2 of 2
java.lang.IllegalStateException: Unable to perform operation: method inject on com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:392)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
...

WARNING: Unknown HK2 failure detected:
MultiException stack 1 of 3
java.lang.NullPointerException
    at com.sun.jersey.core.provider.jaxb.AbstractJAXBProvider.setConfiguration(AbstractJAXBProvider.java:107)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
    at test.TestApp.main(TestApp.java:12)
MultiException stack 2 of 3
java.lang.IllegalStateException: Unable to perform operation: method inject on com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:392)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
...
    at test.TestApp.main(TestApp.java:12)
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.message.internal.MessageBodyFactory
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:386)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
...

I found that some users are getting similar error (as dropwizard and hive/hiverunner integration with maven and http://thread.gmane.org/gmane.comp.java.dropwizard.devel/461)

Is this (incompatibility in Jersey) the problem that is causing the error? Does anyone knows how to solve it?

Caio
  • 45
  • 9
  • Look at the maven shade plugin. – Software Engineer Aug 10 '17 at 22:02
  • I'd tried to add exclusion clause in maven-shade-plugin configuration for removing jersey-server, which maven complained of incompatibility. however, nothing changes. – Caio Aug 10 '17 at 22:09
  • Shade allows you to rewrite package names and references to them -- so you can rewrite the packages in, say, jersey1, and the references to them in hive-jdbc, and that may help you solve your problem. See: https://stackoverflow.com/questions/13620281/what-is-the-maven-shade-plugin-used-for-and-why-would-you-want-to-relocate-java . Shade is designed to allow you to solve the problem of having to depend on incompatible libraries. If that's your problem, then this may fix it. But, this looks a lot like reflection, which means ymmv. – Software Engineer Aug 11 '17 at 07:38

1 Answers1

1

Yup, its jersey conflict issue, exclude jersey 1 dependencies (com.sun.jersey) from both hive-jdbc and hadoop-core. Had ran your test application and it worked with below exclusions.

 <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-jdbc</artifactId>
        <version>1.1.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jersey</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-core</artifactId>
        <version>1.2.1</version>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jersey</groupId>
                <artifactId>*</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
Ravi
  • 912
  • 6
  • 12
  • Lol. Thanks a lot. I didn't realized that hadoop-core also uses jersey. That what I was missing. Now is working perfectly. I still can't understand why hive driver and hadoop core needs to use a jersey server. – Caio Aug 11 '17 at 17:53