Details
-
Bug
-
Status: Open
-
Critical
-
Resolution: Unresolved
-
None
-
None
Description
What happened:
Test TestRPC#testReaderExceptions assumes there is a RemoteException has been thrown and directly cast the root cause of ServiceException to RemoteException. But this cast may lead to ClassCastException when the root cause exception is not RemoteException.
Buggy code:
@Test (timeout=30000) public void testReaderExceptions() throws Exception { ... try { FakeRequestClass.exception = doDisconnect ? rseFatal : rseError; proxy.ping(null, newEmptyRequest()); fail(reqName + " didn't fail"); } catch (ServiceException e) { RemoteException re = (RemoteException)e.getCause(); // <--- Here the test assumes the root cause is RemoteException assertEquals(reqName, expectedIOE, re.unwrapRemoteException()); }
How to reproduce:
(1) Set hadoop.security.authentication to kerberos
(2) Run test TestRPC#testReaderExceptions
Stack trace:
java.lang.ClassCastException: class java.io.IOException cannot be cast to class org.apache.hadoop.ipc.RemoteException (java.io.IOException is in module java.base of loader 'bootstrap'; org.apache.had oop.ipc.RemoteException is in unnamed module of loader 'app') at org.apache.hadoop.ipc.TestRPC.testReaderExceptions(TestRPC.java:1742) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:299) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:293) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.lang.Thread.run(Thread.java:829)
Fix:
A better way to do is to firstly check whether the root cause is RemoteException, if not, fail the test rather than causing the CastClassException:
try { FakeRequestClass.exception = doDisconnect ? rseFatal : rseError; proxy.ping(null, newEmptyRequest()); fail(reqName + " didn't fail"); } catch (ServiceException e) { if (e.getCause() instanceof RemoteException) { RemoteException re = (RemoteException)e.getCause(); assertEquals(reqName, expectedIOE, re.unwrapRemoteException()); } else { fail(reqName + " didn't fail with RemoteException"); } }
Attachments
Attachments
Issue Links
- links to