Custom Realm Plugin install fails on jar hell error

I have a custom plugin on my local elastic 6.3.2 environment. After packaging this and when I try to run the install command, it was failing to recognize the SecurityExtension class on a provided maven scope, so I included all transitive dependencies as mentioned in https://www.elastic.co/guide/en/elasticsearch/reference/6.3/setup-xpack-client.html after changing scope to compile.
This introduces a whole host of jars which I don't need and x-pack is in the org.elasticsearch.xpack.* library, do I have to exclude each one until I have only the xpack.* libraries? or is there a dependency which will get me just that, I do not want to copy the xpack.core jar as part of my packaging from my share until that's the last resort.
I was wondering how others are getting around this, any suggestions would help.

Error
Caused by: java.lang.IllegalStateException: jar hell!
class: org.elasticsearch.cli.Terminal$ConsoleTerminal
jar1: C:\Program Files\elasticsearch-6.3.2\lib\elasticsearch-cli-6.3.2.jar
jar2: C:\Program Files\elasticsearch-6.3.2\plugins.installing-5426440422517939048\elasticsearch-cli-6.3.2.jar
at org.elasticsearch.bootstrap.JarHell.checkClass(JarHell.java:273)
at org.elasticsearch.bootstrap.JarHell.checkJarHell(JarHell.java:190)
at org.elasticsearch.plugins.PluginsService.checkBundleJarHell(PluginsService.java:609)
... 12 more

You'll need to depend on the x-pack security jar as a provided dependency, and specify in your plugin descriptor that you are extending x-pack-security. Have you looked at the example api security extension?

1 Like

I could find x-pack-core dependency and pulling in seem to help with it.

<dependency>
			<groupId>org.elasticsearch.plugin</groupId>
			<artifactId>x-pack-core</artifactId>
			<version>${elasticsearch.version}</version>
		</dependency>

I packaged my zip with this jar as well, ran the install and the error went away. I can try pulling in x-pack-security because that's really just the one I want so that it would not get the other unneeded jars

Note that it is important those are marked as provided. Your plugin should compile against them (core and security jars), but not include them in your own plugin zip. This is because by declaring your plugin to extend x-pack-security, your plugin will be loaded in a way the classes are pulled in from x-pack core and security classes already loaded by elasticsearch. If you include these jars in your own plugin SPI could never work because the SecurityExtension interface would be a different loaded version than that in x-pack-security.

When I started off with the java.lang.NoClassDefFoundError, the documentation (Configuring X-Pack Java Clients | Elasticsearch Guide [6.3] | Elastic) said I need to add x-pack-transport to the classpath and all it's dependencies, so I had this scope as compile to pull in the jar but excluded all transitive dependencies as it was causing the jar hell error, lot of the jars which the x-pack-transport pulls are already present. To fix this, I got my own x-pack-core jar with the custom zip so that it's recognized at compile time and helped fix the error.
Now, I tried what you said by having the x-pack-core and x-pack-security as provided and I'm back to square 1 with the same initial error -

java.lang.NoClassDefFoundError: org/elasticsearch/xpack/core/security/SecurityExtension
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:?]
at java.lang.ClassLoader.defineClass(ClassLoader.java:1009) ~[?:?]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174) ~[?:?]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:545) ~[?:?]
at java.net.URLClassLoader.access$100(URLClassLoader.java:83) ~[?:?]
at java.net.URLClassLoader$1.run(URLClassLoader.java:453) ~[?:?]
at java.net.URLClassLoader$1.run(URLClassLoader.java:447) ~[?:?]
at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
at java.net.URLClassLoader.findClass(URLClassLoader.java:446) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:566) ~[?:?]
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:890) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[?:?]
at org.elasticsearch.plugins.PluginsService.loadPluginClass(PluginsService.java:668) ~[elasticsearch-6.3.2.jar:6
.3.2]
at org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:642) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:557) ~[elasticsearch-6.3.2.jar:6.3.2
]
at org.elasticsearch.plugins.PluginsService.(PluginsService.java:162) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.node.Node.(Node.java:311) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.node.Node.(Node.java:252) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Bootstrap$5.(Bootstrap.java:213) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:213) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:326) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:136) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:127) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.3.2.
jar:6.3.2]
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.3.2.jar:6.3.2]
at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[elasticsearch-6.3.2.jar:6.3.2]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) ~[elasticsearch-6.3.2.jar:6.3.2]
Caused by: java.lang.ClassNotFoundException: org.elasticsearch.xpack.core.security.SecurityExtension
at java.net.URLClassLoader.findClass(URLClassLoader.java:466) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:566) ~[?:?]
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:890) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:499) ~[?:?]
... 28 more

Which makes me think that elastic wants to bring in our x-pack jars with the zip and the rest of the functionalities outside x-pack are provided.

What does your plugin descriptor look like? Also, why are you bringing in the transport client? This won't work. You need to either use the NodeClient that is accessible through createComponents in your plugin, or use rest apis.

Here is my plugin descriptor.properties and the plugin.xml which loads this

description=custom Extension
version=${plugins.version}
name=customRealm
classname=${elasticsearch.plugin.classname}
java.version=${maven.compiler.target}
elasticsearch.version=${elasticsearch.version}

<?xml version="1.0"?> plugin dir false ${basedir}/src/main/plugin-metadata plugin-security.policy plugin-descriptor.properties true / true false

The reason why I brought in the x-pack-transport is because I was trying a few things and found the documentation which asked to bring in the transport client with default compile scope if you look at the example. I thought creating a custom realm is just extending the SecurityExtension class - Integrating with other authentication systems | Elastic Stack Overview [7.4] | Elastic, I want to be able to implement it this way.

Is this the one I'm missing?

'extended.plugins': other plugins this plugin extends through SPI
As this plugin provides a SecurityExtension, it must extend x-pack-security
extended.plugins=x-pack-security

All the info you need is spelt out in this blog post, including a sample maven build file.

I just happened to find this and did include the extended.plugins=x-pack-security in my descriptor and just bringing in x-pack-core with provided as @rjernst mentioned above. All the errors I had before went away but getting a unknown realm type exception

Caused by: java.lang.IllegalArgumentException: unknown realm type [myRealm] set for realm [custom]
at org.elasticsearch.xpack.security.authc.Realms.initRealms(Realms.java:159) ~[?:?]
at org.elasticsearch.xpack.security.authc.Realms.(Realms.java:63) ~[?:?]

Also, is it mandatory to include the META-INF folder like mentioned in the post above?
META-INF/services/org.elasticsearch.xpack.core.security.SecurityExtension file

Yes, that is how you register your extension.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.