You are viewing a plain text version of this content. The canonical link for it is here.
Posted to api@directory.apache.org by Frode Randers <fr...@gmail.com> on 2014/01/15 18:03:06 UTC

LdapNetworkConnection blocking on close()

I have this really simple setup;

  - Java 1.7.0_40

  - an embedded ApacheDS 1.5.7 listening on port 389 and prepared with a
minimal (proprietary) schema used for tests

            <dependency>
                <groupId>org.apache.directory.server</groupId>
                <artifactId>apacheds-all</artifactId>
                <version>1.5.7</version>
            </dependency>


  - apache LDAP API q.0.0-M20

            <dependency>
                <groupId>org.apache.directory.api</groupId>
                <artifactId>api-all</artifactId>
                <version>1.0.0-M20</version>
            </dependency>


Either running both in the same classloader or separately in different JREs
will give same error.

Comment: Running both in the same classloader will give an error on
duplicate schemas, so I have a local copy of the api-all JAR in Artifactory
from which I have stripped all schemas. They are accessible through the
server JAR so this should not be a problem.

In order to authenticate a user, I connect and bind to the object in the
directory (which by the way works just fine) but when I try to close the
connection things seems to lock up.

This is where it hangs:

LdapNetworkConnection.close():
    {
       ...
        // And close the connector if it has been created locally
        // Release the connector
        connectorMutex.lock();  <---- Here
       ...
    }


This is how I call this:

    public UserProfile validateUser(
            final String userDN, final String userCredential, final
UserProfileCreator profileCreator
    ) throws DirectoryException {

        LdapConnection connection = null;
        try {
            connection = new LdapNetworkConnection(host, port);
            if (!connection.connect()) {
                String info = "Could not connect to directory service";
                throw new DirectoryConnectionException(info);
            }

            BindRequest request = new BindRequestImpl();
            request.setName(userDN);
            request.setCredentials(userCredential);

            BindResponse response = connection.bind(request);

            ResultCodeEnum resultCode =
response.getLdapResult().getResultCode();
            if (ResultCodeEnum.SUCCESS != resultCode) {
                String info = "The bind failed with result code: " +
resultCode.name();
                log.info(info);
            }

            if (!connection.isAuthenticated()) {
                return null; // user does not exist or incorrect credential
            }

            Entry entry = connection.lookup(userDN); // have access to
private parts
            return profileCreator.create(entry);
        }
        catch (LdapException e) {
            String info = "Could not validate user \"" + userDN + "\"";
            throw new DirectoryReadException(info, e);
        }
        finally {
            if (null != connection) {
                try {
                    // Doing an unBind() will make me hang here, but a
close() will close the session
                    // as well - effectively doing an unbind
                    connection.setTimeOut(5);  // Has no effect
                    connection.close(); // <--- Hangs here
                }
                catch (Throwable t) {
                    String info = "Could not properly close the validation
connection: " + t.getMessage();
                    throw new DirectoryConnectionException(info, t);
                }
            }
        }
    }

  Regards, Frode.

Re: LdapNetworkConnection blocking on close()

Posted by Emmanuel Lécharny <el...@gmail.com>.
Le 1/15/14 6:03 PM, Frode Randers a écrit :
> I have this really simple setup;
>
>   - Java 1.7.0_40
>
>   - an embedded ApacheDS 1.5.7 listening on port 389 and prepared with a
> minimal (proprietary) schema used for tests
>
>             <dependency>
>                 <groupId>org.apache.directory.server</groupId>
>                 <artifactId>apacheds-all</artifactId>
>                 <version>1.5.7</version>
>             </dependency>
>
>
>   - apache LDAP API q.0.0-M20
>
>             <dependency>
>                 <groupId>org.apache.directory.api</groupId>
>                 <artifactId>api-all</artifactId>
>                 <version>1.0.0-M20</version>
>             </dependency>
>
>
> Either running both in the same classloader or separately in different JREs
> will give same error.
>
> Comment: Running both in the same classloader will give an error on
> duplicate schemas, 
apacheds-all.jar already contains api-all, that's explai why you have a
duplicate schema.

> so I have a local copy of the api-all JAR in Artifactory
> from which I have stripped all schemas. They are accessible through the
> server JAR so this should not be a problem.
>
> In order to authenticate a user, I connect and bind to the object in the
> directory (which by the way works just fine) but when I try to close the
> connection things seems to lock up.
>
> This is where it hangs:
>
> LdapNetworkConnection.close():
>     {
>        ...
>         // And close the connector if it has been created locally
>         // Release the connector
>         connectorMutex.lock();  <---- Here
>        ...
>     }


Weird... This lock is used in two places only.
>
>
> This is how I call this:
>
>     public UserProfile validateUser(
>             final String userDN, final String userCredential, final
> UserProfileCreator profileCreator
>     ) throws DirectoryException {
>
>         LdapConnection connection = null;
>         try {
>             connection = new LdapNetworkConnection(host, port);
>             if (!connection.connect()) {
>                 String info = "Could not connect to directory service";
>                 throw new DirectoryConnectionException(info);
>             }
>
>             BindRequest request = new BindRequestImpl();
>             request.setName(userDN);
>             request.setCredentials(userCredential);
>
>             BindResponse response = connection.bind(request);
>
>             ResultCodeEnum resultCode =
> response.getLdapResult().getResultCode();
>             if (ResultCodeEnum.SUCCESS != resultCode) {
>                 String info = "The bind failed with result code: " +
> resultCode.name();
>                 log.info(info);
>             }
>
>             if (!connection.isAuthenticated()) {
>                 return null; // user does not exist or incorrect credential
>             }
>
>             Entry entry = connection.lookup(userDN); // have access to
> private parts
>             return profileCreator.create(entry);
>         }
>         catch (LdapException e) {
>             String info = "Could not validate user \"" + userDN + "\"";
>             throw new DirectoryReadException(info, e);
>         }
>         finally {
>             if (null != connection) {
>                 try {
>                     // Doing an unBind() will make me hang here, but a
> close() will close the session
>                     // as well - effectively doing an unbind
>                     connection.setTimeOut(5);  // Has no effect
>                     connection.close(); // <--- Hangs here
>                 }
>                 catch (Throwable t) {
>                     String info = "Could not properly close the validation
> connection: " + t.getMessage();
>                     throw new DirectoryConnectionException(info, t);
>                 }
>             }
>         }
>     }
>
>   Regards, Frode.

Do you have a stacktrace, to can you provide a thread dump ?

At this point, I think it would be good to create a JIRA for the pb you
have.


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com