Bug 24956 - Compiler misdiagnoses exception sequence
Summary: Compiler misdiagnoses exception sequence
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 1.0   Edit
Hardware: PC Windows XP
: P3 minor (vote)
Target Milestone: 2.1 M3   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-10-17 09:10 EDT by Jonathan Gossage CLA
Modified: 2002-10-18 04:57 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Gossage CLA 2002-10-17 09:10:09 EDT
Consider the following code sequence.

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

  
public class maskedException {
    private DatagramSocket  _socket = null;
    
         maskedException() throws Exception {
            try {
               _socket = new DatagramSocket( 5000,InetAddress.getLocalHost() );
            }
            catch (SocketException e) {
               throw new Exception();
            }
            catch (UnknownHostException e) {
                throw new Exception();
            }
******      catch (IOException e) {
               throw new Exception();
            }
         }

The compiler issues a diagnostic stating "Catch block is hidden by another one 
in the same try statement"

The diagnostic is only triggered when the catch blocks throw a new exception. 
Any other code in the catch blocks does not cause a problem.

The code sequence is normal in the sense that most specific exceptions are 
caught first and most general exceptions last. This code does not generate a 
diagnostic with either the JBuilder compiler or the Sun compiler from JDK 
1.3.1-04.
Comment 1 Philipe Mulet CLA 2002-10-17 12:25:30 EDT
It is only an extra warning we produce. If you did write your code in 2 nested 
try statements, wouldn't it report an error with the other compilers ? If no, 
then I agree we have a bug. But I guess it does, and we give you an advanced 
warning for this scenario (I guess that for the catch block to be reachable, a 
non declared exception would need to be thrown, which might indicate a binary 
compatibility issue: the constructor for DatagramSocket you are using to 
compile against isn't the same that you run against).

Doesn't this fail to compile with other compilers ? 
      try {
            try {
               _socket = new DatagramSocket( 5000,InetAddress.getLocalHost() );
            }
            catch (SocketException e) {
               throw new Exception();
            }
            catch (UnknownHostException e) {
                throw new Exception();
            }
      catch (IOException e) {
          throw new Exception();
      }
Comment 2 Philipe Mulet CLA 2002-10-17 12:29:04 EDT
Humm, actually, I take my previous comment back. We seem to have a bug. The 
nested scenario doesn't report a problem. 

You are absolutely right, we should not complain.
Comment 3 Jonathan Gossage CLA 2002-10-17 12:44:24 EDT
On the other side of the coin, though, it turns out that in all three cases 
where we had this kind of code sequence, using the Sun JDK 1.3.1-04 and your 
M1 compiler the IOException was not being thrown. Thus at least this prompted 
us to remove some obselete code.

It might be useful in fact if the compiler could recognize that the last 
exception in the chain could not be caught because it was not being thrown, 
only derived exceptions that were caught.

BTW the code snippet you sent me compiles OK on JBuilder and the Sun compiler.
Comment 4 Philipe Mulet CLA 2002-10-18 04:43:11 EDT
Actually, I think our behavior is correct. The reason why the nested case 
compiles ok (even with our compiler) is due to the fact that Exception(s) are 
rethrown in the catch block clauses. These exception are thus to be handled by 
the outermost try/catch.

This becomes obvious with some slight change in your code (javac will diagnose 
that IOException isn't reachable - like Eclipse compiler).

	void maskedException() throws Exception {
		boolean broken = false;
		try { 
			try {
				_socket = new DatagramSocket(5000, 
InetAddress.getLocalHost());
			} catch (SocketException e) {
				broken = true;
			} catch (UnknownHostException e) {
				broken = true;
			}
		} catch (IOException e) {
			broken = true;
		}
		if (broken) throw new Exception();
	}

You can observe that this one is an error, as opposed to the advanced warning 
notification we gave you in the flatten case (and you can turn off this extra 
warning: Window>Preferences>Java>Compiler>Hidden catch blocks>Ignore).

Is it ok to close then ?
Comment 5 Philipe Mulet CLA 2002-10-18 04:57:36 EDT
Closing, please reopen if you feel we are still wrong.