I set-up the LDAP DirContext.search(...) to ignore referrals, but I still get a referral exception when I call NamingEnumeration.hasMore().
Exception in thread "main" javax.naming.PartialResultException: Unprocessed Continuation Reference(s); remaining name 'DC=company,DC=com'
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2846)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2820)
at com.sun.jndi.ldap.LdapNamingEnumeration.getNextBatch(LdapNamingEnumeration.java:129)
at com.sun.jndi.ldap.LdapNamingEnumeration.hasMoreImpl(LdapNamingEnumeration.java:198)
at com.sun.jndi.ldap.LdapNamingEnumeration.hasMore(LdapNamingEnumeration.java:171)
Can I tell DirContext.search to ignore referrals, so that NamingEnumeration.hasMore() returns false instead of throwing an exception?
this is the snipped:
import javax.naming.*;
import javax.naming.directory.*;
Properties p = new Properties();
p.setProperty(Context.INITIAL_CONTEXT_FACTORY, ldapInitContextFactory);
p.setProperty(Context.PROVIDER_URL, ldapURL);
p.setProperty(Context.SECURITY_CREDENTIALS, ldapPassword);
p.setProperty(Context.SECURITY_PRINCIPAL, ldapUser);
p.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
p.setProperty(Context.REFERRAL, "ignore");
DirContext ctx = new InitialDirContext(p);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setDerefLinkFlag(false);
NamingEnumeration e = ctx.search(ldapBaseDN, ldapQuery, null, searchControls);
for (; e.hasMore();) {
SearchResult sr = (SearchResult) e.next();
System.out.println("\nSearch Result: " + sr.getName());
}
Note: if I enable referrals, I get an LdapReferralException expcetion when I call NamingEnumeration.hasMore().
javax/naming/NamingEnumeration.java
public interface NamingEnumeration<T> extends Enumeration<T> {
public boolean hasMore() throws NamingException;
public T next() throws NamingException;
...
}
java/util/Enumeration.java
public interface Enumeration<E> {
boolean hasMoreElements();
E nextElement();
}
calling e.hasMoreElements() instead of e.hasMore() solves the issue. that is, it returns false (instead of throwing an exception) when there are referrals.
however, it is not an optimal solution, in the sense that we might be missing other real NamingException exceptions (such as CommunicationException).
I still would like to find the proper way to tell DirContext.search to ignore referrals, so that NamingEnumeration.hasMore() returns false instead of throwing an exception. any idea?
I downloaded the JDK source code at http://download.java.net/openjdk/jdk6/ -> openjdk-6-src-b24-14_nov_2011.tar.gz however this source code does not correspond exactly with the JDK binaries, see how to find the exact sources of a JDK1.6 binary (including com.sun.jndi.*)
from this JDK source code below it doesn't seem possible to get a "false" instead of an exception when there are referrals.
./jdk/src/share/classes/com/sun/jndi/ldap/LdapCtx.java
protected void processReturnCode(LdapResult res, Name resolvedName, Object resolvedObj, Name remainName, Hashtable envprops, String fullDN) throws NamingException {
NamingException e;
switch (res.status) {
case LdapClient.LDAP_SUCCESS:
// handle Search continuation references
if (res.referrals != null) {
msg = "Unprocessed Continuation Reference(s)";
if (handleReferrals == LdapClient.LDAP_REF_IGNORE) {
e = new PartialResultException(msg);
break;
}
[...]
}
[...]
throw e;
}
but still I am not sure.
I think it makes sense that we could tell DirContext.search to ignore referrals, so that NamingEnumeration.hasMore() returns false instead of throwing an exception.
any idea?
From what little I understand, there is a way to ignore referrals, which can be especially helpful when dealing with Active Directory LDAP operations. You'd have to create and inject a new LdapTemplate
(constructed with a configured ContextSource
) instead of creating your own InitialDirContext
from scratch. I can't tell if that's going to be compatible with your setup. I hope this helps.
From the Spring LDAP Core LdapTemplate
documentation:
AD servers are apparently unable to handle referrals automatically, which causes a
PartialResultException
to be thrown whenever a referral is encountered in a search. To avoid this, set theignorePartialResultException
property totrue
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With