How to share ClassLoader bewteen different Plugins

(pazugan) #1

Hi,

I am trying develop Elatsicsearch plugins and currently facing some issue as how to share single request model and allow one plugin to accept the request in the TransportAction from other plugin.

Error I message I am getting is

Internal error: class foo.bar.MyRequest cannot be cast to class foo.bar.MyRequest (foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @19a64eae; foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @697a34af). See the Elasticsearch.log for details
java.lang.ClassCastException: class foo.bar.MyRequest cannot be cast to class foo.bar.MyRequest (foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @19a64eae; foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @697a34af)

To be clear I have shared dependency on package that has MyRequest class in both Plugins.

Thanks in advance!

(pazugan) #2

Alternatively, how do I write a High Level Rest Client from one plugin to be used by another plugin?

(Ryan Ernst) #3

I think this may be a bug, due to optimizations to avoid serialization for local requests. It may be difficult to fix, though. Can you show the full stacktrace from the elasticsearch log?

(pazugan) #4

Thank you for the response. This is the stack trace from the elasticsearch log.
For now I am trying to do a simple client.execute(MyAction.INSTANCE, MyRequest()).actionGet() from SamplePlugin to another plugin. At which, it fails to cast into same type of class.

    Internal error: class foo.bar.MyRequest cannot be cast to class foo.bar.MyRequest (foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @55cff952; foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @66ec9390). See the Elasticsearch.log for details
    java.lang.ClassCastException: class foo.bar.MyRequest cannot be cast to class foo.bar.MyRequest (foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @55cff952; foo.bar.MyRequest is in unnamed module of loader java.net.FactoryURLClassLoader @66ec9390)
            at foo.bar.MyTransportAction.doExecute(MyTransportAction.java:30) ~[?:?]
            at org.elasticsearch.action.support.TransportAction.doExecute(TransportAction.java:143) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.action.support.TransportAction$RequestFilterChain.proceed(TransportAction.java:167) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:139) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.action.support.TransportAction.execute(TransportAction.java:81) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.client.node.NodeClient.executeLocally(NodeClient.java:87) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.client.node.NodeClient.doExecute(NodeClient.java:76) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:403) ~[elasticsearch-6.6.2.jar:6.6.2]
            at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:391) ~[elasticsearch-6.6.2.jar:6.6.2]
            at foo.bar.SampleClass$runTask$1.run(SampleClass.java:184) [SamplePlugin.jar:Sample]
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
            at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
            at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:660) [elasticsearch-6.6.2.jar:6.6.2]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
            at java.lang.Thread.run(Thread.java:834) [?:?]
(Ryan Ernst) #5

This is what I thought: the node client is executing the action directly, since both actions are executing on the same node. However, is your plugin trying to do the cast which is causing the problem, or is this due to generics? If you could take in the superclass ActionRequest, you could do your own serialization/deserialization, but I'm not sure the generics will allow that (I haven't tried experimenting, just hypothesizing).