IO Error: Got minus one from a read call

2019-07-07 03:26发布

问题:

I am running out of time and ideas. I need to make this simulation of booking an entire plane using Java and an Oracle Database.

We have a few instructions on how to do it and what is expected, but our code keeps having this really odd and unexpected behaviour.

The database looks like this:

We need to have a pool of threads running constantly to simulate 10 simultaneous users trying to book a plane. When a thread ends, another one takes its place. Some of the threads have to do it instantly (random chance) both reserve and book. Others will reserve, then decide for a second if they want to book or not. If they decide to wait and then book another thread might reserve in the meantime which means the thread lose that reservation and will terminate. It can also wait for an extended time, in which it will be considered as a timeout.

Now here are the weird parts:

  1. It then tells me the error of the title.
  2. It then shows me to the HelperClass.java line about checking if everything is booked (included below).

From Master.java

public static void main(String[] args) throws InterruptedException, ExecutionException {

    long start = System.nanoTime();
    Random r = new Random(start);
    ExecutorService pool = Executors.newFixedThreadPool(10);
    int threadsStarted = 0;
    List<Future<Integer>> results = new ArrayList<>();
    do {
        // TODO: Check for available seats left
        long id = r.nextLong();
        Future<Integer> submit = pool.submit(new UserThread(id));
        results.add(submit);
        threadsStarted++;
        id++;
    } while (!HelperClass.isAllBooked("CR9"));

    pool.shutdown();

From HelperClass.java

public static boolean isAllBooked(String plane_no) {
    String sql = "SELECT * FROM SEAT WHERE plane_no=?";

    try(Connection conn = getConnection("db_010", "db2014");
            PreparedStatement st = conn.prepareStatement(sql)) {
        st.setString(1, plane_no);
        ResultSet rs = st.executeQuery();
        while (rs.next()) {
            int i = rs.getInt("BOOKED");
            if (rs.wasNull()) {
                return false;
            }
        }
    } catch (SQLException ex) {
        System.out.println("[HELPER CLASS] SQL ERROR: " + ex.getMessage());
    }
    return true;
}

To not fill this post with code step by step, I just stop here and will provide if you need more to see the issues in this code. Please note that this is prototyping code and is not supposed to be amazingly secure or follow every code ethic on earth.

Full stack:

[HELPER CLASS] SQL ERROR: IO Error: Got minus one from a read call
Exception in thread "main" java.lang.NullPointerException
    at dbassignment4.HelperClass.isAllBooked(HelperClass.java:50)
    at dbassignment4.Master.main(Master.java:36)
apr 28, 2014 8:02:59 PM dbassignment4.UserThread getConnection
SEVERE: null
java.sql.SQLRecoverableException: IO Error: Got minus one from a read call
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:673)
    at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:715)
    at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:385)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:30)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:564)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at dbassignment4.UserThread.getConnection(UserThread.java:76)
    at dbassignment4.UserThread.reserve(UserThread.java:63)
    at dbassignment4.UserThread.call(UserThread.java:35)
    at dbassignment4.UserThread.call(UserThread.java:21)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: oracle.net.ns.NetException: Got minus one from a read call
    at oracle.net.ns.Packet.receive(Packet.java:314)
    at oracle.net.ns.NSProtocolStream.negotiateConnection(NSProtocolStream.java:153)
    at oracle.net.ns.NSProtocol.connect(NSProtocol.java:263)
    at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1360)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:486)
    ... 15 more

BUILD STOPPED (total time: 36 seconds)

回答1:

  1. You are getting IO Exception. Possible reasons for this . Your server is not responding. if its already working check the connection through some tools ( sqlplus/toad/tns) , if everything works you can retry ( if datasource involved re-establish/refresh the state)

  2. Seems you are getting connection in your helper class using getconnection() method. In which you may excepting connection and doing some operation. You are getting Null Pointer exception at the getConnection method. You have to show us to give what is cause for Nullpointer.

  3. Finaly, you can simply write query to return true/false if any one of the seat not booked instead of iterating all the results and stop when its found not booked.



回答2:

I think this might be the problem

    ResultSet rs = st.executeQuery();
    while (rs.next()) {
        int i = rs.getInt("BOOKED");
        if (rs.wasNull()) {
            return false;
        }
    }

If rs is NULL, then you are calling getInt on a null, causing a NPE