Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6231286

"FATAL ERROR in native method: ... with exception ..." from DatagramSocket.recei

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 6
    • 5.0
    • core-libs
    • beta
    • x86
    • linux

      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

            yuwangsunw Yujiang Wang (Inactive)
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: