Skip to content
Permalink
Browse files
8273402: Use derived NamingExceptions in com.sun.jndi.ldap.Connection…
…#readReply

Reviewed-by: dfuchs
  • Loading branch information
AlekseiEfimov committed Sep 10, 2021
1 parent 4e6de5f commit c464f09056c239f701b400a5c59c54646f840391
Showing 3 changed files with 38 additions and 28 deletions.
@@ -425,7 +425,7 @@ LdapRequest writeRequest(BerEncoder ber, int msgId,
/**
* Reads a reply; waits until one is ready.
*/
BerDecoder readReply(LdapRequest ldr) throws IOException, NamingException {
BerDecoder readReply(LdapRequest ldr) throws NamingException {
BerDecoder rber;

// If socket closed, don't even try
@@ -436,7 +436,7 @@ BerDecoder readReply(LdapRequest ldr) throws IOException, NamingException {
}
}

NamingException namingException = null;
IOException ioException = null;
try {
// if no timeout is set so we wait infinitely until
// a response is received OR until the connection is closed or cancelled
@@ -445,25 +445,29 @@ BerDecoder readReply(LdapRequest ldr) throws IOException, NamingException {
} catch (InterruptedException ex) {
throw new InterruptedNamingException(
"Interrupted during LDAP operation");
} catch (CommunicationException ce) {
// Re-throw
throw ce;
} catch (NamingException ne) {
} catch (IOException ioe) {
// Connection is timed out OR closed/cancelled
namingException = ne;
// getReplyBer throws IOException when the requests needs to be abandoned
ioException = ioe;
rber = null;
}

if (rber == null) {
abandonRequest(ldr, null);
}
// namingException can be not null in the following cases:
// ioException can be not null in the following cases:
// a) The response is timed-out
// b) LDAP request connection has been closed or cancelled
// b) LDAP request connection has been closed
// If the request has been cancelled - CommunicationException is
// thrown directly from LdapRequest.getReplyBer, since there is no
// need to abandon request.
// The exception message is initialized in LdapRequest::getReplyBer
if (namingException != null) {
// Re-throw NamingException after all cleanups are done
throw namingException;
if (ioException != null) {
// Throw CommunicationException after all cleanups are done
String message = ioException.getMessage();
var ce = new CommunicationException(message);
ce.initCause(ioException);
throw ce;
}
return rber;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,17 +103,17 @@ synchronized boolean addReplyBer(BerDecoder ber) {
* @param millis timeout, infinite if the value is negative
* @return BerDecoder if reply was read successfully
* @throws CommunicationException request has been canceled and request does not need to be abandoned
* @throws NamingException request has been closed or timed out. Request does need to be abandoned
* @throws InterruptedException LDAP operation has been interrupted
* @throws IOException request has been closed or timed out. Request does need to be abandoned
* @throws InterruptedException LDAP operation has been interrupted
*/
BerDecoder getReplyBer(long millis) throws NamingException,
BerDecoder getReplyBer(long millis) throws IOException, CommunicationException,
InterruptedException {
if (cancelled) {
throw new CommunicationException("Request: " + msgId +
" cancelled");
}
if (isClosed()) {
throw new NamingException(CLOSE_MSG);
throw new IOException(CLOSE_MSG);
}

BerDecoder result = millis > 0 ?
@@ -126,11 +126,11 @@ BerDecoder getReplyBer(long millis) throws NamingException,

// poll from 'replies' blocking queue ended-up with timeout
if (result == null) {
throw new NamingException(String.format(TIMEOUT_MSG_FMT, millis));
throw new IOException(String.format(TIMEOUT_MSG_FMT, millis));
}
// Unexpected EOF can be caused by connection closure or cancellation
if (result == EOF) {
throw new NamingException(CLOSE_MSG);
throw new IOException(CLOSE_MSG);
}
return result;
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,14 @@

/*
* @test
* @bug 8062947
* @summary Test that NamingException message text matches the failure reason
* @bug 8062947 8273402
* @summary Test that CommunicationException is thrown when connection is timed out or closed/cancelled,
* and it's text matches the failure reason.
* @library /test/lib lib
* @run testng NamingExceptionMessageTest
*/

import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.ServiceUnavailableException;
@@ -55,9 +57,10 @@ public void timeoutMessageTest() throws Exception {
ldapServer.start();
ldapServer.awaitStartup();
var env = ldapServer.getInitialLdapCtxEnvironment(TIMEOUT_VALUE);
var namingException = Assert.expectThrows(NamingException.class, () -> new InitialDirContext(env));
System.out.println("Got naming exception:" + namingException);
Assert.assertEquals(namingException.getMessage(), EXPECTED_TIMEOUT_MESSAGE);
var communicationException =
Assert.expectThrows(CommunicationException.class, () -> new InitialDirContext(env));
System.out.println("Got CommunicationException:" + communicationException);
Assert.assertEquals(communicationException.getMessage(), EXPECTED_TIMEOUT_MESSAGE);
}
}

@@ -74,9 +77,12 @@ public void connectionClosureMessageTest() throws Exception {
// read-out of the reply message. For such cases test run is considered as successful.
System.out.println("Got ServiceUnavailableException: Test PASSED");
} else {
// If exception is not ServiceUnavailableException - check the exception message
System.out.println("Got NamingException:" + namingException);
Assert.assertEquals(namingException.getMessage(), EXPECTED_CLOSURE_MESSAGE);
// If exception is not ServiceUnavailableException, CommunicationException is expected
Assert.assertTrue(namingException instanceof CommunicationException);
var communicationException = (CommunicationException) namingException;
System.out.println("Got CommunicationException:" + communicationException);
// Check exception message
Assert.assertEquals(communicationException.getMessage(), EXPECTED_CLOSURE_MESSAGE);
}
}
}

1 comment on commit c464f09

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on c464f09 Sep 10, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.