Michael Allen created ACCUMULO-1928:
---------------------------------------

             Summary: Class loader issues with building auth/auth/perm 
extensions
                 Key: ACCUMULO-1928
                 URL: https://issues.apache.org/jira/browse/ACCUMULO-1928
             Project: Accumulo
          Issue Type: Bug
    Affects Versions: 1.5.0, 1.6.0
            Reporter: Michael Allen


In the course of building extensions to take advantage of the 
{{Authenticator}}, {{Authorizor}} and {{PermissionHandler}} interfaces, I ran 
into several issues with how the extension classes were loaded (and reloaded) 
using {{AccumuloVFSClassloader}}.  These issues ultimately meant that we had to 
make the decision to put these extensions into {{$ACCUMULO_HOME/lib}}, rather 
than {{$ACCUMULO_HOME/lib/ext}}, so that they would not be reloaded and we 
would not encounter those issues.

We should figure out how to fix up the classloader such that it makes it 
possible to put extensions like these into {{$$ACCUMULO_HOME/lib/ext}}, or we 
should document that it is not recommended to do so.

So what were the problems?

1. In 1.5.0, Authentication tokens from within the extension could not be 
loaded via the normal creation pathway.  This pathway in {{CredentialHelper}} 
includes the following line of code:

{code}
Object obj = Class.forName(tokenClass).newInstance();
{code}

In 1.6 this code has been replaced with a call in 
{{AuthenticationToken.AuthenticationTokenSerializer.deserialize()}} that uses 
{{AccumuloVFSClassloader}}, but I wonder if we shouldn't also make a 1.5.X 
change to at least make it possible to do it there?  Otherwise anyone trying to 
create an extension for 1.5.X can only use {{PasswordToken}}s

2.  Even when you do or don't fix #1, it leads you on to a different, less 
tractable problem.

The {{Authenticatior}} etc. classes are loaded by {{SecurityOperation}} 
singleton, using {{AccumuloVFSClassloader}} and the objects are held within the 
singleton, which is held statically by the {{SecurityOperation}} class.  That's 
all well and good, and let's call that {{AccumuloVSFClassloader}} instances 
that loaded those classes {{CL1}}.

But now let's say you stick a new version of your JAR file into 
{{$ACCUMULO_HOME/lib/ext}}.  {{AccumuloVFSClassloader}} happily creates a new 
classloader (call it {{CL2}}) for you and reloads your classes.  *However*, the 
objects instantiated by {{SecurityOperation}} still owe their lineage to 
{{CL1}}.  When a new authentication token comes in and gets loaded by {{CL2}}, 
its class name might look like a class from {{CL1}}, but when the 
{{Authenticator}} that came from {{CL1}} tries to cast that {{CL2}}-based 
object, you get {{ClassCastException}}s and are basically toast at that point.

One possible fix here would be for {{AccumuloVFSClassloader}} to somehow notify 
interested parties that classes had reloaded so that they could flush away any 
old classes if desired.  There'd be some synchronization issues around doing 
this, to make sure that the security stuff still worked reliably through this 
process.  You'd have no guarantee, though, that the rest of the code wouldn't 
be hanging on to {{CL1}}-based object references and not letting go.  Beating 
those bugs out may require too much coder discipline to be worth the feature.

Another possible fix is to just say "don't do that for security-related 
features and put them in {{$ACCUMULO_HOME/lib}}.  That's kind of giving up on 
being able to reload these at runtime, but maybe that's OK.  Generally 
speaking, reloading your security assumptions might be something you want to 
take the tablet server down for.








--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to