[jira] [Commented] (CASSANDRA-15111) StorageService.move() throws RuntimeException when interrupted

2019-05-09 Thread eBugs (JIRA)


[ 
https://issues.apache.org/jira/browse/CASSANDRA-15111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16836680#comment-16836680
 ] 

eBugs commented on CASSANDRA-15111:
---

Thanks a lot Jon! Your explanation make sense to me. Even if the exception will 
not be logged at the default level, I think it can still be helpful to wrap the 
cause exception, especially for debugging purpose.

Thanks for tagging this for 4.x.

> StorageService.move() throws RuntimeException when interrupted
> --
>
> Key: CASSANDRA-15111
> URL: https://issues.apache.org/jira/browse/CASSANDRA-15111
> Project: Cassandra
>  Issue Type: Bug
>  Components: Observability/JMX, Tool/nodetool
>Reporter: eBugs
>Priority: Low
> Fix For: 4.x
>
>
> Dear Cassandra developers, we are developing a tool to detect 
> exception-related bugs in Java. Our prototype has spotted the following 
> {{throw}} statement whose exception class and error message indicate 
> different error conditions.
>  
> Version: Cassandra-3.11 (commit: 123113f7b887370a248669ee0db6fdf13df0146e) 
> File: CASSANDRA-ROOT/src/java/org/apache/cassandra/service/StorageService.java
> Line: 4168
> {code:java}
> try
> {
> relocator.stream().get();
> }
> catch (ExecutionException | InterruptedException e)
> {
> throw new RuntimeException("Interrupted while waiting for stream/fetch 
> ranges to finish: " + e.getMessage());
> }
> {code}
>  
> {{RuntimeException}} is usually used to represent errors in the program logic 
> (think of one of its subclasses, {{NullPointerException}}), while the error 
> message indicates that an interrupt has occurred. This mismatch could be a 
> problem. For example, the callers may miss the possibility that 
> {{StorageService.move()}} can be interrupted because it does not throw any 
> {{InterruptedException}}. Or, the callers trying to handle other 
> {{RuntimeException}} may accidentally (and incorrectly) handle the interrupt.
>  
> If throwing a {{RuntimeException}} is preferred, maybe it can wrap the cause 
> exception so that the inner call stack is preserved.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

-
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org



[jira] [Commented] (CASSANDRA-15111) StorageService.move() throws RuntimeException when interrupted

2019-05-09 Thread Jon Meredith (JIRA)


[ 
https://issues.apache.org/jira/browse/CASSANDRA-15111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16836656#comment-16836656
 ] 

Jon Meredith commented on CASSANDRA-15111:
--

Thanks for trying out your tool on Cassandra and reporting your findings.

The {{StorageService.move}} call is invoked by {{nodetool}} when the operator 
wants to move the tokens owned by the node. The catch is being used to convert 
from checked to unchecked exceptions. Looking at StorageServerMbean, the 
interface has gone back and forth between checked/unchecked exceptions over 
time.

I can't see a way where this could fail to be handled with current usage and 
don't think there's an immediate need to make a change, and I know that 
operational systems parse the log stream generated by Cassandra so I don't want 
to risk breaking any tooling in a patch release that I have no way to audit.

As you say it would be possible for the interrupted/execution exception to be 
wrapped (although I don't think it would ever be output anywhere tracing 
through the default logging), and agree it would be better to do that. I've 
tagged this issue for 4.next.

I didn't provoke an Interrupted/ExecutionException, but did check that 
exceptions are making it through to logs and nodetool correctly

{panel:title=log}
ERROR [RMI TCP Connection(2)-x.x.x.x] 2019-05-09 10:29:36,965 
StorageService.java:4149 - Invalid request to move(Token); This node has more 
than one token and cannot be moved thusly.
{panel}

{panel:title=nodetool outtput}
$ bin/nodetool  move 0
error: This node has more than one token and cannot be moved thusly.
-- StackTrace --
java.lang.UnsupportedOperationException: This node has more than one token and 
cannot be moved thusly.
at 
org.apache.cassandra.service.StorageService.move(StorageService.java:4150)
at 
org.apache.cassandra.service.StorageService.move(StorageService.java:4125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at 
com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:112)
at 
com.sun.jmx.mbeanserver.StandardMBeanIntrospector.invokeM2(StandardMBeanIntrospector.java:46)
at 
com.sun.jmx.mbeanserver.MBeanIntrospector.invokeM(MBeanIntrospector.java:237)
at com.sun.jmx.mbeanserver.PerInterface.invoke(PerInterface.java:138)
at com.sun.jmx.mbeanserver.MBeanSupport.invoke(MBeanSupport.java:252)
at 
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at 
com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at 
javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
at 
javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at 
javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
at 
javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
at 
javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at 
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
at 
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at