You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Icky Dude <ic...@gmail.com> on 2008/03/21 23:43:45 UTC

[ApacheDS] Declaration and instantiation of refService in ServerLdapContext limits extensibility

Hi,

I am using ApacheDS code for a research project.  The best and
quickest way for me to meet my requirements has been to write my own
DirectoryService, PartitionNexus, and Partitions (which implement
ApacheDS's declared DirectoryService, PartitionNexus, and Partition
interfaces).  So far, I've been really pleased with how little code
I've had to write because I've been able to reuse most of the existing
classes.

Today, however, I ran into a problem that I think needs some simple
design work.  For my project is is not necessary to handle referrals,
so I decided to simply eliminate the ReferralIntercepter from my
InterceptorChain.  As soon as I did this, myDirectoryService started
crapping on a NullPointerException buried in the bowels of the
DefaultSearchHandler (something I definitely don't want to mess with
for my project).

1) At DefaultSearchHandler.java:357 of  there is an instantiation of a
new SearchResponseIterator.
2) The constructor for SearchResponseIterator calls
ServerLdapContex.isReferral() at SearchResponseItereator:117
3) ServerLdapContext.isReferral() results in a NPE at
ServerLdapContext.java:264 unless your DirectoryService's
InterceptorChain includes a ReferralInterceptor.  Take a look at the
constructor and you'll see why:

public ServerLdapContext( DirectoryService service, Hashtable<String,
Object> env ) throws NamingException
{
    super( service, env );
    refService = ( ( ReferralInterceptor )
service.getInterceptorChain().get( ReferralInterceptor.class.getName()
) );
}

Is there any chance that we can simply Check refService for null
before it's used ServerLdapContext.isReferral().  If it's
refService==null, return false?

There's also similar a similar problem in PartitionNexusProxy.java:891
and 901.  Here the code checks the chain for null, and returns, but it
doesn't check the for null before invoking the interceptor method.

Here's the patch:

$ svn diff ServerLdapContext.java
Index: ServerLdapContext.java
===================================================================
--- ServerLdapContext.java      (revision 638966)
+++ ServerLdapContext.java      (working copy)
@@ -261,7 +261,11 @@
      */
     public boolean isReferral( String name ) throws NamingException
     {
-        return refService.isReferral( name );
+       if( refService == null )
+        {
+               return false;
+        }
+       return refService.isReferral( name );
     }

     /**
@@ -272,7 +276,11 @@
      */
     public boolean isReferral( LdapDN name ) throws NamingException
     {
-        return refService.isReferral( name );
+        if( refService == null )
+        {
+               return false;
+        }
+       return refService.isReferral( name );


$ svn diff PartitionNexusProxy.java
Index: PartitionNexusProxy.java
===================================================================
--- PartitionNexusProxy.java    (revision 638966)
+++ PartitionNexusProxy.java    (working copy)
@@ -889,6 +889,10 @@
     {
         InterceptorChain chain = service.getInterceptorChain();
         EventInterceptor interceptor = ( EventInterceptor )
chain.get( EventInterceptor.class.getName() );
+        if( interceptor == null )
+        {
+               return;
+        }
         interceptor.addNamingListener( ctx, name, filter,
searchControls, namingListener );
     }

@@ -901,6 +905,10 @@
             return;
         }
         EventInterceptor interceptor = ( EventInterceptor )
chain.get( EventInterceptor.class.getName() );
+        if( interceptor == null )
+        {
+               return;
+        }
         interceptor.removeNamingListener( ctx, namingListener );
     }
 }