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: 5092063
Votes 50
Synopsis Extremely slow socket creation using new Socket("ip-address", port)
Category java:classes_net
Reported Against b03 , tiger-beta2
Release Fixed mustang(beta), 5.0u6(b02) (Bug ID:2128319)
State 10-Fix Delivered, request for enhancement
Priority: 2-High
Related Bugs 6287178 , 6223354 , 6224843
Submit Date 25-AUG-2004
Description


FULL PRODUCT VERSION :
java version "1.5.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows XP professional SP1

EXTRA RELEVANT SYSTEM CONFIGURATION :
simple LAN network, 1router, 1 PC, router contains DNS,  DHCP, etc. router connected to Internet

A DESCRIPTION OF THE PROBLEM :
The creation of a socket using new Socket("ip-address", port) seems to be extremely slow. On my machine it takes up to 5 seconds to create the socket. Multiple sockets (in sequence, not parallel) take approximately the same amount of time.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided sample code on java1.5.0 on Windows XP Professional SP1.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the time to open sockets to be very small (<10ms).
ACTUAL -
Output of the sample code in Java1.5.0:
Time to open socket (ms): 4515
Time to open socket (ms): 4500
Time to open socket (ms): 4500
Time to open socket (ms): 4500
Time to open socket (ms): 4500

Output of the same sample code in Java1.4.2_05:
Time to open socket (ms): 31
Time to open socket (ms): 0
Time to open socket (ms): 0
Time to open socket (ms): 0
Time to open socket (ms): 16


ERROR MESSAGES/STACK TRACES THAT OCCUR :
no errors, just slow responses

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
for(int i=0;i<5;i++)
{
    long time_start = System.currentTimeMillis();
    Socket s = new Socket("192.168.1.1",80);
    long time_end = System.currentTimeMillis();
    System.out.println("Time to open socket (ms): "+(time_end-time_start));
    s.close();
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
A profiler showed that the problem may not lie in the socket implementation but in the InetAddress implementation because most of the waiting time was spent there.

A workaround was by creating a InetAddress myself, cache it, and pass that to the constructor of the sockets. This resulted in the behaviour that the first socket took about 4.5 seconds to be created, the others were much faster. Perhaps the bug has something to do with DNS resolving? Note that I do not pass a DNS name to the Socket constructor but a String representation of a IPv4 address. It is not a bug of the router, as I have tried multiple routers (from different vendors).

I use the sockets to do some HTTP requests. Using HttpUrlConnection to get the HTTP contents made my program much much faster. This makes me believe that the error is not in my OS, but in the implementation of the java Socket classes. There is something in the construction of a socket that is not in the HttpUrlConnection that makes socket creation very slow.
(Incident Review ID: 297298) 
======================================================================
Posted Date : 2005-07-29 09:03:32.0
Work Around
Long timeouts are due to DNS being badly configured. Customers experiencing this issue should try to fix the DNS configuration on the machines (i.e. make sure the DNS servers do exist).

jean-  xxxxx@xxxxx   2005-2-15 16:50:30 GMT
Evaluation
Finally was able to reproduce this.
There is a call to InetSocketAddress.getHostName() in the ProxySelector code. This will trigger a reverse lookup when the hostname is not already known.
If DNS is not configured correctly on the machine, this will generate a long timeout.
Will fix as soon as possible.

jean-  xxxxx@xxxxx   2005-2-15 16:50:30 GMT
Comments
  
  Include a link with my name & email   

Submitted On 07-OCT-2004
evandro.augusto.munhoz.machado
The final version of Tiger seems to be with the same problem.


Submitted On 08-OCT-2004
ricrac50
This problem doesn't exist on Linux Suse release 9.0/9.1.  But is terrible on Windows XP/XP Pro


Submitted On 18-OCT-2004
Martyn
Experienced extreme version of this problem on Win98 SP2 using final version of Tiger.
All URL connections request DNS lookup from the proxy when IPv4 addresses where given, not hostnames.
These requests added 20-30 seconds to every connection making it unusable.
Can DNS lookup be disabled?


Submitted On 07-NOV-2004
josephiam
We have the same problem. It seems that in 1.5 the default 'SocketImpl' was switched from PlainSocketImpl to SocksSocketImpl. 

Durring connect, the SocksSocketImpl makes a call to InetSocketAddress.getHostAddress() which causes a reverse DNS lookup. This can be extrememly slow, we are also passing in a string IPv4, and our servers don't have DNS entries. 

My question is, why is the SocksSocketImpl being used at all - we don't make any use of proxies and don't have them setup? 


Submitted On 09-NOV-2004
jcc
SocksSocketImpl is a subclass of PlainSocketImpl, it is used systematically because for every socket operation there is the possibility that Socks has to be used. If it is determined that no proxy is necessary, then all methods are defered to the superclass. By the way, the Socks code used to be incorporated into PlainSocketImpl, so nothing really changed here, it's just a better organization of the code. Now, as to the DNS request, it shouldn't happen. getHostAddress() does not, as far as I know, do any reverse lookup. But we are looking into this, obviously something is happening there and we're not ignoring it. Thanks for all the information you're giving us.


Submitted On 09-NOV-2004
insertnamehere
After moving from JDK 1.4 to version 1.5, socket.connect() times have gone up
 from less than a second to 27 seconds (Windows 2000). 
I am working around this with the new Socket(Proxy.NO_PROXY) contructor, like this:

Socket socket = null;
if (javaVersion >= 1.5) socket = new  Socket(Proxy.NO_PROXY);
else socket = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress(ipHost, port);
socket.connect(socketAddress, CONNECT_TIMEOUT);


Submitted On 29-NOV-2004
cid96mzi
Windows 2000 resorts to using NetBIOS to resolve hostname of the IP-address I am trying to connect to and therefore I have to wait until NetBIOS times out until I get my socket.

Since also RMI sockets are affected it is rather hard to work around this problem.


Submitted On 06-DEC-2004
easdown
This is an old problem and it occurs with 1.3.1_0x as well (I still use it unfortunately).  The only workaround I have found is to ensure that the "hosts" file within \windows\system32\drivers\etc\ contains names that allow the address to be resolved.  We have found that it is vital for this to be done for both normal sockets, and all of our RMI stuff as well.


Submitted On 06-DEC-2004
easdown
I have another workaround which works a treat if you want to live dangerously.

It turns out that the DNS lookups are being done by the security manager (twice) when it socket.connect() calls checkConnect() and checkAccept().

If you subclass the security manager, and override these two methods, it's amazing how fast it connects by comparison.

Still not really too sure how smart this action is though in an open network.  Some sagely advice wouldn't go astray.....


Submitted On 01-FEB-2005
heydowns
All the comments here summed up together with a little new information, too:
Slow behavior is only seen on Windows.
Slow behavior is only seen when using IP addresses which do not immediately resolve to host names.
Slow behavior is seen in 1.5 because the default SocketImpl was changed to SocksSocketImpl.


SocksSocketImpl:341 has a call to getHostName() for the Socket endpoint.  For most InetSocketAddress endpoints created with an IP address or InetSocketAddress, this means looking up the hostname from the IP address.  

The call to getHostName() will eventually trickle down to the native method Inet4AddressImpl.getHostByAddr(byte[]).  This internally uses the WinSock function gethostbyaddr() which looks up not only via DNS, but also via NetBIOS.

Should DNS reverse-resolution fail, Windows will fall back  to NetBIOS resolution.  This can be VERY slow - 10-20 seconds - before it will timeout.

All this behavior was not seen in 1.4.2 because it did not use SocksSocketImpl by default, thus it simply used the InetAddress


Submitted On 01-FEB-2005
heydowns
[ rest of original message -- silently discarded by the bug system ]

All this behavior was not seen in 1.4.2 because it did not use SocksSocketImpl by default, thus it simply used the InetAddress's  internal IP address and never needed reverse resolution to a hostname.  

Workarounds:
1. Use new Socket(Proxy.NONE) to indicate no proxy (will only compile on 1.5). This side-steps the issue by skipping the Socks code which does the getHostName() call.
2. Use InetAddress.getByAddr(String, byte[]) to provide both a hostname and IP address yourself, which will prevent reverse lookups.
3.  If you make repeated connections to the same host (on same or different ports), reuse the InetAddress objects. InetAddress objects will cache the reverse-looked up hostname.
4.  Ensure that IP addresses in use always reverse lookup in DNS (or in local host table). This is not a very practical workaround in most cases.

(Commentary: Why does the default implementation of the Socket API even bother with Socks?   This is just feature bloat into what should be a relatively simple implementation)


Submitted On 22-FEB-2005
BezugliyY
I understand I can make changes to my new code to work around the problem but what about running old 1.4 code on JRE 1.5? There seems to be nothing I can do to fix it... This is not an enhancement, it is a bug! 


Submitted On 24-FEB-2005
BezugliyY
What I mean is that if I have a 1.4 applet I want to run on a PC with JRE 1.5 installed then I will inevitably experience the long delays. The only way to fix it is to tell IE somehow that for 1.4 applet it needs to use 1.4 JRE even if JRE 1.5 is available. Anyone knows how? Is static versioning the way to go? http://java.sun.com/products/plugin/versions.html
What if I cannot change the web page containg the applet?


Submitted On 29-MAR-2005
sammer
Now, tiger has come to a version "1.5.0_03" and this bug is still not fixed. Are there no plans to correct this soon?


Submitted On 17-APR-2005
deniz_tatar
   I have the same problem on my RMI client/server application. Naming.lookup(..) and remote method calls are very slow. (Which I haven't got this problem on 1.4.2)
   It is a big problem for RMI. I hope this bug will be fixed in a short time...


Submitted On 17-APR-2005
deniz_tatar
You can also find how this bug effects RMI;

http://forum.java.sun.com/thread.jspa?messageID=3458680&#3458680


Submitted On 22-APR-2005
deniz_tatar
I could not find a workaround for this bug.

I put my server hostname and ip address into client hosts file and nothing changed.

Also tried to use and cache InetAddress with both hostname and ip address.

Are there any different solutions for this bug? especially for RMI.

Thanks,


Submitted On 26-APR-2005
deniz_tatar
If you are using a security manager for your RMI server application YOU MUST DISABLE IT.

Because I debugged and saw that checkAccept(..) and checkConnect(..)  methods of SecurityManager tries to resolve client hostname from ip address.

I think this is not needed if you configure this permission;

permission java.net.SocketPermission "*:1024-", "accept,connect,resolve";

"*" means every client can connect. So why we try to resolve any client ip or hostname?


Submitted On 04-MAY-2005
Mikno
The problem still exist in 
java version 


Submitted On 04-MAY-2005
Mikno
Sorry,
the problem still exists in Jre 1.5.0_03
Miknosoft


Submitted On 04-MAY-2005
twe3lve
Who called this a request for enhancement? This is a screaming, fire-breathing cockroach bug from hell. It's actually a lot worse if you need to do multi-threaded socket connections to multiple hosts. I've seen it take 20 seconds to just get through the Socket constructor, even when giving it an InetAddress. The best workaround I've been able to find has been to try to maintain open connections as much as possible. But even then, the best advice I've been able to give our people is to remove the Java 1.5 JVM and install the 1.4.2 JVM instead.


Submitted On 11-MAY-2005
eamm
This fix will be available only in mustang release?
Why don't  fix it in 1.5.0_04 ??
:(


Submitted On 17-MAY-2005
droida38
I Agree! Why not release it in the next 1.5 release?


Submitted On 25-MAY-2005
jcc
I'd like to clarify a few misconceptions about this issue.

The reverse lookup takes a long time only on machines where the DNS is not properly configured. More precisely when the address for the NameServer points to a non existing DNS server. Because of the nature of DNS this will trigger a long timeout. Granted the reverse lookup is not necessary and that's fixed in mustang, but there are a number of workarounds:

1) Fix the DNS configuration. If the server is reponding, the lookup will  not wait until timeout has expired but returns immediately. This is the preferred way as it doesn't require a change in the application.

2) use Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 80); instead. This will not trigger a reverse lookup

3) The code that triggers the reverse lookup is in the ProxySelector mechanism (when checking if SOCKS should be used or not). If you are sure your application does not need proxies, you can disable the ProxySelector by using ProxySelector.setDefault(null) at the start of the application. Be warned though that will also disable the http & ftp proxies.

I have tested all 3 workarounds and they do work.

I'd also like to outline that there is no bloat regarding the SOCKS code. If no SOCKS proxy is configured, then all the calls will be passed directly to the "plain" socket implementation. But because the proxy settings are dynamic, it has to be checked everytime. It has been that way since the days of 1.0.2. The only difference is that now the SOCKS code and the "normal" code are better separated in the code while before they were intertwined in the "plain" socket code.


Submitted On 05-JUN-2005
ecki
IMHO it helps to generate a inet address where hostname and address are given, then the reverse lookup will not attempt the lookup. However it is anyway good to remove the lookup from the proxy selector code if possible (I dont think it is avoidable in the http case)


Submitted On 07-JUN-2005
geek
thanks ecki,

your's is the workaround that works for my application.

jcc's workarounds 1 & 2 don't work in my application and may not work for others. (The problem being that (1) my DNS is already configured properly, but a reverse lookup for a host that has no host name (like 192.168.22.33)  still takes a few seconds, and (2) his second suggestion still results in a 4500ms delay in creating the socket)


Submitted On 15-JUN-2005
worsaae
DNS is not the problem. java 1.5 is!!.
When we know the server IP address there shouldnt be any DNS involvement (as it where in 1.4).
We have to explain our custommers to stay with 1.4 until sun have fixed this


Submitted On 17-JUN-2005
Nagypapi
"
2) use Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 80); instead. This will not trigger a reverse lookup
"

Im using java 1.5_03.
I agree with a former poster: code given doesn't speed up the connection, except of course if you use the loopback address which is by default in the hosts file...

I too could only help myself using ECKI's suggestion on using InetAddress.getByAddress(host,raw_ip)


Submitted On 30-JUN-2005
martinm1000
*** NOT FIXED ***

Still exist under 1.5.0_04.

Before finding this bug report, I filled a new one. We will see what they are saying... Please re-open this bug.


Submitted On 01-JUL-2005
calumm
I can't believe a bug like this isn't going to be fixed in Tiger!

However, the "new  Socket(Proxy.NO_PROXY)" seems to work for me.
As I'm not too au fait with networking code, can I ask if using this workaround will have any negative effects?  Are there some scenarios where this might cause a problem?


Submitted On 03-JUL-2005
martinm1000
My problem is that the new Socket call that is having the problem is inside a JDBC driver for which I don't have the source code...

I need to test a fix I just did; I call under java 1.5 ProxySelector.setDefault(null) to deactivate it; but I use
reflection to do it, since my app is compiled under 1.4.

If it seems to work ok for the rest of my app, I'll post the code.

Just a question: how bad could setting to null the ProxySelector be ? Is it possible that the default ProxySelector will be needed by some users so my app can reach the internet ?

ps.: my app is a java webstart program that talk to a database.


Submitted On 06-JUL-2005
martinm1000
Well they refused my bug report for this problem, pointing at this one... which is closed. They told me to try Java 1.6.... Yeah sure, I'll tell my customers that ! I'm not even ready to officially push for Java 1.5, and with this kind of problems, I won't. The day 1.6 will be mainstream and stable, maybe our app won't even be in Java anymore, but in C# / .net 2.0.

Anyway, if you need to deactivate the proxy selector but still need to compile for 1.4, use this snippet :

import java.lang.reflect.*;

if (System.getProperty(


Submitted On 06-JUL-2005
martinm1000
forums are down, hoping it will fit here:
import java.lang.reflect.*;
if (System.getProperty("java.version", "").startsWith("1.5")) {
  try {
    Class PS = Class.forName("java.net.ProxySelector");
    Method[] m = PS.getDeclaredMethods();
    for (int i = 0; i < m.length; i++) {
      if (Modifier.isPublic(m[i].getModifiers())) {
        if (m[i].getName().equals("setDefault") && 
          m[i].getParameterTypes().length == 1) {
          Object[] params = { null };
          m[i].invoke(PS, params);
          System.out.println("ProxySelector Deactivated.");
        }
      }
    }
  } catch (Exception e) { System.err.println(e); } 
}


Submitted On 06-SEP-2005
fabriziobertocci
I've experienced this problem only on Windows XP.
The problem goes away if you tell JVM to use the internal resolver by launching it with this option:
    -Dsun.net.spi.nameservice.provider.1=dns,sun


Submitted On 21-SEP-2005
Alberto
This problem seems not to be still solved.


Submitted On 05-OCT-2005
milx
I just spent two days trying to figure out why my web service client was extremely slow on 1.5.0_05. This is the only problem I had migrating a large application from 1.4, and it really sucks. A simple entry in the hosts file solved the problem, but if my application was distributed on several computers it would be hell to fix. Shame on you Sun.


Submitted On 14-OCT-2005
Our applet is developed on 1.4.2, now with the new JRE1.5, customer are complaining how slow it is. Please fix it soon.


Submitted On 30-NOV-2005
davidekholm
Sun, please fix this bug soon. I Develop JAlbum (http://jalbum.net) with millions of users world wide. I can't tell them to tell their ISPs and web hosting companies to review their reverse lookups. They will simply switch to another program to do the file uploading :-(


Submitted On 09-JAN-2006
craig_kelley
This bug is most definitely *not* fixed.  We just spent two days trying to track down this issue, with a packet dump to see what was going on.  The Socket constructor is in an external JAR that we do not have the source to, so the various fixes are not suitable.  We also have many hosts, so using a hosts file would be problematic.  Please fix this bug.


Submitted On 11-JAN-2006
jcc
This bug fix has been integrated into both Mustang (1.6.0, not released yet) and <a href="http://java.sun.com/j2se/1.5.0/download.jsp">1.5.0 update 6</a> which has been recently released.
Make sure you do have 1.5.0_06.


Submitted On 17-APR-2006
Sir I want   sample code for 'isReachable(int timeout)'  method. please comment


Submitted On 18-APR-2006
Gernot_Eger
There is a similar bug ( http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6413593. ) which was closed right away as "not a bug". Seems to happen with Win2K and Java 1.5.0_06 and mustang beta. 


Submitted On 13-JUL-2006
saqbashir
Our applet has to be java 1.1 compliant. Has anyone got a suggestion re. how we can avoid reverse lookup if we use URL class to create a connection? (it doesnt use InetSocketAddress parameter... )


Submitted On 11-AUG-2006
Hi - so what is final resolution here?

I am using the sockets(ip,port) and am seeing about 10 seconds to connect. Not very good.

Does someone have a code segment that gets mS level connect times?


Submitted On 17-AUG-2006
Fritztdog
My company was having this same problem until we stumbled onto the solution. In hindsight, it's probably the solution that was alluded to as "Fix the DNS configuration" in the post from jcc on May 25, 2005. In our case, we had registered our domain but our ISP was not supplying a reverse lookup in our ISP's DNS for our domain.
It appears that most ISP's supply a default reverse lookup for all machines under
their control, but I guess not all do.
To test if this is what's happening for you, try running the UNIX command
   host <ipaddress>

If you don't have UNIX, there's probably an equivalent in the "other" world, but I don't know it.
If you don't get an error saying "not found", this is not the problem.
If you wait for 5 seconds (sound familiar) and then get the response:
   Host zz.yy.xx.ww.in-addr.arpa not found: 3(NXDOMAIN)

then the ISP that hosts your machine needs to have it's DNS
upated. Note, the zz.yy.xx.ww is your IP address in reverse. Hence,
reverse lookup :)

Another, temporary way to get around this delay is to add an entry in *your* computer's host file for that ipaddress. If you are hosing a public application, 
this will probably not be a viable option for your customers since IT departments should disallow
individuals from changing their host defintions. Otherwise, you could have "google.com" point
to joblow.google.com...not good. But if you want to try it, here's the steps you can use on Windows:
1. open a Command Prompt window
2. type:  c:
3. type:  cd windows
4. type:  cd system32
5. type:  cd drivers
6. type:  cd etc
7. type:  edit hosts
8. add a line like the following for the host having the problem:
       <your ip address here>        <your domain or hostname alias>
9. save the changes and exit
10. try running your app from your machine to see if it's faster

note, steps 2-6 can be a single command if you use the "\" as a separator between the folder names.

So, in closing, my $0.02 is that this is not a bug in Java. However, a lot of anguish could
have been avoided if earlier explanations would have gone into detail about what
"fixing DNS" really meant.




Submitted On 11-DEC-2006
knystautas
There is another workaround that we're finding should work.  By default InetAddress caches positive hits indefinitely, but negative hits for 10 seconds.  If you change this to cache negative hits indefinitely as well, then all your subsequent unnecessary reverse DNS cache entries will fire quickly.

-Dnetworkaddress.cache.negative.ttl=-1


Submitted On 19-OCT-2007
Similar to host <ipaddress> which was perviously mentioned.  

You can perform a reverse DNS lookup test from a Windows command with the following (should also work for Linux and Unix):

nslookup <ipaddress>




Submitted On 03-JAN-2008
Gaurav4556
my version is java 1.5.0_01 

it is extremely create big  problame for database connection


Submitted On 06-MAY-2008
saraolsson
I have been searching the bug database forever, and this sounds like the problem we are experiencing. We have an applet that makes rmi-calls, and we had problems with the dns lookup in java 1.5.0 - 1.5.5. Then in 1.5.6 it was fixed!

Now in 1.6.0 - 1.6.4 it is back! So now we have to put ipadress along with the name in the hosts file, but that is not a solution we can get our hundreds of thousands of users to do :( Does anyone know if they are planning to fix this in 1.6?


Submitted On 22-MAY-2009
I have the same issue with Java 1.6_07 to Java 1.6_13


Submitted On 21-JUL-2009
MauriceS
This problem seems to be still/again present in 1.6.0_14-b08



PLEASE NOTE: JDK6 is formerly known as Project Mustang