java.net.InetAddress gets localhost address wrong (WinXP) - java

I'm working in Groovy 1.8.6, running on JDK 1.6.0u33. When my program is starting up, it attempts to connect to another process on the same host by connecting to a telnet port on the host address. It uses the standard Java class InetAddress to determine the local host address. However, for some reason when I start the program up on a Windows XP VM, the host address resolves to garbage and the connection fails.
The startup script includes this line for diagnostic information:
def serverAddress = "http://${InetAddress.localHost.hostAddress}:${config.ServerPort}/DigitizerService?wsdl"
The output when serverAddress is printed to the terminal is:
http://0.1.0.5:8989/DigitizerService?wsdl
The address is not always the same- another time it came out as 0.2.0.5. But it always comes out as something that's not even a valid address, let alone the actual address for this host.
This same codebase is in production on a large number of boxes out in the wild and I've never seen an issue like this coming up, so I guess it must be specific to this new devbox it's on- or it's a bug in the new JDK.
Does anyone have any idea what might be causing something so basic as this to output garbage? Thanks in advance.

While I tried restarting before posting this question (of course, this is Windows after all), and it did not help, a second reboot of the VM seems to have fixed the issue. It was in the process of installing a big pile of Windows updates, as it was an old VM that I'd just dusted off, so I suppose that may have somehow scrambled things internally in the OS.
So I'm still very confused as to how this came about, but I think I can conclude that it was not Java at fault. Probably.

Related

Java NetworkInterface methods failing

Having an issue with the product I code for where our licensing service is unable to find a host MAC address. We don't have much idea why this is happening and it is only happening to very small percentage of users.
The method to get this MAC address is using the Java NetworkInterface methods. If this fails and returns NULL (or users JRE is <1.6) we then fall back to using Sigar to get our address. However it seems this is also failing. The problem is either that it can't obtain the IP address (and then further to this can't get the MAC address) or just can't get the MAC. This issue is happening across all OS' we support (AIX, Solaris, Win7/8, Win Server, Linux & MAC).
As such, my first thought was that these users were enabling the Java security manager (as this is a common factor), but this is looking less likely as I try to reproduce it as this requires a lot of extra configuration steps with permissions to even get our product to run. As such we would have expected to see users asking us for what they need to enable to get our software to run, but this does not happen.
As such I am wondering what is causing this to fail. My only lead now is that it is something lower level (within the OS) that is being enabled to block Java's attempts to natively get this information. I am searching for this now, but it is slow going and an odd thing to search for.
My question is, is this kind of behavior possible (i.e. disabling calling of native methods to discover network info to anything other than trusted code within the OS?), on any/some of the platforms listed above?
Has anyone had this problem before with Java NetworkInterface methods?

Is it possible to run a program (java\c\etc) under these situations?

Scenario 1: I have a test server that gets OS reinstalls on a frequent basis. Is there any way to add a program to the server that will remain and execute even if the OS is reinstalled? (I know it's a stretch, but had to ask)
Scenario 2: I have another server running ESXi 5.1 (which I admit, I know nothing about) how (or can) I run a program at the OS level (not as a VM)? Reason being, I need to get information specific to the server and not the VM's such as ip,MAC address, etc that my program gathers with Runtime.exec().
I have a PXE server setup with kickstart files that work great for linux, but not sure if I can do it with ESX or not, anyone ever try to PXE boot ESX like this? On linux, I run my program via crontab, and in the past did it with rc.local. Any suggestions would be appreciated, even if it is a link to potential resources you have had luck with in similar situations.
1) The program must run within an OS, or the JVM will have been designed to run without an OS. I don't believe there is a JVM which will use an OS if it is there but not care if it is not.
You can do this with virtual machines. You can have the OS run/stop/start/reinstall in a virtual machine, while an application is running on the bare machine or in another virtual machine.
2) When you application runs, it is at the OS level. The distinction is largely an illusion. You can get the IP and MAC addresses in normal Java. If you nee to get something else, you can use JNA/JNI/JNR.
I have not heard of ESX before.

Java IOException: No buffer space available while sending UDP packets on Linux

I have a third party component which tries to send too many UDP messages to too many separate addresses in a certain situation. This is a burst which happens when the software is started and the situation is temporary. I'm actually not sure is it the plain amount of the messages or the fact that each of them go to a separate IP address.
Anyway, changing the underlying protocol or the problematic component is not an option, so I'm looking for a workaround. The StackTrace looks like this:
java.io.IOException: No buffer space available
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:612)
This issue occurs (at least) with Java versions 1.6.0_13 and 1.6.0_10 and Linux versions Ubuntu 9.04 and RHEL 4.6.
Are there any Java system properties or Linux configuration tweaks which might help?
I've finally determined what the issue is. The Java IOException is misleading since it is "No buffer space available" but the root issue is that the local ARP table has been filled. On Linux, the default ARP table lookup is 1024 (files /proc/sys/net/ipv4/neigh/default/gc_thresh1, /proc/sys/net/ipv4/neigh/default/gc_thresh2, /proc/sys/net/ipv4/neigh/default/gc_thresh3).
What was happening in my case (and I assume your case), is that your Java code is sending out UDP packets from an IP address that is in the same subnet as your destination addresses. When this is the case, the Linux machine will perform an ARP lookup to translate the IP address into the hardware MAC address. Since you are blasting out packets to many different IPs the local ARP table fills up quickly, hits 1024, and that is when the Java exception is thrown.
The solution is simple, either increase the limit by editing the files I mentioned earlier, or move your server into a different subnet than your destination addresses, which then causes the Linux box to no longer perform neighbor ARP lookups (instead will be handled by a router on the network).
When sending lots of messages, especially over gigabit ethernet in Linux, the stock parameters for your kernel are usually not optimal. You can increase the Linux kernel buffer size for networking through:
echo 1048576 > /proc/sys/net/core/wmem_max
echo 1048576 > /proc/sys/net/core/wmem_default
echo 1048576 > /proc/sys/net/core/rmem_max
echo 1048576 > /proc/sys/net/core/rmem_default
As root.
Or use sysctl
sysctl -w net.core.rmem_max=8388608
There are tons of network options
See Linux Network Tuning by IBM
and More tuning information
Might be a bit complicated but as I know, Java uses the SPI1 pattern for the network sub-library. This allows you to change the implementation used for various network operations. If you use OpenJDK then you could gain some hints how and what to wrap with your implementation. Then, in your implementation you slow down the I/O with some sleeps for example.
Or, just for fun, you could override the default DatagramSocket with your modified implementation. Have the same package name for it and - as I know - it will take precedence over the default JRE class. At least this method worked for me on some buggy 3rd party library.
Edit:
1Service Provider Interface is a method to separate client and service code within an API. This separation allows different client and different provider implementations. Can be recognized from the name ending in Impl usually, just like in your stack trace java.net.PlainDatagramSocketImpl is the provider implementation where the DatagramSocket is the client side API.
You commented that you don't want to slow down the communication the entire way. There are several hacks to avoid it, for example measure the time in your code and slow the communication within the first 1-2 minutes starting at your first incoming method call. Then you can skip the sleep.
Another option would be to identify the misbehaving class in the library, JAD it and fix it. Then replace the original class file in the library.
I'm also currently seeing this problem as well with both Debian & RHEL. At this point I believe I've isolated it down to the NIC and/or the NIC driver. What hardware configuration do you have this also exhibits this problem? This seems to only occur on new Dell PowerEdge servers that we recently acquired that have Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet NICs.
I too can confirm that it is the rapid generation of outbound UDP packets to many different IP addresses in a short window. I've attempted to write a simple Java application that can reproduce it (since ours is occurring with snmp4j).
EDIT
Look at my answer here: Java IOException: No buffer space available while sending UDP packets on Linux
I have got this error when i tried to run coherence cluster in two local JVM using the WIFI connection to database..
If i run it using the ethernet - it runs well.

How long is the request queue on a Vista-system?

I'm currently hacking on a new project, a web-app. But something's wrong, and I think it's Vistas fault, when I'm stress-testing the app, not all of the requests are answered.
The only thing I can think of is that the queue of incomming requests is getting too long, I've googled around, but can't find out how long the queue is, only that it depends on OS. Tough this may simply be because I don't know the "real" name for it;)
The project is written in Java SE.
If someone knows the answer I'd be really happy as I can't find it myself anywhere;)
UPDATE: The app is just a pet-project, and I won't be running it on a Vista machine when it's done. I've even been thinking of running it on a Solaris box, just to try Solaris:)
There are no errors or anything, but the request counter is way too low. Testing is done from Opera, with 30 tabs on auto-refresh every one second. I know, it's not the right way to do it, but it works:)
I don't use any frameworks, EE or anything, just pure Java SE.
If you're writing a server app, but running it on Vista, you may be hitting the hard limit for inbound network connections on the Vista OS. I've seen numbers from 5 (for Home Basic) up to 25 (for Business Pro and Ultimate) simultaneous connections allowed.
Vista is not designed as a Server OS. If you want more simultaneous network connections, and you want to run Windows, get a license for one of the Windows Server products. Alternately, you can run on some *NIX system.

Why does getLocalhost() freeze sometimes?

With JRE6 (SUN VM on Windows XP), getLocalhost() freezes sometimes.
Interestingly, if in the debugger in Eclipse, it does not freeze. I narrowed it down to a single getLocalhost() call using old school println. There is nothing particularly special about the code, that I can see.
Has anyone else seen this problem?
You did not specify how long it freezes for... or did you mean completely frozen, never returning.
If the local host name (returned from a JNI call) is not "localhost", the IP address for the local name is resolved using InetAddress.getAddressFromNameService(). This is a DNS call that could conceivably block for an unspecified amount of time finding and accessing the name server.
Use wireshark to see if your DNS is taking a long time to respond.

Categories

Resources