[ 
https://issues.apache.org/jira/browse/DERBY-6265?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13686715#comment-13686715
 ] 

Rick Hillegas commented on DERBY-6265:
--------------------------------------

I'm not sure what Derby can do in this situation. According to the following 
discussion, on Windows systems you can change the access mode of a directory so 
that it can be deleted itself (and File.canWrite() returns true) but you can't 
create files inside that directory: 
http://stackoverflow.com/questions/1272130/checking-for-write-access-in-a-directory-before-creating-files-inside-it
 Maybe someone who uses Windows file systems can shed some light on this 
problem.

Whatever checks we put in, it will always be possible to subvert Derby's 
understanding of whether a database is writable. Someone can always go into the 
seg0 directory and change the file permissions on the table files there.  The 
worst scenario is when someone does this on a database which is booted and 
in-use.

I would recommend the following workaround:

1) Before changing the Windows file permissions, first set 
derby.database.defaultConnectionMode=readOnlyAccess in the database.

2) Bring down the database.

3) Then change the Windows file permissions on that database directory.

Then you should be able to continue accessing other databases in read-write 
mode, but the read-only database should not be writable.

Hope this helps,
-Rick
                
> Opening a read-only database fails: "Container was opened in read-only mode"
> ----------------------------------------------------------------------------
>
>                 Key: DERBY-6265
>                 URL: https://issues.apache.org/jira/browse/DERBY-6265
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.9.1.0, 10.10.1.1
>         Environment: Windows 8 64-bit
>            Reporter: Trejkaz
>
> I created a read-only database by taking an existing database and then using 
> Windows to set the directory (which really means the files) to read-only.
> Opening the database now results in the following error:
> {noformat}
> java.sql.SQLException: Failed to start database 
> 'C:\Cases\Read-only\Stores\AnalysisDatabase' with class loader 
> sun.misc.Launcher$AppClassLoader@893886b, see the next exception for details.
>   at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
>       at org.apache.derby.impl.jdbc.Util.seeNextException(Unknown Source)
>       at org.apache.derby.impl.jdbc.EmbedConnection.bootDatabase(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.EmbedConnection.<init>(Unknown Source)
>       at org.apache.derby.impl.jdbc.EmbedConnection40.<init>(Unknown Source)
>       at org.apache.derby.jdbc.Driver40.getNewEmbedConnection(Unknown Source)
>       at org.apache.derby.jdbc.InternalDriver.connect(Unknown Source)
>       at org.apache.derby.jdbc.EmbeddedBaseDataSource.getConnection(Unknown 
> Source)
>       at 
> org.apache.derby.jdbc.EmbedPooledConnection.openRealConnection(Unknown Source)
>       at org.apache.derby.jdbc.EmbedPooledConnection.<init>(Unknown Source)
>       at org.apache.derby.jdbc.EmbedPooledConnection40.<init>(Unknown Source)
>       at org.apache.derby.jdbc.Driver40.getNewPooledConnection(Unknown Source)
>       at 
> org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource.createPooledConnection(Unknown
>  Source)
>       at 
> org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource.getPooledConnection(Unknown
>  Source)
>       at 
> com.acme.sql.ConnectionPoolManager$PooledConnectionFactory.makeObject(ConnectionPoolManager.java:218)
>       at 
> org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:974)
>       at 
> com.acme.sql.ConnectionPoolManager.getConnection(ConnectionPoolManager.java:93)
>       at 
> com.acme.storage.database.AbstractPooledDatabase.<init>(AbstractPooledDatabase.java:66)
>       ... 17 more
> Caused by: java.sql.SQLException: Failed to start database 
> 'C:\Cases\Read-only\Stores\AnalysisDatabase' with class loader 
> sun.misc.Launcher$AppClassLoader@893886b, see the next exception for details.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown
>  Source)
>       ... 36 more
> Caused by: java.sql.SQLException: Container was opened in read-only mode.
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown
>  Source)
>       at 
> org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown 
> Source)
>       at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown 
> Source)
>       ... 33 more
> Caused by: ERROR 40XD1: Container was opened in read-only mode.
>       at org.apache.derby.iapi.error.StandardException.newException(Unknown 
> Source)
>       at org.apache.derby.impl.store.raw.data.BaseContainer.use(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.raw.data.BaseContainerHandle.useContainer(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.raw.data.BaseDataFileFactory.openContainer(Unknown
>  Source)
>       at 
> org.apache.derby.impl.store.raw.data.BaseDataFileFactory.openContainer(Unknown
>  Source)
>       at org.apache.derby.impl.store.raw.xact.Xact.openContainer(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.access.conglomerate.OpenConglomerate.init(Unknown 
> Source)
>       at org.apache.derby.impl.store.access.heap.Heap.openScan(Unknown Source)
>       at org.apache.derby.impl.store.access.RAMTransaction.openScan(Unknown 
> Source)
>       at org.apache.derby.impl.store.access.RAMTransaction.openScan(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.access.PropertyConglomerate.openScan(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.access.PropertyConglomerate.saveProperty(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.access.PropertyConglomerate.setProperty(Unknown 
> Source)
>       at 
> org.apache.derby.impl.store.access.RAMTransaction.setProperty(Unknown Source)
>       at 
> org.apache.derby.impl.sql.catalog.DD_Version.applySafeChanges(Unknown Source)
>       at org.apache.derby.impl.sql.catalog.DD_Version.upgradeIfNeeded(Unknown 
> Source)
>       at 
> org.apache.derby.impl.sql.catalog.DataDictionaryImpl.loadDictionaryTables(Unknown
>  Source)
>       at org.apache.derby.impl.sql.catalog.DataDictionaryImpl.boot(Unknown 
> Source)
>       at org.apache.derby.impl.services.monitor.BaseMonitor.boot(Unknown 
> Source)
>       at org.apache.derby.impl.services.monitor.TopService.bootModule(Unknown 
> Source)
>       at 
> org.apache.derby.impl.services.monitor.BaseMonitor.startModule(Unknown Source)
>       at 
> org.apache.derby.iapi.services.monitor.Monitor.bootServiceModule(Unknown 
> Source)
>       at org.apache.derby.impl.db.BasicDatabase.boot(Unknown Source)
>       at org.apache.derby.impl.services.monitor.BaseMonitor.boot(Unknown 
> Source)
>       at org.apache.derby.impl.services.monitor.TopService.bootModule(Unknown 
> Source)
>       at 
> org.apache.derby.impl.services.monitor.BaseMonitor.bootService(Unknown Source)
>       at 
> org.apache.derby.impl.services.monitor.BaseMonitor.startProviderService(Unknown
>  Source)
>       at 
> org.apache.derby.impl.services.monitor.BaseMonitor.findProviderAndStartService(Unknown
>  Source)
>       at 
> org.apache.derby.impl.services.monitor.BaseMonitor.startPersistentService(Unknown
>  Source)
>       at 
> org.apache.derby.iapi.services.monitor.Monitor.startPersistentService(Unknown 
> Source)
>       ... 33 more
> {noformat}
> Behaviour under 10.9.1.0 is somewhat different but still undesirable. The 
> database successfully opens, but connection.isReadOnly() returns false. Our 
> application code then attempts to modify the database itself, resulting in 
> the same error above (just at a different point in the application lifecycle.)
> The last time I tested the read-only support was reading databases from 
> optical disks which is "true" read-only, but maybe this kind of read-only 
> database just isn't detected properly when the database is being opened?
> Even in the case of a read-only database, the only error I would ever expect 
> to see is: "An SQL data change is not permitted for a read-only connection, 
> user or database". I would only expect to see this when I actually make 
> changes to the database and of course, connection.isReadOnly() should return 
> false so that I don't try to.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to