Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4256129
Votes 3
Synopsis DNS resolution fails even when name has been added.
Category java:classes_net
Reported Against 1.2.1 , 1.2.2
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 4330985 , 4354354
Submit Date 21-JUL-1999
Description




-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) 
======================================================================




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)
======================================================================
Work Around




Restart the java application. :( This is unacceptable (for us)
as the application we are running is meant to be a stand alone
server app. that restarts on its own at system boot time.
======================================================================




Restart the application, not accepted solution.
(Review ID: 101200)
======================================================================
Evaluation
 xxxxx@xxxxx  2000-04-13
We cache negative lookup which we probably shouldn't. At the least there should be a way to turn this off.
Comments
  
  Include a link with my name & email   

Submitted On 18-FEB-2000
plundin
This seem to toggle the caching policy in jdk 1.2.1:
java -Dsun.net.inetaddr.ttl=0
this is the property that the sun.net.InetAddressCachePolicy
is using and which in turn are used by java.net.InetAddress.


Submitted On 28-JUL-2000
abrighto
The problem is not fixed in jdk1.3 beta refresh. Is it
supposed to be fixed already?


Submitted On 18-DEC-2000
lindamarcella
is there a way to clear the UnknownHostException in 
jdk1.2.2?


Submitted On 18-DEC-2000
lindamarcella
at first java -Dsun.net.inetaddr.ttl=0 didn't work for me, 
but then adding the statement:
   import sun.net.InetAddressCachePolicy;
fixed it


Submitted On 30-NOV-2001
johnR
This is still broken in Java HotSpot(TM) Client VM (build 
1.3.1_01, mixed mode). Observed on W2k. java -
Dsun.net.inetaddr.ttl=0 workaround works.


Submitted On 16-APR-2002
net_ma
Looks to me this problem still there for jdk1.3.1_03 on 
Linux. I use InetAddress.getByName(host) to a dynamically 
dns served dial-up site, every time the IP address changes, 
getByName fails and I have to restart the virtual machine, 
which is tomcat in my case. Anybody could tell me if it 
indeed is still a bug in jdk1.3.1 or I did some thing 
inccorect.


Submitted On 28-MAY-2003
jcrossley
I think it's still broken in Sun's JDK 1.4.1 for Linux.  I
can set networkaddress.cache.negative.ttl=0 to disable
caching entirely, but the default 10 second TTL does NOT
seem to work -- failed lookups appear to cache forever.


Submitted On 25-JUN-2004
javabits
For Java 1.4.2 you need to edit the java security property network.address.cache.ttl and networkaddress.cache.negative.ttl. This is actually documented in the InetAddress javadoc. Not sure if this also applies to older versions of 1.4, but I imagine if you check the javadoc for that version you'll find out. The java.security file actually says that the default is to cache dns resolution forever because of dns spoofing issues, personally I think this is bad because it breaks thinks like round robin dns. DNS spoofing should be fixed by the people who administer the dns servers and not by java.



PLEASE NOTE: JDK6 is formerly known as Project Mustang