Plugin throws java.lang.ClassNotFoundException

Hello,

i have wrote plugin for elasticsearch which use oracle.ucp libary. The libary use Thread.currentThread().getContextClassLoader() to load 'oracle.jdbc.OracleDriver' with elasticsearch 2.1, disabled securityManager and oracle libaries stored in <ES_HOME>/lib directory everything works fine.

Now i want to update elasticsearch to version 2.4.0. Therefore i granted the permissions insdie a plugin-security.policy and stored the oracle libaries in the plugin directory. But now i always get an 'java.lang.ClassNotFoundException' cause the Thread.currentThread().getContextClassLoader() only contains the libaries of the <ES_HOME>/lib directory and not the libaries of the plugin directory.

How can i solve this problem? If i store the oracle libaries in <ES_HOME>/lib instead of the plugin directory i get problems with the granted permissions cause this permissions only for the plugin and it's libaries...

Why Thread.currentThread().getContextClassLoader() only returns entries of 'elasticsearch/lib/' directory?

Class.forName() returns entries of 'elasticsearch/lib/' and 'elasticsearch/plugins/myPlugin' directory

Elasticsearch does not support class loading per thread context because threads are not isolated. All threads are shared by ES code and all plugin code. Plugin initialization code is isolated. So, a plugin can only see their own class path at startup time, composed of the Elasticsearch parent class path and the JARs in the plugin folder.

As a consequence, this breaks everything with class loading as intended by the JDK. There is no mechanism in Elasticsearch like in Java EE (context class loading).

In practice, you must either load OracleDriver class directly in your code, which is clumsy, or you must put your JDBC driver to the ES_HOME/lib directory, because Java JDK ServiceLoader infrastructure is not aware of any plugin class path.

Thanks for your response. For now it only works when i put the JDBC driver to the ES_HOME/lib directory and start elasticsearch with security.manager.enabled: false.

Is it possible to grant permissions for the JDBC driver of ES_HOME/lib directory? Following the permission error with security.manager.enabled: true

SEVERE: Error while registering Oracle JDBC Diagnosability MBean.
java.security.AccessControlException: access denied ("javax.management.MBeanServerPermission" "createMBeanServer")

You have to add extra permissions to your security file, like this

permission javax.management.MBeanServerPermission "createMBeanServer";
permission javax.management.MBeanServerPermission "findMBeanServer";
permission javax.management.MBeanPermission "oracle.*", "*";
permission javax.management.MBeanTrustPermission "register";

Maybe it works, maybe not. I did not try it. Oracle driver needs lots of disabled security.

Currently my plugin-security.policy looks like this:

grant {
  // needed to apply additional sandboxing
  permission java.security.SecurityPermission "createAccessControlContext";

  // Allow MBeanServerPermission createMBeanServer
  permission javax.management.MBeanServerPermission "createMBeanServer";

  // Allow MBeanTrustPermission register
  permission javax.management.MBeanTrustPermission "register";

  // Allow MBeanPermission registerMBean
  permission javax.management.MBeanPermission "*", "registerMBean";

  // Allow RuntimePermission getClassLoader
  permission java.lang.RuntimePermission "getClassLoader";
  permission java.lang.RuntimePermission "accessDeclaredMembers";
};

Is it correct to put it inside the plugin-security.policy at ES_HOME/plugins/myPlugin?

It seems that plugin-security.policy at ES_HOME/plugins/myPlugin dosn't work for the JDBC driver of ES_HOME/lib