Unable to connect to Elastic Search - java

I am building a simple REST API which queries ElasticSearch. I am not using the ElasticSearch REST API way rather than I am using the TCP way.
My goal is to make REST API using spring boot which will communicate with ElasticSearch via TCP.
I am using ElasticSearch sever 5.6
I have a ElasticSearchClientFactory which contains the code to establish connection with ElasticSearch server.
ElasticSearchClientFactory.java ' buildClient
void buildClient() {
Settings settings = Settings.builder().put("cluster.name", elasticSearchProperties.getClusterName()).build();
TransportClient transportClient = new PreBuiltTransportClient(settings);
if (!StringUtils.isEmpty(elasticSearchProperties.getHostname())
&& !StringUtils.isEmpty(elasticSearchProperties.getPort() + "")) {
try {
transportClient.addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName(elasticSearchProperties.getHostname()),
elasticSearchProperties.getPort()));
transportClient.connectedNodes();
this.client = transportClient;
} catch (UnknownHostException e) {
LOGGER.error("Unable to Connect to ElasticSearch,UnknownHost" + elasticSearchProperties.getHostname());
}
} else {
LOGGER.error("Missing ElasticSearch configuration hostname and portNumber");
throw new DataAccessException(CommonConstants.DAE001, "Unable to connect to ElasticSearch");
}
}
pom.xml contains following related dependencies related to ElasticSearch
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.5.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.5.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
Following logs printing at server startup-
2017-09-14 16:52:28:840 search org.springframework.boot.SpringApplication [main] ERROR - Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticSearchClientFactory' defined in file [D:\projects\verizon\mesh_workspace\search\target\classes\com\sapient\mesh\productlisting\config\ElasticSearchClientFactory.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: io.netty.util.internal.ObjectUtil.checkPositive(ILjava/lang/String;)I
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:732)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)
at com.sapient.mesh.SearchApplication.main(SearchApplication.java:20)
Caused by: java.lang.NoSuchMethodError: io.netty.util.internal.ObjectUtil.checkPositive(ILjava/lang/String;)I
at io.netty.util.NettyRuntime$AvailableProcessorsHolder.setAvailableProcessors(NettyRuntime.java:44)
at io.netty.util.NettyRuntime.setAvailableProcessors(NettyRuntime.java:87)
at org.elasticsearch.transport.netty4.Netty4Utils.setAvailableProcessors(Netty4Utils.java:82)
at org.elasticsearch.transport.netty4.Netty4Transport.<init>(Netty4Transport.java:138)
at org.elasticsearch.transport.Netty4Plugin.lambda$getTransports$0(Netty4Plugin.java:93)
at org.elasticsearch.client.transport.TransportClient.buildTemplate(TransportClient.java:174)
at org.elasticsearch.client.transport.TransportClient.<init>(TransportClient.java:265)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:130)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:116)
at org.elasticsearch.transport.client.PreBuiltTransportClient.<init>(PreBuiltTransportClient.java:106)
at com.sapient.mesh.productlisting.config.ElasticSearchClientFactory.buildClient(ElasticSearchClientFactory.java:62)
at com.sapient.mesh.productlisting.config.ElasticSearchClientFactory.afterPropertiesSet(ElasticSearchClientFactory.java:53)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
... 16 common frames omitted

In java NoSuchMethodError usually tells that you have multiple instances of same library (or sometime you have only one, but it's a wrong one).
If I were you I would:
check maven tree with mvn dependency:tree -Dverbose. In the tree you going to see 2 instances of same library (probably 2 different versions). You need to manually exclude a dependency in pom.xml from the entry that has this lib as a dependency. Well, sometime extra lib can come from a server (e.g. glassfish) instead of maven, in that case check below.
Put a breakpoint to NettyRuntime.java:44, connect in a debug mode and when you hit it, evaluate the path of wrong library. To evaluate the path you need to ask a classLoader where the lirary is located. You can do this, evaluate code in debug mode*. (io.netty.util.internal.ObjectUtil class.getClassLoader()).getResource("io.netty.util.internal.ObjectUtil.class")) this will provide you a path to a library, from that point you would know what you need to exclude and where it came from
*Evaluate code or Evaluate expression is an option that should be available in debug mode in your IDE (Eclipse/Jetbrains/Netbeans or w/e you use, should support it)

Related

ElasticSearch AbstractMethodError while making client

I am trying to make an elastic search transport client, but getting below error
Caused by: java.lang.AbstractMethodError:
org.elasticsearch.transport.TcpTransport.sendMessage(Ljava/lang/Object;Lorg/elasticsearch/common/bytes/BytesReference;Ljava/lang/Runnable;)V
at
org.elasticsearch.transport.TcpTransport.internalSendMessage(TcpTransport.java:1111)
at
org.elasticsearch.transport.TcpTransport.sendRequestToChannel(TcpTransport.java:1093)
at
org.elasticsearch.transport.TcpTransport.executeHandshake(TcpTransport.java:1600)
Here is my code :
Settings settings = Settings.builder()
.put("cluster.name", "elasticsearch")
.put("node.name", "node1").build();
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
Is this a dependency issue?
I got stuck on this. You can't mix dependency versions.
Turned out I was using spring-data-elasticsearch in one project that depended on another project that had the plain elasticsearch dependency. These included differing versions and caused that error.
That was not fun to track down.
It is a dependency issue. In maven pom, i have below dependencies
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.6.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.6.3</version>
</dependency>
I have removed the dependency of org.elasticsearch, and it is running fine.

Spring Boot JNDI not found - can't compile WAR with Maven

i can't mvn clean install my project.
I need to use a remote JNDI in WAR(not jar), but having the name in application.properties throws error during mvn clean install(due to "datasource jndi name not found")
if I have to use jndi name from a remote server, that I have no control over, how do i compile my package in WAR without lookup fail, but let it look up during the deployment/installation of the app on the server? any hint, or direction is very much appreicated...
in app prop, i have
spring.datasource.jndi-name=jdbc/ff-app
I have tried: Spring boot JNDI datasource lookup failure - Name comp/env/jdbc not found in context "java:"
tried, http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-connecting-to-a-jndi-datasource
and pretty much every questions asked in stackoverflow about a remote jndi..
Some of the errors:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'jdbc/ff-app'; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
... 69 common frames omitted
Caused by: org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'jdbc/ff-app'; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:48) ~[spring-jdbc-4.3.6.RELEASE.jar:4.3.6.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration.dataSource(JndiDataSourceAutoConfiguration.java:62) ~[spring-boot-autoconfigure-1.5.1.RELEASE.jar:1.5.1.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration$$EnhancerBySpringCGLIB$$9509801a.CGLIB$dataSource$0() ~ ........
My POM.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
</dependencies>
The point is that when you try to compile by using maven, maven tries to execute also Junit tests; in your case you have in src/resources/java some unit tests and so maven tries to execute them. Since you are using a JNDI datasource, it means that also the servlet container must be active for executing tests otherwise you can't get connection.
In this case when maven tries to execute tests maybe no servlet container (and, so, no JNDI datasource) is active and your test throws error.
To solve this (and to compile the maven artifact) you must:
or exclude tests execution: this is done by adding <maven.test.skip>true</maven.test.skip> in pom.xml. No test will be executed
or ignore tests error this is done by adding <maven.test.failure.ignore>true</maven.test.failure.ignore> in pom.xml. In this case tests will be executed but any test error will not stop maven compilation
The configuration I gave not only tells maven to not execute tests but it tells maven to not stop on any test error
I hope i have been clearer... my english is not the best

javax/mail/MessagingException in Spring 4 MVC

I have an application (Spring 4 MVC+Hibernate 4+MySQL+Maven integration example using annotations) , integrating Spring with Hibernate using annotation based configuration.
I have this error when starting the appl.
GRAVE: Excepción enviando evento inicializado de contexto a instancia de escuchador de clase org.springframework.web.context.ContextLoaderListener
java.lang.NoClassDefFoundError: javax/mail/MessagingException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
at java.lang.Class.getDeclaredMethods(Class.java:1860)
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:609)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:521)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:507)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:241)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1069)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5001)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5517)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: javax.mail.MessagingException
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1854)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1703)
... 30 more
I have this in the pom.xml
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
and I've checked the repository and is there:
/Users/paquirrin/.m2/repository/javax/mail/mail/1.4
I've updated the maven project 1000 times, but it doesn't work!
I run the project in a tomcat7 at localhost
Seems you are using the wrong dependency. Try the following:
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mailapi</artifactId>
<version>1.4.3</version>
</dependency>
Make sure to refresh the dependencies, and rebuild the project.
The artifact has been already moved from javax.mail >> javax.mail-api.
So, it is better not to use this given below.
<!-- https://mvnrepository.com/artifact/javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
Instead, use this latest dependency :
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.6</version>
</dependency>
After adding this dependency, then do these steps:
Go to Project Menu >> Activate Build Automatically Option >> Then Click on Clean Option there.
After that, do Maven Clean and Maven Install.
Delete the war and the extracted war folder from tomcat/webapps and redeploy the war again.
Through this, the problem may be solved.
You should not have a need to add the mail api's to your classpath, since spring will include them transitively (given you are using spring-boot).
In case you are using spring-framework without boot, you can (as suggested in the documentation), also ensure the JavaMail library (com.sun.mail:javax.mail) is on the classpath.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.27.RELEASE</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
There is a requirement for some jars according to Spring 4 docs in order to make it work. You are probably missing some of them.
The following additional jars to be on the classpath of your application in order to be able to use the Spring Framework’s email library.
The JavaMail mail.jar library
The JAF activation.jar library
All of these libraries are freely available on the web.
Or there might be something with Maven. Sometimes it helps if you remove .m2 folder and then run mvn install on your project to download all the dependencies with the right versions.

spring-boot: response compression while executed from Maven command line

I'm interested in enabling HTTP response compression for my Java 8 / spring-boot 1.3.2 / Maven 3.3 based application.
Following the spring-boot reference documentation from http://docs.spring.io/spring-boot/docs/1.3.x/reference/htmlsingle/#how-to-enable-http-response-compression, I have added the following change to my application.properties:
server.compression.enabled=true
While the application started successfully before the above addition, with it the application fails to start with the following error when using the Maven command below:
mvn clean spring-boot:run
...
...
2016-01-26 09:48:48.802 ERROR 15204 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is java.lang.IllegalStateException: Compression is enabled, but GzipHandler is not on the classpath
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at com.miletwentyfour.client.Application.main(Application.java:43) [classes/:na]
Caused by: java.lang.IllegalStateException: Compression is enabled, but GzipHandler is not on the classpath
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory.createGzipHandler(JettyEmbeddedServletContainerFactory.java:192) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory.addHandlerWrappers(JettyEmbeddedServletContainerFactory.java:168) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory.getEmbeddedServletContainer(JettyEmbeddedServletContainerFactory.java:148) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:160) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
... 8 common frames omitted
My next step, per the reference documentation section 64.18.2, was to add the following dependency to the pom.xml:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>9.3.7.v20160115</version>
</dependency>
Using mvn:dependency:tree I can verify that jetty-servlets is included in the application as a compile time scoped dependency. Yet, the application fails to start with the same error output as above.
Can anyone please point out what I am missing and/or what do I need to do to get response compression to work successfully when launching the application from a Maven command line?
You need following maven dependancy:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.7.v20160115</version>
</dependency>
Andy Wilkinson was correct and provided the needed information I was missing.
For the benefit of others, I was mixing Spring Boot 1.3 with the 9.3.x flavors of spring-jetty. Once I used the latest of spring-jetty 9.2.x -- I used 9.2.14.v20151106 -- my application started as normal.
To summarize, here the changes I made:
application.properties:
server.compression.enabled=true
pom.xml:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>9.2.14.v20151106</version>
</dependency>

How to avoid dependency conflict when using dropwizard + jersey client

I have a DropWizard REST API written and works. One of the resource endpoints actually writes an email, however as soon as I add the following dependencies DropWizard starts to fail on start up
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.1</version>
</dependency>
The DropWizard dependency is:
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-core</artifactId>
<version>0.8.1</version>
</dependency>
The error on startup is really long, summarised below
WARN [2015-05-01 20:06:08,887] 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:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
....
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:395)
....
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: create on org.glassfish.jersey.message.internal.MessageBodyFactory
...
I'm guessing DropWizard is using another conflicting dependency so how do I deal with this?
Thanks in advance
Dropwizard 0.8.x uses Jersey 2.x which naturally conflicts with your Jersey 1.x dependencies.
I think it might be fine with jersey-client as long as you don't have dropwizard-client dependency but jersey-core will conflict at many points with dropwizard's jersey which I don't think you can fix. And also I don't think you'd need jersey-core for sending email anyway.
If you do need jersey for this, try using Jersey 2.16 instead which is the version dropwizard is using.
I had the same problem (I'm using DW 0.9.2 and have unwanted transitive dependencies of both DW 0.7.2 and Jersey 1.x)
The solution was pretty simple: in the dependency that's bringing you those two family of libraries, declare an exclusion and it should work, for instance, this is how I did it in Gradle:
compile("com.example.culprit:culprit:1.2.3") {
exclude group: 'io.dropwizard'
exclude group: 'com.sun.jersey'
}
The syntax for Maven is pretty similar (more verbose actually ;-) )
Hope this helps someone.

Categories

Resources