JDK-4030767 : ObjectInputStream constructor under certain conditions blocks program execution
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Affected Version: 1.1
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_2.5.1
  • CPU: sparc
  • Submitted: 1997-02-06
  • Updated: 1997-03-03
  • Resolved: 1997-03-03
Related Reports
Duplicate :  
Description

Name: mc57594			Date: 02/06/97


The complete source code is at the bottom of this message

aFromClient = new ObjectInputStream(aSock.getInputStream());    // line y
aToClient   = new ObjectOutputStream(aSock.getOutputStream());  // line x

The program blocks on the first line.
(The problem seens to lie in the ObjectInputStream constructor
because getInputStream() seemed to work well)

If you swap the two lines, everything works well.

================================================================
Sample code:

Note: the problem is only in the server process

Server.java :
-----------------------------------------------------------
import java.net.*;
import java.io.*;

public class Server {

  public static void main(String[] pArgs) {
    ObjectOutputStream aToClient = null;
    ObjectInputStream  aFromClient = null;
    ServerSocket       aListenSock = null; 
    String             aConnectionID = null;
    Socket             aSock = null;

    try {
      aListenSock = new ServerSocket(12345);
      System.out.println("Waiting for client connection...");
      aSock = aListenSock.accept();
    } catch (IOException e) { System.out.println(e); }
    // handle client connection
    System.out.println("Setting object streams...");
    try {
      System.out.println("1");
      // swap line x and line y and it will work
      aFromClient = new ObjectInputStream(aSock.getInputStream());    // line y
      System.out.println("2");
      aToClient   = new ObjectOutputStream(aSock.getOutputStream());  // line x
      System.out.println("3");
    } catch(UnknownHostException e)   { System.out.println(e);}
    catch(StreamCorruptedException e) { System.out.println(e);}
    catch(IOException e)              { System.out.println(e);}
    // register connection ID
    System.out.println("Trying to register new connection...");
    try {
      aConnectionID = (String) aFromClient.readObject();
    } catch(UnknownHostException e) { System.out.println(e);}
    catch (StreamCorruptedException e) { System.out.println(e);}
    catch (IOException e) { System.out.println(e);}
    catch (ClassNotFoundException e) { System.out.println(e);}
    System.out.println("Read string: " + aConnectionID);
    try {
      aSock.close();
    } catch (IOException e) { System.out.println(e); }
  }
}
-----------------------------------------------------------
Client.java
-----------------------------------------------------------
import java.net.*;
import java.io.*;

public class Client {
  public static void main(String[] pArgs) {
    Socket             aSock = null;       
    ObjectInputStream  aFromServer = null; 
    ObjectOutputStream aToServer = null;   

    boolean lSuccessfulConnection = true;
    try {
      aSock = new Socket("localhost", 12345);
      aFromServer = new ObjectInputStream(aSock.getInputStream());
      aToServer = new ObjectOutputStream(aSock.getOutputStream());
    }
    catch (UnknownHostException e) {
      System.out.println(e);
      lSuccessfulConnection = false;
    }
    catch (IOException e) { 
      System.out.println(e);
      lSuccessfulConnection = false;
    }
  
    if (lSuccessfulConnection == true) {
      try {
        aToServer.writeObject("Hello");
      } catch(IOException e) {
        System.out.println(e);
      }
    }
    try {
      aSock.close();
    } catch (IOException e) { System.out.println(e); }
  }
}




company  -  Beltron Technologies (http://www.beltrom.com)  , email  -  ###@###.###
======================================================================

Comments
EVALUATION The constructor of ObjectInputStream is documented and designed to read the stream header from the stream. It will naturally block waiting for this data if the data is not available. The user of the stream must be prepared for it to block.
11-06-2004

WORK AROUND Name: mc57594 Date: 02/06/97 Swap the two lines. Replace: aFromClient = new ObjectInputStream(aSock.getInputStream()); // line y aToClient = new ObjectOutputStream(aSock.getOutputStream()); // line x with: aToClient = new ObjectOutputStream(aSock.getOutputStream()); // line x aFromClient = new ObjectInputStream(aSock.getInputStream()); // line y But you'll agree it's just a patch... ======================================================================
11-06-2004

PUBLIC COMMENTS The constructor for ObjectInputStream is designed to read the stream header before returning. If the magic number and version are not available the stream will block.
10-06-2004