trixrabbit
trixrabbit

Reputation: 279

How to fix java.net.SocketException: Connection reset

I'm pretty sure i know the problem, I just don't know how to solve it.

I have a java EE application that do searches in ldap. I initialize the context with getEnv :

(note* : code is a bit simplified for understanding purposes)

InitialDirContext ctx = new InitialDirContext( getEnv( CONFIG_MAP ); //CONFIG_MAP contains  the host, mng_dn, mng_pw

public static Hashtable<String, String> getEnv( Map<String, String> configMap ) {

    // Hashtable for environmental information
    Hashtable<String, String> env = new Hashtable<String, String>();

    // Specify which class to use for our JNDI Provider
    env.put( Context.INITIAL_CONTEXT_FACTORY, INITCTX );

    // Specify the host and port to use for directory service
    env.put( Context.PROVIDER_URL, configMap.get( HOST ) );

    // Security Information
    env.put( Context.SECURITY_AUTHENTICATION, "simple" );
    env.put( Context.SECURITY_PRINCIPAL, configMap.get( MGR_DN ) );
    env.put( Context.SECURITY_CREDENTIALS, configMap.get( MGR_PW ) );
    env.put( "java.naming.ldap.attributes.binary", "objectSID" );

    return env;
}

I don't know if this was bad practice but to prevent the initialization from happening before every search I did an Init function that does :

if(Util.ctx == null ){
    Util.init()
}

So the problem comes from here. My application will work roughly 30 mins (not sure of the time) and then the searches won't work anymore and I'll get the connection reset error in my console. My guess is that the connection is "closed" and it's not doing the initialization again since ctx is not null. I need help to figure out what to add to my if statement in order to prevent this error from happening. Maybe something like

if(Util.ctx == null || Util.ctx.isClosed() ){
    Util.init();
}

I read on InitialDirContext and couldn't find what I need.

Upvotes: 2

Views: 11172

Answers (2)

user207421
user207421

Reputation: 310893

Don't try to keep reusing the same Context. Get a new one every time you need one. The server will close idle connections any time it feels like it, and isClosed() won't tell you when it has done so.

You can use the JNDI LDAP connection pooling feature to conserve connections.

Upvotes: 2

Jegg
Jegg

Reputation: 549

What about set no timeout as follows:

// Set up environment for creating initial context
Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, 
    "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Specify time-out to be infinite time . make it like never expired
env.put("com.sun.jndi.ldap.connect.timeout", "-1");

// Create initial context
DirContext ctx = new InitialDirContext(env);

And you can close it later when needed as follows:

finally {

        if (obj instanceof Context) {

            Context ctx = (Context) obj;
            try {
                ctx.close();
            }
            catch (Exception e) {

            }

        }
    }

Check this out: https://docs.oracle.com/javase/tutorial/jndi/newstuff/readtimeout.html

Upvotes: 1

Related Questions