Derby
  1. Derby
  2. DERBY-5173

RAFContainer.privGetRandomAccessFile() unwraps wrong exception type

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.7.1.1
    • Fix Version/s: 10.8.1.2
    • Component/s: Store
    • Labels:
      None

      Description

      RAFContainer.privGetRandomAccessFile() catches and unwraps PrivilegedActionExceptions raised in the privileged code:

      catch( PrivilegedActionException pae)

      { throw (StandardException) pae.getException(); }

      The problem is that the privileged code is this:

      case GET_RANDOM_ACCESS_FILE_ACTION:

      { return actionFile.getRandomAccessFile("rw"); }

      // end of case BACKUP_CONTAINER_ACTION

      getRandomAccessFile() only has one checked exception, and that is FileNotFoundException. If it ever happens to raise FNFE, privGetRandomAccessFile() will fail with a ClassCastException and hide the underlying error.

      1. derby-5173-1a.diff
        1 kB
        Knut Anders Hatlen

        Activity

        Hide
        Knut Anders Hatlen added a comment -

        To reproduce, follow these steps:

        • create a new, unencrypted database
        • remove the write permission from the db/seg0 directory (chmod 555 db/seg0)
        • reboot the database with encryption enabled, and see it fail with a ClassCastException:

        ij> connect 'jdbc:derby:db;dataEncryption=true;bootPassword=abc1234xyz';
        ERROR XJ040: Failed to start database 'db' with class loader sun.misc.Launcher$AppClassLoader@1a336d5, see the next exception for details.
        ERROR XJ001: Java exception: 'java.io.FileNotFoundException cannot be cast to org.apache.derby.iapi.error.StandardException: java.lang.ClassCastException'.

        Show
        Knut Anders Hatlen added a comment - To reproduce, follow these steps: create a new, unencrypted database remove the write permission from the db/seg0 directory (chmod 555 db/seg0) reboot the database with encryption enabled, and see it fail with a ClassCastException: ij> connect 'jdbc:derby:db;dataEncryption=true;bootPassword=abc1234xyz'; ERROR XJ040: Failed to start database 'db' with class loader sun.misc.Launcher$AppClassLoader@1a336d5, see the next exception for details. ERROR XJ001: Java exception: 'java.io.FileNotFoundException cannot be cast to org.apache.derby.iapi.error.StandardException: java.lang.ClassCastException'.
        Hide
        Knut Anders Hatlen added a comment -

        I'm not sure if there's an easy way to add a regression test for this bug, or if it's worthwhile given that the issue is mostly cosmetic and the bug is somewhat of an edge case.

        In any case, here's a fix for the problem. Following the steps to reproduce described in the previous comment, I now get this error message:

        ij> connect 'jdbc:derby:db;dataEncryption=true;bootPassword=abc1234xyz';
        ERROR XJ040: Failed to start database 'db' with class loader sun.misc.Launcher$AppClassLoader@18a80d4, see the next exception for details.
        ERROR XBCXU: Encryption of an un-encrypted database failed: Exception during creation of file /tmp/db/seg0/n461.dat for container

        The ClassCastException is gone. And if ij had called printStackTrace() or otherwise followed the getCause() exception chain (it currently only follows the SQLException.getNextException() chain), it would have shown the underlying exception too:

        Caused by: java.io.FileNotFoundException: /tmp/db/seg0/n461.dat (Permission denied)
        at java.io.RandomAccessFile.open(Native Method)
        at java.io.RandomAccessFile.<init>(RandomAccessFile.java:233)
        at org.apache.derby.impl.io.DirRandomAccessFile.<init>(DirRandomAccessFile.java:57)
        at org.apache.derby.impl.io.DirFile4.getRandomAccessFile(DirFile4.java:275)
        at org.apache.derby.impl.store.raw.data.RAFContainer.run(RAFContainer.java:1692)
        ... 45 more

        Show
        Knut Anders Hatlen added a comment - I'm not sure if there's an easy way to add a regression test for this bug, or if it's worthwhile given that the issue is mostly cosmetic and the bug is somewhat of an edge case. In any case, here's a fix for the problem. Following the steps to reproduce described in the previous comment, I now get this error message: ij> connect 'jdbc:derby:db;dataEncryption=true;bootPassword=abc1234xyz'; ERROR XJ040: Failed to start database 'db' with class loader sun.misc.Launcher$AppClassLoader@18a80d4, see the next exception for details. ERROR XBCXU: Encryption of an un-encrypted database failed: Exception during creation of file /tmp/db/seg0/n461.dat for container The ClassCastException is gone. And if ij had called printStackTrace() or otherwise followed the getCause() exception chain (it currently only follows the SQLException.getNextException() chain), it would have shown the underlying exception too: Caused by: java.io.FileNotFoundException: /tmp/db/seg0/n461.dat (Permission denied) at java.io.RandomAccessFile.open(Native Method) at java.io.RandomAccessFile.<init>(RandomAccessFile.java:233) at org.apache.derby.impl.io.DirRandomAccessFile.<init>(DirRandomAccessFile.java:57) at org.apache.derby.impl.io.DirFile4.getRandomAccessFile(DirFile4.java:275) at org.apache.derby.impl.store.raw.data.RAFContainer.run(RAFContainer.java:1692) ... 45 more
        Hide
        Knut Anders Hatlen added a comment -

        Committed revision 1088491.

        Show
        Knut Anders Hatlen added a comment - Committed revision 1088491.

          People

          • Assignee:
            Knut Anders Hatlen
            Reporter:
            Knut Anders Hatlen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development