Code in ldap.core.LdapTemplate is wrong, because while(results.hasMore())
is inside try/catch(PartialResultException), and exception breaks while loop,
but it shouldn't. The try/catch(PartialResultException) should be located inside the while loop.
Like this:
public void search(SearchExecutor se, NameClassPairCallbackHandler handler,
DirContextProcessor processor) {
DirContext ctx = contextSource.getReadOnlyContext();
NamingEnumeration results = null;
RuntimeException ex = null;
try {
processor.preProcess(ctx);
results = se.executeSearch(ctx);
log.debug("results are="+results);
while(true) {
try {
if (!results.hasMore())
break;
NameClassPair result = (NameClassPair) results.next();
log.debug("result="+result);
log.debug("result="+result.getName()+", "+result.getClassName());
handler.handleNameClassPair(result);
}
catch (PartialResultException e) {
if (ignorePartialResultException) {
log.debug("PartialResultException encountered and ignored: ["+e.getResolvedName()+"] "+ e.getRemainingName());
} else {
ex = LdapUtils.convertLdapException(e);
}
continue;
}
catch (NullPointerException npe) {
break;
}
}
}
catch (NameNotFoundException e) {
// The base context was not found, which basically means
// that the search did not return any results. Just clean up and
// exit.
// Note that this may present problems if a DirContextProcessor was
// supplied - there's no guarantee that the postProcess() operation
// will go well after a NamingException has been thrown. It is
// however quite possible that information will be available for
// retrieval either way.
e.printStackTrace();
}
catch (javax.naming.NamingException e) {
ex = LdapUtils.convertLdapException(e);
}
finally {
try {
processor.postProcess(ctx);
} catch (javax.naming.NamingException e) {
if (ex == null) {
ex = LdapUtils.convertLdapException(e);
} else {
// We already had an exception from above and should ignore
// this one.
log.debug("Ignoring Exception from postProcess, "
+ "main exception thrown instead", e);
}
}
closeContextAndNamingEnumeration(ctx, results);
// If we got an exception it should be thrown.
if (ex != null) {
throw ex;
}
}
}
see also: http://jira.springframework.org/browse/SEC-832
Are you saying that we may get more results after a PartialResultException has been thrown? If that is true our code should reflect that.
The javadocs for PartialResultException seems to indicate otherwise (though, admittedly, it's far from clear):
"This exception is thrown to indicate that the result being returned or returned so far is partial, and that the operation cannot be completed."