Name: dbT83986 Date: 07/21/99
-Synopsis-
The following problem was seen with jdk 1.2.2 and 1.2.2:
An application attempts to do name resolution on a domain name
that does not exist in the DNS (windows NT resolver (
tested via nslookup) cannot resolve host). An
UnknownHostException is generated. The DNS is updated to c
ontain the name (while the app is still running). At this
point, the nt resolver can resolve the name, but the java
application still generates the UnknownHostException. The
system should call the resolver every time, getByName is
called. This behavior is seen with both the InetAddress.getByName
and InetAddress.getAllByName calls.
This behavior is end user visible and adversly effects the
reliablity of our software in the eyes of our clients.
-Steps to recreate the problem-
1. pick a target machine (in my case a box called wedge)
2. comment out its line in the DNS
3. check that the name wedge does not resolve.
3. restart the dns so it rereads the zone
4. run netTest (my test program): java netTest wedge
5. comment the target machine back into the dns
6. restart the dns so it rereads the zone
7. check that wedge does resolve.
8. check that netTest is still spewing exceptions.
9. sit and wait for netTest to actually call the resolver
10. sit and wait...
11. ..
12. .
13. Get bored and kill netTest.
-Source Code-
/*
netTest.java -test the freaking resolver
Kamil Pawlowski 210799 created
*/
import java.lang.*;
import java.net.*;
public class netTest implements Runnable {
InetAddress hostAddr;
String host;
public netTest(String s){
hostAddr = null;
host = new String(s);
}
//netTest
public static void main(String args[]){
try {
if (args.length != 1){
System.out.println("Usage: java netTest <host>");
System.exit(0);
}
netTest tryOne = new netTest(args[0].toString());
tryOne.run();
} catch (Exception e){
System.out.println("Exception : " + e.getMessage());
e.printStackTrace();
}
}
//main
public void run() {
int cnt =0; //count the number of times we've tried this.
System.out.println("[run] started");
while (true) {
try { //outer block for all threads
try { //inner block for actual work
//comment/uncomment the bit you want to use
//I know I should technically be using a
//command line switch for this, but I'm too lazy.
//just change the comments.
//hostAddr = InetAddress.getByName(host) ;
InetAddress[] ha= InetAddress.getAllByName(host);
hostAddr = ha[0];
System.out.println("host: " + host + " Address: " +
hostAddr.getHostAddress() + " " + cnt);
} catch (UnknownHostException e){
System.out.println("Exception Unknown Host: " + host + " " +cnt);
e.printStackTrace();
} catch (Exception e1){
//something weird happend so stop and exit
System.out.println("Exception at loop " + cnt +
":" + e1.getMessage());
e1.printStackTrace();
System.exit(0);
} finally {
hostAddr =null;
}
//try-catch
//now stop and wait for a bit. See what the heck its actually
//doing.
Thread.sleep(1000);
} catch (Exception e2) {
System.out.println("Exception :" + e2.getMessage());
e2.printStackTrace();
}
//try-catch
cnt++;
}
//while
}
//run
}
//netTest
-Text of Error Messages-
(note:
The first is the error message generated when
getAllByName is used. Next is the error message
generated when getByName is used.
41 is a sequence number, this is how many times (+1)
this message appeared before I cut it off. A similar
sequence number is included for getByName. The program
pauses between attempts to invoke the resolver so
this takes that into account and lets me see that its
actually retrying. One could actually let it run for
longer, but I can't see a difference.)
Exception Unknown Host: wedge 41
java.net.UnknownHostException: wedge
at java.net.InetAddress.getAllByName0(InetAddress.java:577)
at java.net.InetAddress.getAllByName0(InetAddress.java:546)
at java.net.InetAddress.getAllByName(InetAddress.java:539)
at netTest.run(netTest.java, Compiled Code)
at netTest.main(netTest.java:26)
Exception Unknown Host: wedge 71
java.net.UnknownHostException: wedge
at java.net.InetAddress.getAllByName0(InetAddress.java:577)
at java.net.InetAddress.getAllByName0(InetAddress.java:546)
at java.net.InetAddress.getByName(InetAddress.java, Complied Code)
at netTest.run(netTest.java, Compiled Code)
at netTest.main(netTest.java:26)
-Output of Java -version and Java -fullversion-
C:\java -version
java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)
C:\java -fullversion
java full version "JDK-1.2.2-W"
(Review ID: 88212)
======================================================================
Name: skT88420 Date: 02/14/2000
java version "1.2.1"
Classic VM (build JDK-1.2.1-A, native threads)
When using a java.net.Socket on a machine with dial-up connection
that is not connected you get as expected a java.net.UnknownHostException
When keeping the application up and dialing up a connection
and try to open a Socket to the same host you still get a
UnknownHostException.
Solution is to restart the application using the Socket which is hardly
accepted, I assume this is related to bug 4256129 since it seems the
DNS is not resolved again if it fails once.
To test this use the following code and follow these steps:
on a machine with dial-up connection
1. Make sure you are not connected, start the TestSocket program
and press the button, it should say "Failed !"
2. While keeping the application up, dial-up a connection
3. When the connection is established try to press the button again,
the connection SHOULD say "OK" but instead it says "Failed !"
This problem does not appear with JRE 1.1.7B
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
public class TestSocket extends Frame implements ActionListener{
Button b;
TextField txt;
public
TestSocket()
{
b = new Button( "Test" );
txt = new TextField( 30 );
b.addActionListener( this );
setLayout( new GridLayout( 2, 1 ) );
add( b );
add( txt );
pack();
setVisible( true );
}
public static void
main( String args[] )
{
new TestSocket();
}
public void
testSocket()
{
OutputStream o = null;
Socket s = null;
try{
s = new Socket( "javathings.com", 80 );
o = s.getOutputStream();
txt.setText( "OK !" );
}
catch( Exception e )
{
txt.setText( "Failed ! " + e.getMessage() );
}
finally
{
try{ s.close(); }catch( Exception i ){}
}
}
public void
actionPerformed( ActionEvent e )
{
if( e.getSource() == b ) testSocket();
}
}
(Review ID: 101200)
======================================================================