JDK-6231286 : "FATAL ERROR in native method: ... with exception ..." from DatagramSocket.recei
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2005-02-21
  • Updated: 2011-02-16
  • Resolved: 2005-07-13
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 6
6 betaFixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)
$ java -version
java version "1.6.0-ea"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-ea-b23)
Java HotSpot(TM) Client VM (build 1.6.0-ea-b23, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Linux jared-d800 2.6.8.1-24mdk #1 Fri Jan 14 03:01:00 MST 2005 i686 Intel(R) Pentium(R) M processor 1600MHz unknown GNU/Linux

A DESCRIPTION OF THE PROBLEM :
When I close a java.net.DatagramSocket that's blocking another thread
with the receive method, and I started the JVM with -Xcheck:jni, I get
the following output indicating a bug in the runtime library:

FATAL ERROR in native method: JNI call made with exception pending
	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.DatagramSocket.receive(DatagramSocket.java:712)
	- locked <0x659076d8> (a java.net.DatagramPacket)
	- locked <0x658fd9d8> (a java.net.DatagramSocket)
	at JNIBug$ReceiveRunner.run(JNIBug.java:42)
	at java.lang.Thread.run(Thread.java:595)
Aborted


* NOTE: Scalent has filed this thirdparty bug internally as #1981.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
* Compile the source example. I called it JNIBug.java:

  $ javac JNIBug.java

* Execute the test case with and without -Xcheck:jni.

  $ java -cp . JNIBug
  Success.


  $ java -Xcheck:jni -cp . JNIBug
  FATAL ERROR in native method: JNI call made with exception pending
  	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
  	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
  	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
  	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
  	at java.net.DatagramSocket.receive(DatagramSocket.java:712)
  	- locked <0x659076d8> (a java.net.DatagramPacket)
  	- locked <0x658fd9d8> (a java.net.DatagramSocket)
  	at JNIBug$ReceiveRunner.run(JNIBug.java:42)
  	at java.lang.Thread.run(Thread.java:595)
  Aborted


* Note: This same byte code executes with the same arguments
  successfully with 1.4.2_06. I believe that the same bug likely
  exists in 1.4.2_06, but 1.5 has added a new check for JNI code,
  uncovering this bug.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The compiled class JNIBug, when executed, should print:
	
Success.

ACTUAL -
When executed with -Xcheck:jni, the following output is printed:

FATAL ERROR in native method: JNI call made with exception pending
	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.DatagramSocket.receive(DatagramSocket.java:712)
	- locked <0x659076d8> (a java.net.DatagramPacket)
	- locked <0x658fd9d8> (a java.net.DatagramSocket)
	at JNIBug$ReceiveRunner.run(JNIBug.java:42)
	at java.lang.Thread.run(Thread.java:595)
Aborted

ERROR MESSAGES/STACK TRACES THAT OCCUR :
FATAL ERROR in native method: JNI call made with exception pending
	at java.net.PlainDatagramSocketImpl.receive0(Native Method)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
	- locked <0x65906ea8> (a java.net.PlainDatagramSocketImpl)
	at java.net.DatagramSocket.receive(DatagramSocket.java:712)
	- locked <0x659076d8> (a java.net.DatagramPacket)
	- locked <0x658fd9d8> (a java.net.DatagramSocket)
	at JNIBug$ReceiveRunner.run(JNIBug.java:42)
	at java.lang.Thread.run(Thread.java:595)
Aborted

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.io.IOException;

public class JNIBug {
    public static class ReceiveRunner implements Runnable {

        private Thread m_myThread;
        private DatagramSocket m_socket;

        public final void run() {
            // Record the thread we're in.
            synchronized(this) {
                m_myThread = Thread.currentThread();
            }

            DatagramSocket socket = null;
            try {
                // Set up a DatagramSocket and listen on it. No one is
                // going to send any packets, the intention is that we
                // close the socket underneith the "receive" call.
                socket = new DatagramSocket(new InetSocketAddress(9888));
                socket.setSoTimeout(0);
            } catch(SocketException e) {
                System.err.println("FAILURE: Could not create socket: " +
                                   e.getMessage());
                e.printStackTrace();
                System.exit(-1);
            }
        
            synchronized(this) {
                m_socket = socket;
            }
        
            byte[] dgBuf = new byte[100];
            DatagramPacket dg = new DatagramPacket(dgBuf, dgBuf.length);

            // Start receiving. This will never return...
            try {
                socket.receive(dg);
            } catch(SocketException e) {
                
                if (Thread.interrupted())
                    // Success... This is what we were looking for. We were
                    // interrupted and now we can go about our business.
                    return;

                // Bad. Something bad happened.
                System.err.println("FAILURE: Could not create socket: " +
                                   e.getMessage());
                e.printStackTrace();
                System.exit(-1);
                
            } catch(IOException e) {
                System.err.println("FAILURE: Could not create socket: " +
                                   e.getMessage());
                e.printStackTrace();
                System.exit(-1);
            }

            // If we fall through, we've failed.
            System.err.println("FAILURE: Did not expect to actually receive a packet.");
            System.exit(-1);
        }

        public void interruptReceive() {
            // With the lock, interrupt this thread and then close the
            // datagram socket.
            synchronized(this) {
            
                m_myThread.interrupt();
            
                if (m_socket != null)
                    m_socket.close();
            }
        }
    }

    public static void main(String[] args) {
        try {
            safeMain();
        } catch(Throwable e) {
            System.err.println("FAILURE: " + e.getMessage());
            e.printStackTrace();
            System.exit(-1);
        }

        System.out.println("Success.");
        System.exit(0);
    }
    
    public static void safeMain() throws Throwable {

        // Create the thread and start it running.
        ReceiveRunner runner = new ReceiveRunner();
        Thread t = new Thread(runner);
        t.start();

        // Wait a bit for it to get situated.
        Thread.sleep(2000);

        // Tell it to stop waiting for a packet.
        runner.interruptReceive();

        // Wait.
        t.join();
    }

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Don't run the JVM with -Xcheck:jni
###@###.### 2005-2-21 06:25:40 GMT

Comments
EVALUATION Duplicated with 6273094. So this bug will serve the same purpose for Mustang as 6273094 for 5.0u4. ###@###.### 2005-06-10 07:21:35 GMT
10-06-2005