views:

1368

answers:

8

Hello again -

I am running a query on Sybase ASE that produces a ResultSet that I then traverse and write the contents out to a file. Sometimes, this will throw a NullPointerException, stating that the ResultSet is null. However, it will do this after printing out one or two records. Other times, with the same exact input, I will receive no errors.

I have been unable to consistently produce this error. The error message is pointing to a line:

output.print(rs.getString(1));

It appears to happen when the query takes a little longer to run, for some reason. The recordset returns thus far have been very small (4 to 7 records). Sometimes I'll have to run the app 3 or 4 times, then the errors will just stop, as though the query was getting "warmed up". I've run the query manually and there doesn't appear to be any performance problems.

Thanks again!

+2  A: 

I hope you will be doing it well, I mean after calling rs.next().

According to the specs. the ResultSet object should never be null, in any case. Even if no records found. Posting the code snippet and the stack trace would definitely help us in giving you a better answer.

EDIT: Since, the error is pointing to that line. It might be calling toString() method on null String, that caused NullPointerException. Not sure though, it doesn't happen in standard output (System.out.println()) if the passed argument is of String type. But you are using output.print(), so I am not sure about this. It might be calling toString() on the passed String argument, behind the scene.

Adeel Ansari
I don't know what is the type of output but I doubt any method that is passed a String will again call toString on that object
Hemal Pandya
Your doubt is correct, regarding System.out.println(). But I am not sure here. Edited the post to match the scenrio. Thanks, Hemal.
Adeel Ansari
+3  A: 

Are you sure it's the ResultSet that's null, and not the rs.getString(1)?

This is a typical Java query

preparedStatement.setLong(1, primaryKey);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next())
{
  String foo = rs.getString(1);
  if (foo != null)
    ...
}
Paul Tomblin
A: 

try wrap the stuff for accessing the data like :

if(rs!=null && rs.next()) {

// read the stuff

}

if still persists will advice to check the read value for null itself.

Nrj
I believe Tim is looking for a way to fix the problem, not work around it.
Alan Moore
This is not a work around. This will help him to nail down to the specific values which become null. I believe this is the way to start with.
Nrj
+1  A: 

What is the type of output? Does output.print method handle null?

Try checking if rs.getObject(1) is null before calling output.print(rs.getString(1))

Hemal Pandya
I don't think rs.getObject() is worth a try. Posting the stack trace will work the best.
Adeel Ansari
A: 

This morning it errored on a different line: output.write(rs.getDate(2) + " " + timeFormat.format(rs.getTime(2)) + "|");

This is within the following:

while (rs.next()){
    try{
        output.write(rs.getDate(2) + " " + timeFormat.format(rs.getTime(2)) + "|");
        ....
    }
    catch(IOException e){//error handling code}
}

output is: output = new BufferedWriter(new FileWriter(outFile));

Here is the stack trace:

Exception in thread "main" java.lang.NullPointerException
at com.sybase.jdbc3.timedio.RawDbio.reallyRead(Unknown Source)
at com.sybase.jdbc3.timedio.Dbio.doRead(Unknown Source)
at com.sybase.jdbc3.timedio.InStreamMgr.a(Unknown Source)
at com.sybase.jdbc3.timedio.InStreamMgr.doRead(Unknown Source)
at com.sybase.jdbc3.tds.TdsProtocolContext.getChunk(Unknown Source)
at com.sybase.jdbc3.tds.PduInputFormatter.a(Unknown Source)
at com.sybase.jdbc3.tds.PduInputFormatter.read(Unknown Source)
at com.sybase.jdbc3.tds.TdsInputStream.read(Unknown Source)
at com.sybase.jdbc3.utils.CacheStream.read(Unknown Source)
at com.sybase.jdbc3.tds.TdsInputStream.read(Unknown Source)
at com.sybase.jdbc3.tds.TdsInputStream.readInt(Unknown Source)
at com.sybase.jdbc3.tds.TdsDataObject.readDATETIMN(Unknown Source)
at com.sybase.jdbc3.tds.TdsJdbcInputStream.getDateObject(Unknown Source)
at com.sybase.jdbc3.jdbc.SybResultSet.getDate(Unknown Source)
at <removed>.processResults(ProcessRecords.java:118)
at <removed>.Main.main(Main.java:65)

I just ran the query manually, and the first couple of times it seemed to be timing out, and then after that, it runs really fast. So I think I've got two issues - a null value in one (or more) of the fields that output.write doesn't handle correctly (thanks for pointing that out!), and an issue with the query that is causing the field to be null to begin with (none of these fields should ever be null).

A: 

I'm wondering if this could be a threading issue. Is your app multi-threaded? Are you running it on a multi-core computer?

Alan Moore
A: 

Is the connection still active? Are you using a connection pool?

See if you can enable debug logging for that JDBC driver.

See if you can upgrade the driver to a new version.

sjbotha
A: 

I've found the solution to this problem - the database connection was getting closed too early. I didn't realize that as soon as the db connection was closed that the record pointer would end up being null - I thought the resultset would be in system memory.

The solution is to close the connection after the while(rs.next()) loop terminates.

Thanks again.