MulticastSocket problem on FreeBSD
Hi, I encountered a bug while migrating from FreeBSDs old "Diablo jre" to openjdk-jre version 6. I'm running a software using multicast communication and it fails on FreeBSD when using openjdk6. example code: import java.io.IOException; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketException; import java.net.UnknownHostException; class Main { static String hostname = new String("10.0.1.1"); public static void main(String args[]) throws SocketException, UnknownHostException, IOException{ InetAddress ia = InetAddress.getByName(hostname); MulticastSocket ssdpSocket = new MulticastSocket(); ssdpSocket.setInterface(ia); System.out.println("network interface: " + ssdpSocket.getNetworkInterface()); System.out.println("interface: " + ssdpSocket.getInterface()); } } The output of the old "Diablo JRE" is: network interface: name:null index: -1 addresses: /10.0.1.1; interface: /10.0.1.1 The output of openJDK6 is: network interface: name:null interface: /0.0.0.0 It always returns this information. For comparison - openjdk on Linux: network interface: name:eth0 (eth0) interface: /10.0.1.54 Oracle 7 VM on Windows: network interface: name:eth3 (Realtek PCIe GBE Family Controller) interface: /10.0.1.51 For me this seems to be an implementation bug of... I don't know? PlainDatagramSocketImpl.c maybe? I tried to debug this further, but did not succeeded to find out if either setInterface() failed to set it correctly, or somewhere in getInterface() an early return() happens. I tried to remotly debug this using Eclipse, but only saw the private variables of ssdpSocket which didn't indicated something obvious. Breakpoints inside java.net.MulticastSocket would have helped ;)
In addition to my 1st mail: Is this the code which was used to compile openjdk 6 on FreeBSD? http://download.java.net/openjdk/jdk6/promoted/b27/openjdk-6-src-b27-26_oct_... PlainDatagramSocketImpl.c only contains an implementation for Solaris and Linux for the method setMulticastInterface(). It looks like exactly this method is called when ssdpSocket.setInterface(ia); is executed. MulticastSocket.java:setInterface() -> PlainDatagramSocketImpl.java:socketSetOption() -> PlainDatagramSocketImpl.c:Java_java_net_PlainDatagramSocketImpl_socketSetOption() -> PlainDatagramSocketImpl.c:setMulticastInterface() But this tar.gz does not contain (Free)BSD specific code I guess as there are only directories for solaris, linux and windows. So - where is the BSD specific code located?
Hi Oliver, On Thursday 31 January 2013 01:39:40 pm Oliver Lehmann wrote:
In addition to my 1st mail:
Is this the code which was used to compile openjdk 6 on FreeBSD?
http://download.java.net/openjdk/jdk6/promoted/b27/openjdk-6-src-b27-26_oct_...
The bsd-port repository is for openjdk7. For openjdk6 on FreeBSD you would need to instal the ports tree and build /usr/local/java/openjdk6: http://svnweb.freebsd.org/ports/head/java/openjdk6 It uses the source you found above combined with a large patchset plus some other patches. Regards, -Kurt
PlainDatagramSocketImpl.c only contains an implementation for Solaris and Linux for the method setMulticastInterface(). It looks like exactly this method is called when
ssdpSocket.setInterface(ia);
is executed.
MulticastSocket.java:setInterface() -> PlainDatagramSocketImpl.java:socketSetOption() -> PlainDatagramSocketImpl.c:Java_java_net_PlainDatagramSocketImpl_socketSetOption() -> PlainDatagramSocketImpl.c:setMulticastInterface()
But this tar.gz does not contain (Free)BSD specific code I guess as there are only directories for solaris, linux and windows. So - where is the BSD specific code located?
On Thursday 31 January 2013 05:02:51 pm Kurt Miller wrote:
Hi Oliver,
On Thursday 31 January 2013 01:39:40 pm Oliver Lehmann wrote:
In addition to my 1st mail:
Is this the code which was used to compile openjdk 6 on FreeBSD?
http://download.java.net/openjdk/jdk6/promoted/b27/openjdk-6-src-b27-26_oct_...
The bsd-port repository is for openjdk7. For openjdk6 on FreeBSD you would need to instal the ports tree and build /usr/local/java/openjdk6:
/usr/ports/java/openjdk6 rather.
http://svnweb.freebsd.org/ports/head/java/openjdk6
It uses the source you found above combined with a large patchset plus some other patches.
Regards, -Kurt
PlainDatagramSocketImpl.c only contains an implementation for Solaris and Linux for the method setMulticastInterface(). It looks like exactly this method is called when
ssdpSocket.setInterface(ia);
is executed.
MulticastSocket.java:setInterface() -> PlainDatagramSocketImpl.java:socketSetOption() -> PlainDatagramSocketImpl.c:Java_java_net_PlainDatagramSocketImpl_socketSetOption() -> PlainDatagramSocketImpl.c:setMulticastInterface()
But this tar.gz does not contain (Free)BSD specific code I guess as there are only directories for solaris, linux and windows. So - where is the BSD specific code located?
Hi Oliver, On 01/31/13 13:26, Oliver Lehmann wrote:
Hi,
I encountered a bug while migrating from FreeBSDs old "Diablo jre" to openjdk-jre version 6.
I'm running a software using multicast communication and it fails on FreeBSD when using openjdk6.
example code:
import java.io.IOException; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketException; import java.net.UnknownHostException;
class Main { static String hostname = new String("10.0.1.1");
public static void main(String args[]) throws SocketException, UnknownHostException, IOException{ InetAddress ia = InetAddress.getByName(hostname); MulticastSocket ssdpSocket = new MulticastSocket();
ssdpSocket.setInterface(ia);
System.out.println("network interface: " + ssdpSocket.getNetworkInterface()); System.out.println("interface: " + ssdpSocket.getInterface()); } }
The output of the old "Diablo JRE" is:
network interface: name:null index: -1 addresses: /10.0.1.1;
interface: /10.0.1.1
The output of openJDK6 is:
network interface: name:null interface: /0.0.0.0
It always returns this information. For comparison - openjdk on Linux:
network interface: name:eth0 (eth0) interface: /10.0.1.54
Oracle 7 VM on Windows:
network interface: name:eth3 (Realtek PCIe GBE Family Controller) interface: /10.0.1.51
I can confirm this is a problem for bsd-port (openjdk7) on OpenBSD too.
For me this seems to be an implementation bug of... I don't know? PlainDatagramSocketImpl.c maybe?
I tried to debug this further, but did not succeeded to find out if either setInterface() failed to set it correctly, or somewhere in getInterface() an early return() happens. I tried to remotly debug this using Eclipse, but only saw the private variables of ssdpSocket which didn't indicated something obvious. Breakpoints inside java.net.MulticastSocket would have helped ;)
Hi, I patched openjdk7. Attached you'll find the patch. It is now possible (at least for me) to use MulticastSocket. I know the patch is not ready for checkin, but I guess you'll get the idea and know how to do it properly as I don't know the correct defines to check. (The first two chunks in the patch are probably already in HG as the patch is based on u6 code) Basically I just replaced the MACOSX check with __FreeBSD__ and it works now: root@bigoli test> /usr/local/bootstrap-openjdk/bin/javac test.java root@bigoli test> /usr/local/bootstrap-openjdk/bin/jar -cf test.jar Main.class root@bigoli test> /usr/local/openjdk7/bin/java -classpath .:test.jar Main network interface: name:null interface: /10.0.1.1 Java is still not able to detect my network interface name, but this was also not working in Diablo JRE and I don't need it. At least I'm now getting the correct Multicast Address back (10.0.1.1 and not 0.0.0.0) Please consider fixing this upstream. PS: Sorry for top-post but I'm CCing FreeBSDs java@ list Kurt Miller <kurt@intricatesoftware.com> wrote:
Hi Oliver,
On 01/31/13 13:26, Oliver Lehmann wrote:
Hi,
I encountered a bug while migrating from FreeBSDs old "Diablo jre" to openjdk-jre version 6.
I'm running a software using multicast communication and it fails on FreeBSD when using openjdk6.
example code:
import java.io.IOException; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketException; import java.net.UnknownHostException;
class Main { static String hostname = new String("10.0.1.1");
public static void main(String args[]) throws SocketException, UnknownHostException, IOException{ InetAddress ia = InetAddress.getByName(hostname); MulticastSocket ssdpSocket = new MulticastSocket();
ssdpSocket.setInterface(ia);
System.out.println("network interface: " + ssdpSocket.getNetworkInterface()); System.out.println("interface: " + ssdpSocket.getInterface()); } }
The output of the old "Diablo JRE" is:
network interface: name:null index: -1 addresses: /10.0.1.1;
interface: /10.0.1.1
The output of openJDK6 is:
network interface: name:null interface: /0.0.0.0
It always returns this information. For comparison - openjdk on Linux:
network interface: name:eth0 (eth0) interface: /10.0.1.54
Oracle 7 VM on Windows:
network interface: name:eth3 (Realtek PCIe GBE Family Controller) interface: /10.0.1.51
I can confirm this is a problem for bsd-port (openjdk7) on OpenBSD too.
For me this seems to be an implementation bug of... I don't know? PlainDatagramSocketImpl.c maybe?
I tried to debug this further, but did not succeeded to find out if either setInterface() failed to set it correctly, or somewhere in getInterface() an early return() happens. I tried to remotly debug this using Eclipse, but only saw the private variables of ssdpSocket which didn't indicated something obvious. Breakpoints inside java.net.MulticastSocket would have helped ;)
Hi Oliver, On Friday 01 February 2013 03:03:19 am Oliver Lehmann wrote:
Hi,
I patched openjdk7. Attached you'll find the patch. It is now possible (at least for me) to use MulticastSocket. I know the patch is not ready for checkin, but I guess you'll get the idea and know how to do it properly as I don't know the correct defines to check. (The first two chunks in the patch are probably already in HG as the patch is based on u6 code)
Right those parts are already there.
Basically I just replaced the MACOSX check with __FreeBSD__ and it works now:
The last chunk of the diff is not needed for this problem and is incomplete. It is for the problem described here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7144274 http://hg.openjdk.java.net/bsd-port/bsd-port/jdk/rev/99cc5c9ef200 I have not yet checked to see if we need this fix in addition to the problem you noted. However, if we do need it then we to change MACOSX to _ALLBSD_SOURCE in both PlainDatagramSocketImpl.c mcast_join_leave() and net_util_md.c setDefaultScopeID() I am attaching patches for both openjdk6 and openjdk7 that should fix the problem you initially reported and will apply to FreeBSD's ports cleanly. Thanks for reporting the problem and tracking the correction down. -Kurt
root@bigoli test> /usr/local/bootstrap-openjdk/bin/javac test.java root@bigoli test> /usr/local/bootstrap-openjdk/bin/jar -cf test.jar Main.class root@bigoli test> /usr/local/openjdk7/bin/java -classpath .:test.jar Main network interface: name:null interface: /10.0.1.1
Java is still not able to detect my network interface name, but this was also not working in Diablo JRE and I don't need it. At least I'm now getting the correct Multicast Address back (10.0.1.1 and not 0.0.0.0)
Please consider fixing this upstream.
PS: Sorry for top-post but I'm CCing FreeBSDs java@ list
Kurt Miller <kurt@intricatesoftware.com> wrote:
Hi Oliver,
On 01/31/13 13:26, Oliver Lehmann wrote:
Hi,
I encountered a bug while migrating from FreeBSDs old "Diablo jre" to openjdk-jre version 6.
I'm running a software using multicast communication and it fails on FreeBSD when using openjdk6.
example code:
import java.io.IOException; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketException; import java.net.UnknownHostException;
class Main { static String hostname = new String("10.0.1.1");
public static void main(String args[]) throws SocketException, UnknownHostException, IOException{ InetAddress ia = InetAddress.getByName(hostname); MulticastSocket ssdpSocket = new MulticastSocket();
ssdpSocket.setInterface(ia);
System.out.println("network interface: " + ssdpSocket.getNetworkInterface()); System.out.println("interface: " + ssdpSocket.getInterface()); } }
The output of the old "Diablo JRE" is:
network interface: name:null index: -1 addresses: /10.0.1.1;
interface: /10.0.1.1
The output of openJDK6 is:
network interface: name:null interface: /0.0.0.0
It always returns this information. For comparison - openjdk on Linux:
network interface: name:eth0 (eth0) interface: /10.0.1.54
Oracle 7 VM on Windows:
network interface: name:eth3 (Realtek PCIe GBE Family Controller) interface: /10.0.1.51
I can confirm this is a problem for bsd-port (openjdk7) on OpenBSD too.
For me this seems to be an implementation bug of... I don't know? PlainDatagramSocketImpl.c maybe?
I tried to debug this further, but did not succeeded to find out if either setInterface() failed to set it correctly, or somewhere in getInterface() an early return() happens. I tried to remotly debug this using Eclipse, but only saw the private variables of ssdpSocket which didn't indicated something obvious. Breakpoints inside java.net.MulticastSocket would have helped ;)
Hi Kurt, Kurt Miller <kurt@intricatesoftware.com> wrote:
I am attaching patches for both openjdk6 and openjdk7 that should fix the problem you initially reported and will apply to FreeBSD's ports cleanly.
I now compiled openjdk6 and 7 ports with your patches in place and the problem goes away. Any chance they get committed to HQ?
Hi Oliver, On Friday 01 February 2013 05:35:45 pm Oliver Lehmann wrote:
Hi Kurt,
Kurt Miller <kurt@intricatesoftware.com> wrote:
I am attaching patches for both openjdk6 and openjdk7 that should fix the problem you initially reported and will apply to FreeBSD's ports cleanly.
I now compiled openjdk6 and 7 ports with your patches in place and the problem goes away. Any chance they get committed to HQ?
Great. I can take care of bsd-port. Probably Greg or other FreeBSD commters will review and commit them to the FreeBSD's ports tree. Regards, -Kurt
participants (2)
-
Kurt Miller
-
Oliver Lehmann