Menu

#1 "double get" exception on opening unclosed database

closed-fixed
nobody
None
7
2000-04-11
2000-04-03
No

[reported by Alex Boisvert <boisvert@exoffice.com>]

Hi Cees,

I've found a bug in PageManager... :(

Luckily, I've also found a way to reproduce it systematically. I've
attached to this message two .java files to reproduce the problem.

Here's the recipe to trigger the bug:

1) Run "java InsertNoClose"
This will print two "insert id=xxxxx"

2) Run "java Fetch xxxx" where xxxx is the second id shown in 1).

ie.

% java InsertNoClose
Insert id=131090
Insert id=131100

% java Fetch 131100
Fetch id = 131100

Exception in thread "main" java.lang.Error: double get for block 0
at com.cdegroot.db.recman.RecordFile.get(RecordFile.java:133)
at
com.cdegroot.db.recman.PhysicalRowIdManager.fetch(PhysicalRowIdManager.java:94)
at
com.cdegroot.db.recman.RecordManager.fetch(RecordManager.java:156)
at Fetch.main(Fetch.java:22)

I don't know if you have time to look into this bug in the near future.
I will certainly have a quick look in the code to see if it's an easy
fix....

In any case, I'd like to know what you think of this.

Regards,
alex.

PS: We (at Exoffice) really like the PageManager. Thanks for your
work.

--
Alex Boisvert, XJ2EE Project Manager
Exoffice Technologies, Inc.
http://www.exoffice.com
mailto:boisvert@exoffice.com

2. InsertNoClose.java

import java.io.*;
import java.util.*;
import com.cdegroot.db.recman.*;

/***********************************************************************
* Demonstrate bug in PageManager
*
* 1) Insert two records (and make sure we can re-read them)
* 2) Exit the application without closing the RecordManager
**********************************************************************/
public class InsertNoClose {

public static void main(String[] args) {
try {
RecordManager recman = new RecordManager("test");
long id;
byte[] buf;

id = recman.insert(new byte[1024]);
System.out.println("Insert id="+id);
buf = recman.fetch(id);

id = recman.insert(new byte[1024]);
System.out.println("Insert id="+id);
buf = recman.fetch(id);

// force exit (no explicit close call)
System.exit(1);

} catch (IOException ioe) {
ioe.printStackTrace();
}
}

}

3. Fetch.java

import java.io.*;
import java.util.*;
import com.cdegroot.db.recman.*;

/***********************************************************************
* Fetch records from database
*
* Usage: java Fetch recordNumber ...
**********************************************************************/
public class Fetch {

public static void main(String[] args) {
try {
RecordManager recman = new RecordManager("test");
long id;
byte[] buf;

for (int i=0; i<args.length; i++) {
id = Long.parseLong(args[i]);
System.out.println("fetch id="+id);
buf = recman.fetch(id);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}

}

Discussion

  • Cees de Groot

    Cees de Groot - 2000-04-03
    • priority: 5 --> 7
     
  • Alex Boisvert

    Alex Boisvert - 2000-04-11

    I\'ve submitted a fix for this.

    cvs -z9 commit -m \"Fix [ Bug #103848 ] \"double get\" exception on opening unclosed database\" TransactionManager.java (in directory C:\\sourceforge\\jdbm\\db\\com\\cdegroot\\db\\recman)
    Checking in TransactionManager.java;
    /cvsroot/jdbm/db/com/cdegroot/db/recman/TransactionManager.java,v <-- TransactionManager.java
    new revision: 1.2; previous revision: 1.1
    done

    The TransactionManager was serializing the same BlockIo instance twice in the same ObjectOutputStream... well, as it turns out, the ObjectOutputStream only serialized the first \"version\" of the BlockIo (as per serialization spec.). Thus, the transaction log was inconsistent with the changes made in the file.

     
  • Alex Boisvert

    Alex Boisvert - 2000-04-11
    • status: Error - status not found --> closed-fixed
     

Log in to post a comment.