Remaining doclint issues in java.net

Chris Hegarty chris.hegarty at oracle.com
Fri Aug 2 09:37:13 UTC 2013


comments inline...

On 01/08/2013 22:18, Stuart Marks wrote:
> On 7/31/13 2:39 PM, Matthew Hall wrote:
>> On Wed, Jul 31, 2013 at 02:38:26PM -0700, Stuart Marks wrote:
>>> The alternative is to add "@throws SocketException never" to the
>>> javadoc, just to get rid of the doclint warning, but this has the
>>> consequence of requiring people to keep dead code around
>>> indefinitely, and furthermore it requires them to add new dead code
>>> every time they create a DatagramPacket.
>>
>> I have never understood in many years using Java why the compiler
>> generates
>> errors about attempting to catch supposedly-impossible exceptions,
>> instead of
>> warnings.
>>
>> For me it only leads to difficulties when I'm trying to write
>> prototypes or
>> refactor and clean up some old brittle code, and I run into that rather
>> dubious sort of error.
>>
>> This is a good example of where it causes more harm than good. Is
>> there still
>> a really good reason for this over-paranoid compiler error given that
>> checked
>> exceptions aren't as popular as they used to be anyways?
>
> I don't have the definitive answer, but it was a very early Java design
> decision to make unreachable code be a compilation error instead of a
> warning. This is a matter of judgment, of course; reasonable people come
> down on different sides of this, for different cases. For example, see
> this Stackoverflow conversation:
>
> http://stackoverflow.com/questions/3795585/why-does-java-have-an-unreachable-statement-compiler-error
>
>
> * * *
>
> Meanwhile, I did a little bit of studying about DatagramPacket. The
> doclint warnings occur on two of the six DatagramPacket constructors:
>
> DatagramPacket(byte[] buf, int len, SocketAddress sa)
> DatagramPacket(byte[] buf, int off, int len, SocketAddress sa)
>
> There are two other equivalent overloaded constructors that take
> InetAddress and port arguments:
>
> DatagramPacket(byte[] buf, int len, InetAddress ia, int port)
> DatagramPacket(byte[] buf, int off, int len, InetAddress ia, int port)
>
> To my eye the InetAddress/port constructors are used quite a bit more
> often than the SocketAddress ones. I did a web search for "java
> DatagramPacket example" and looked at all the examples on the first page
> of hits. All of them used the InetAddress+port constructor overloads
> (including the Oracle Java tutorial). I didn't see any uses of the
> SocketAddress overloads.
>
> I also did an ohloh search for "new DatagramPacket(":
>
> http://code.ohloh.net/search?s=%22new%20DatagramPacket%28%22&p=2&pp=0&fl=Java&mp=1&ml=1&me=1&md=1&ff=1&filterChecked=true

Thank you Stuart, this is really helpful.

> (HT: Dalibor)
>
> I looked through around 100 examples, and the vast majority of them use
> the InetAddress+port overloads. I saw three examples that use the

I would tend to agree with this, the InetAddress+port are probably most 
commonly used. The SocketAddress variants are useful when you have 
already constructed an InetSocketAddress elsewhere and pass it into the 
method that creates/sends the packet. I can only find this sort of code 
in tests.

Also worth noting is that typically datagram packets are created in 
close proximity to the code that sends them, and the sending of a packet 
requires handling IOE. This, IMO, further reduces the impact of removing 
'throw SE'.

> SocketAddress overloads. Two of them were within methods that declared
> "throws Exception." The third was within a try/catch block that catches
> IOException. None of the three cases would suffer a source incompatibility.

I cannot comment on the code you are talking about, but removing 'throws 
SE' from these constructors will affect anyone that is catching IOE ( 
since SE is a subclass of IOE ). Simple test:

: cat ThrowingCtrs.java
import java.net.*;
import java.io.IOException;

public class ThrowingCtrs {

     public static void main(String[] args) {
         SocketAddress sa = new InetSocketAddress("127.0.0.1", 45678);

         // DatagramPacket(byte[], int, SocketAddress)
         try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
         catch (SocketException x) { }

         try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
         catch (IOException x) { }

         try { DatagramPacket dp = new DatagramPacket(new byte[1], 1, sa); }
         catch (Exception x) { }

         // DatagramPacket(byte[], int, int, SocketAddress)
         try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, 
sa); }
         catch (SocketException x) { }

         try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, 
sa); }
         catch (IOException x) { }

         try { DatagramPacket dp = new DatagramPacket(new byte[1], 0, 1, 
sa); }
         catch (Exception x) { }
     }
}

Output of javac from a build with SE removed.
  build/solaris-x86_64-normal-server-release/jdk/bin/javac ThrowingCtrs.java
ThrowingCtrs.java:11: error: exception SocketException is never thrown 
in body of corresponding try statement
         catch (SocketException x) { }
         ^
ThrowingCtrs.java:14: error: exception IOException is never thrown in 
body of corresponding try statement
         catch (IOException x) { }
         ^
ThrowingCtrs.java:21: error: exception SocketException is never thrown 
in body of corresponding try statement
         catch (SocketException x) { }
         ^
ThrowingCtrs.java:24: error: exception IOException is never thrown in 
body of corresponding try statement
         catch (IOException x) { }
         ^
4 errors

> This isn't definitive, of course, but it does seem to supply some
> evidence that making this change would result in a relatively minor
> source incompatibility.

Given the above, I still agree with the sentiment here. I will file a 
bug and proceed with the necessary changes to remove SE.

Thanks again,
-Chris.

>
> s'marks



More information about the core-libs-dev mailing list