JDK-8164592 : java/net/MulticastSocket/NoLoopbackPackets.java tests may leave a daemon thread
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-08-23
  • Updated: 2016-09-02
  • Resolved: 2016-08-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b134Fixed
Related Reports
Relates :  
Relates :  
Description
java/net/MulticastSocket/NoLoopbackPackets.java starts a daemon thread which has an infinite loop. Looks like the loop may run forever: 

http://hg.openjdk.java.net/jdk9/dev/jdk/file/0cd4b4def24f/test/java/net/MulticastSocket/NoLoopbackPackets.java#l127 

... 
            Thread sender = new Thread(new Sender(groups)); 
            sender.setDaemon(true); // we want sender to stop when main thread exits 
            sender.start(); 
... 
static class Sender implements Runnable { 
        private List<SocketAddress> sendToGroups; 

        public Sender(List<SocketAddress> groups) { 
            sendToGroups = groups; 
        } 

        public void run() { 
            byte[] buf = "hello world".getBytes(); 
            List<DatagramPacket> packets = new ArrayList<DatagramPacket>(); 

            try { 
                for (SocketAddress group : sendToGroups) { 
                    DatagramPacket packet = new DatagramPacket(buf, buf.length, group); 
                    packets.add(packet); 
                } 

                MulticastSocket msock = new MulticastSocket(); 
                msock.setLoopbackMode(true); // disable loopback mode 
                for (;;) { 
                    for (DatagramPacket packet : packets) { 
                        msock.send(packet); 
                    } 

                    Thread.sleep(1000); // 1 second 
                } 
            } catch (Exception e) { 
                throw new RuntimeException(e); 
            } 
        } 
    } 
...

The test shouldn't leave daemon threads when they finish. It may slow down further test execution a little bit because daemon threads consume some JVM resources. If other tests also leave daemon threads, it may cause intermittent failures of other tests which run in the same JVM. See for example JDK-8160642 and JDK-8162757. Sender daemon thread is in jstack output:

"Thread-2012" #2141 daemon prio=5 os_prio=0 tid=0x00007fec3c2ad800 nid=0x740c waiting on condition [0x00007fec941dc000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(java.base@9-ea/Native Method)
	at NoLoopbackPackets$Sender.run(NoLoopbackPackets.java:144)
	at java.lang.Thread.run(java.base@9-ea/Thread.java:843)
Comments
This can be fixed by the following patch: diff -r 0cd4b4def24f test/java/net/MulticastSocket/NoLoopbackPackets.java --- a/test/java/net/MulticastSocket/NoLoopbackPackets.java Mon Aug 22 17:22:09 2016 -0700 +++ b/test/java/net/MulticastSocket/NoLoopbackPackets.java Mon Aug 22 18:45:56 2016 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,6 +68,7 @@ MulticastSocket msock = null; List<SocketAddress> failedGroups = new ArrayList<SocketAddress>(); + Sender sender = null; try { msock = new MulticastSocket(); int port = msock.getLocalPort(); @@ -80,9 +81,8 @@ groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port)); groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port)); - Thread sender = new Thread(new Sender(groups)); - sender.setDaemon(true); // we want sender to stop when main thread exits - sender.start(); + sender = new Sender(groups); + new Thread(sender).start(); // Now try to receive multicast packets. we should not see any of them // since we disable loopback mode. @@ -107,6 +107,9 @@ } } finally { if (msock != null) try { msock.close(); } catch (Exception e) {} + if (sender != null) { + sender.stop(); + } } if (failedGroups.size() > 0) { @@ -119,6 +122,7 @@ static class Sender implements Runnable { private List<SocketAddress> sendToGroups; + private volatile boolean stop; public Sender(List<SocketAddress> groups) { sendToGroups = groups; @@ -136,7 +140,7 @@ MulticastSocket msock = new MulticastSocket(); msock.setLoopbackMode(true); // disable loopback mode - for (;;) { + while (!stop) { for (DatagramPacket packet : packets) { msock.send(packet); } @@ -147,5 +151,9 @@ throw new RuntimeException(e); } } + + void stop() { + stop = true; + } } }
23-08-2016