I am trying to create a fat executable jar with maven, including elasticsearch as a dependency to create a TransportClient to a running elasticsearch node. From eclipse the client connects just fine to the node, but when I create a jar from the whole project and run that with java -jar bla.jar
, the connection fails with:
DEBUG - [Armor] adding address [{#transport#-1}{127.0.0.1}{127.0.0.1:9300}]
DEBUG - [Armor] connected to node [{#transport#-1}{127.0.0.1}{127.0.0.1:9300}]
INFO - [Armor] failed to get node info for {#transport#-1}{127.0.0.1}{127.0.0.1:9300}, disconnecting...
org.elasticsearch.transport.RemoteTransportException: [Failed to deserialize response of type [org.elasticsearch.action.admin.cluster.node.liveness.LivenessResponse]]
Caused by: org.elasticsearch.transport.TransportSerializationException: Failed to deserialize response of type [org.elasticsearch.action.admin.cluster.node.liveness.LivenessResponse]
at org.elasticsearch.transport.netty.MessageChannelHandler.handleResponse(MessageChannelHandler.java:179) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.transport.netty.MessageChannelHandler.messageReceived(MessageChannelHandler.java:138) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:462) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:443) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_66-internal]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_66-internal]
at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_66-internal]
...
Caused by: java.lang.IllegalArgumentException: An SPI class of type org.apache.lucene.codecs.PostingsFormat with name 'Lucene50' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath. The current classpath supports the following names: [es090, completion090, XBloomFilter]
at org.apache.lucene.util.NamedSPILoader.lookup(NamedSPILoader.java:109) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.apache.lucene.codecs.PostingsFormat.forName(PostingsFormat.java:112) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.common.lucene.Lucene.<clinit>(Lucene.java:68) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.Version.fromId(Version.java:508) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.Version.readVersion(Version.java:280) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.cluster.node.DiscoveryNode.readFrom(DiscoveryNode.java:327) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.cluster.node.DiscoveryNode.readNode(DiscoveryNode.java:310) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.action.admin.cluster.node.liveness.LivenessResponse.readFrom(LivenessResponse.java:52) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.transport.netty.MessageChannelHandler.handleResponse(MessageChannelHandler.java:177) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.elasticsearch.transport.netty.MessageChannelHandler.messageReceived(MessageChannelHandler.java:138) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:462) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:443) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) ~[cmd-0.0.1-SNAPSHOT.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_66-internal]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_66-internal]
at java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_66-internal]
With the root cause of An SPI class of type org.apache.lucene.codecs.PostingsFormat with name 'Lucene50' does not exist. You need to add the corresponding JAR file supporting this SPI to your classpath. The current classpath supports the following names: [es090, completion090, XBloomFilter]
. I read up on this, it basically means that my final jar includes same-named manifest files from the various lucene dependencies, that are overwritten by each other. I used the maven-shade-plugin with a manifest resource transformer to solve the problem, but the error remains:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>de.test.cmd.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Then I looked for elasticsearch jars without lucene dependency, I just want to create a transportclient for communication. No such luck, there is only that one jar, including lucene. What can I do to put elasticsearch into a runnable jar? or should I keep all dependencies in a lib folder besides the jar? I don't know how to tell maven to do that
--
UPDATE: When I use "Copy required libraries into a sub-folder besides the jar" from eclipse export dialog, it works. I let eclipse generate a build.xml from that, but I still want to try and use maven for building that jar, either with dependencies included, or as an extra directory.
You should add the follow
transformer
tag to the shade plugin.<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
I faced the same issue and what I found to work cleaner in maven was the inclusion of lucene-core dependency explicitly above the elasticsearch dependency in the project's pom.xml.
in my case, it's caused the by the incorrect
META-INF/services/{org.apache.lucene.codecs.Codec, org.apache.lucene.codecs.PostingsFormat, org.apache.lucene.codecs.DocValuesFormat}
being overwritten by the wrong lib.
I suppose there are multiple libraries that has the same files that during the assembly, the incorrect one got overwritten.
Just open the correct jar file and copy the same files into your resource folder. I works most of the time ;)