Name: gm110360 Date: 03/26/2004
A DESCRIPTION OF THE REQUEST :
Using an unresolved SocketAddress for sending a DatagramPacket is counter-intuitive. Using such a socket causes the following stack trace to be printed:
java.lang.NullPointerException: null buffer || null address
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:611)
at client.NetworkTest.main(NetworkTest.java:62)
Test program:
DatagramSocket sk = new DatagramSocket( 2222 );
InetSocketAddress remAddr = InetSocketAddress.createUnresolved( "127.0.0.1", 161 );
DatagramPacket packet1 = new DatagramPacket( "Hellooo!".getBytes(), "Hellooo!".length(), remAddr );
sk.send( packet1 );
JUSTIFICATION :
The only way to determine the state of such a socket would be to call InetSocketAddress.isUnresolved() or InetSocketAddress.getAddress() == null . The InetSocketAddress.toString(), InetSocketAddress.hostName(), and InetSocketAddress.getPort() methods all return valid data.
The proper operation of the socket address appears to be valid; having checked the API documentation, I can say that the documentation isn't ambiguous. However, I would argue that the conversion of a String representation of an IP Address is a different matter from the resolution of that address against a name service. Also, the representation of an address as a port value and undetermined String doesn't quite make sense to me, the only way to obtain an InetAddress from the unresolved InetSocketAddress would be to call back to new InetSocketAddress( unresolvedAddr.getHostName() ) ...
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the createUnresolved method to convert the String parameter to an address, of any matching family, and to do so without performing a naming lookup for that address value. In other words,
instead of creating an InetSocketAddress like so:
skAddr = InetSocketAddress.createUnresolved( "1.0.0.1", 7 );
// this appears to be a very unuseful construct, I cannot set the InetAddress from anywhere
skAddr {
String hostname = "1.0.0.1";
InetAddress = null;
}
It would be much more useful to construct it like so:
skAddr {
String hostname = null;
InetAddress = byte[] < 1, 0, 0, 1>;
}
Further, the class provides little or no distinction between an object that was resolved, was resolved unsuccessfully, received an exception while resolving, and was never resolved. It might be better to have the hostname member defined as an object and assign it a naming object or an exception depending on whether or not a resolution call was made.
The lifetime of the resolved String is an issue particularly for applications whose lifetime exceeds that validity period for some naming object; whether that be a resolution from a DNS server with a specified TTL, or a naming cache whose validity period is shorter than the duration of the hostname String.
The class should have a boolean unresolved flag indicating whether or not a resolution attempt was made, the flag should be set regardless of the result or exception status of the naming lookup.
In short, the createUnresolved method should perform as per InetAddress.getByName( String host ) with the exception that if the conversion from String to IP fails, the InetSocketAddress.addr memeber should be initialised with the result of calling InetAddress.getByName( null );
ACTUAL -
The API documentation states that the returned object will be flagged as unresolved. This isn't the case, the InetAddress of the object is set to null.
The createUnresolved method constructs an immutable InetSocketAddress with the given string as the hostname and the given port value as the port exactly as indicated by the API document.
The createUnresolved doesn't actually construct an InetSocketAddress, it assigns values to a partially constructed InetSocketAddress: String inetSocketAddress = "127.0.0.1:21"; would be preferable.
---------- BEGIN SOURCE ----------
DatagramSocket sk = new DatagramSocket( 2222 );
InetSocketAddress remAddr = InetSocketAddress.createUnresolved( "127.0.0.1", 161 );
DatagramPacket packet1 = new DatagramPacket( "Hellooo!".getBytes(), "Hellooo!".length(), remAddr );
---------- END SOURCE ----------
(Incident Review ID: 245061)
======================================================================
###@###.### 10/8/04 16:17 GMT
A DESCRIPTION OF THE REQUEST :
Using an unresolved SocketAddress for sending a DatagramPacket is counter-intuitive. Using such a socket causes the following stack trace to be printed:
java.lang.NullPointerException: null buffer || null address
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:611)
at client.NetworkTest.main(NetworkTest.java:62)
Test program:
DatagramSocket sk = new DatagramSocket( 2222 );
InetSocketAddress remAddr = InetSocketAddress.createUnresolved( "127.0.0.1", 161 );
DatagramPacket packet1 = new DatagramPacket( "Hellooo!".getBytes(), "Hellooo!".length(), remAddr );
sk.send( packet1 );
JUSTIFICATION :
The only way to determine the state of such a socket would be to call InetSocketAddress.isUnresolved() or InetSocketAddress.getAddress() == null . The InetSocketAddress.toString(), InetSocketAddress.hostName(), and InetSocketAddress.getPort() methods all return valid data.
The proper operation of the socket address appears to be valid; having checked the API documentation, I can say that the documentation isn't ambiguous. However, I would argue that the conversion of a String representation of an IP Address is a different matter from the resolution of that address against a name service. Also, the representation of an address as a port value and undetermined String doesn't quite make sense to me, the only way to obtain an InetAddress from the unresolved InetSocketAddress would be to call back to new InetSocketAddress( unresolvedAddr.getHostName() ) ...
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expect the createUnresolved method to convert the String parameter to an address, of any matching family, and to do so without performing a naming lookup for that address value. In other words,
instead of creating an InetSocketAddress like so:
skAddr = InetSocketAddress.createUnresolved( "1.0.0.1", 7 );
// this appears to be a very unuseful construct, I cannot set the InetAddress from anywhere
skAddr {
String hostname = "1.0.0.1";
InetAddress = null;
}
It would be much more useful to construct it like so:
skAddr {
String hostname = null;
InetAddress = byte[] < 1, 0, 0, 1>;
}
Further, the class provides little or no distinction between an object that was resolved, was resolved unsuccessfully, received an exception while resolving, and was never resolved. It might be better to have the hostname member defined as an object and assign it a naming object or an exception depending on whether or not a resolution call was made.
The lifetime of the resolved String is an issue particularly for applications whose lifetime exceeds that validity period for some naming object; whether that be a resolution from a DNS server with a specified TTL, or a naming cache whose validity period is shorter than the duration of the hostname String.
The class should have a boolean unresolved flag indicating whether or not a resolution attempt was made, the flag should be set regardless of the result or exception status of the naming lookup.
In short, the createUnresolved method should perform as per InetAddress.getByName( String host ) with the exception that if the conversion from String to IP fails, the InetSocketAddress.addr memeber should be initialised with the result of calling InetAddress.getByName( null );
ACTUAL -
The API documentation states that the returned object will be flagged as unresolved. This isn't the case, the InetAddress of the object is set to null.
The createUnresolved method constructs an immutable InetSocketAddress with the given string as the hostname and the given port value as the port exactly as indicated by the API document.
The createUnresolved doesn't actually construct an InetSocketAddress, it assigns values to a partially constructed InetSocketAddress: String inetSocketAddress = "127.0.0.1:21"; would be preferable.
---------- BEGIN SOURCE ----------
DatagramSocket sk = new DatagramSocket( 2222 );
InetSocketAddress remAddr = InetSocketAddress.createUnresolved( "127.0.0.1", 161 );
DatagramPacket packet1 = new DatagramPacket( "Hellooo!".getBytes(), "Hellooo!".length(), remAddr );
---------- END SOURCE ----------
(Incident Review ID: 245061)
======================================================================
###@###.### 10/8/04 16:17 GMT