[ 
https://issues.apache.org/jira/browse/HADOOP-17675?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17336994#comment-17336994
 ] 

István Fajth commented on HADOOP-17675:
---------------------------------------

As stated in this article:
https://www.infoworld.com/article/2077344/find-a-way-out-of-the-classloader-maze.html

A native thread has its context classloader set to null by default.
If the context classloader which is used internally by JNDI to load a class is
null, then the bootstrap classloader is used, according to the apidoc here:
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-boolean-java.lang.ClassLoader-

JNDI uses this form with the context classloader as can be seen here:
https://github.com/openjdk/jdk11u/blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java#L107
or here:
https://github.com/openjdk/jdk8u/blob/master/jdk/src/share/classes/com/sun/jndi/ldap/VersionHelper12.java#L72

In Impala this call happens from a Thread created in native space, so in that
case, the System/Application classloader loads LdapSslSocketFactory fine in
LdapGroupsMapping.getDirContext() while creating the environment, but then
InitialDirContext constructor gets to instantiation the LdapSslSocketFactory
inside JNDI with the help of the linked VersionHelper impelmentations,
and fails to load the class with the bootstrap classloader as context
classloader is null.

In order to solve this problem, we can safely use the classloader of the
LdapGroupsMapping class, as it had to load the LdapSslSocketFactory class
before.

> LdapGroupsMapping$LdapSslSocketFactory ClassNotFoundException
> -------------------------------------------------------------
>
>                 Key: HADOOP-17675
>                 URL: https://issues.apache.org/jira/browse/HADOOP-17675
>             Project: Hadoop Common
>          Issue Type: Improvement
>          Components: common
>    Affects Versions: 3.2.2
>            Reporter: Tamas Mate
>            Assignee: István Fajth
>            Priority: Major
>              Labels: pull-request-available
>         Attachments: stacktrace.txt
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> Using LdapGroupsMapping with SSL enabled causes ClassNotFoundException when 
> it is called through native threads, such as Apache Impala does.
> When a thread is attached to the VM, the currentThread's context classloader 
> is null, so when jndi internally tries to use the current thread's context 
> classloader to load the socket factory implementation, the 
> Class.forname(String, boolean, ClassLoader) method gets a null as the loader  
> uses the bootstrap classloader.
>  Meanwhile the LdapGroupsMapping class and the SslSocketFactory defined in it 
> is loaded by the application classloader from its classpath.
> As the bootstrap classloader does not have hadoop-common in its classpath, 
> when a native thread tries to use/load the LdapGroupsMapping class it can't 
> because the bootstrap loader can't load anything from hadoop-common. The 
> correct solution seems to be to set the currentThread's context classloader 
> to the classloader of LdapGroupsMapping class before initializing the jndi 
> internals, and then reset to the original value after, with that we can 
> ensure that the behaviour of other things does not change, but this failure 
> can be avoided as well.
> Attached the complete stacktrace to this Jira.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: common-issues-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-issues-h...@hadoop.apache.org

Reply via email to