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

Suresh Thalamati commented on DERBY-700:
----------------------------------------

I agree with Dan,  getLockedFile() is confusing and should not be added 
to the storage factory interfaces , if it can be avoided or  have better 
comments.
 
Just thought I will take a moment and explain, why in the first place 
I added this method, I hope it will help in finding an alternative solution 
or make the interface better. 

I was testing and developing  my solution on Windows. When I 
first implemented without adding the getLockedFile() method, by
just getting the RandomAccessFile using StorageFile.getRandomAccessFile(), 
after it is locked. I was hitting the error , java.io.IOException: 
"
The process cannot access the file because another process has locked a 
portion of the file. When it write UUID to the dbex.lck file. 
"

After bit of debugging realized , I need access to the same 
RandomAccesFile, that is used to the get the lock. So I simply
added the getLockedFile, which just return the same RandomAccessFile, 
that is used to get the file lock.  


public class writeLock {
        public static void main(String[] args) throws Exception 
        {
        File lf = new File("dbex.lck");
        RandomAccessFile raf1 = new RandomAccessFile(lf, "rw");
        FileChannel fc = raf1.getChannel();
        FileLock lock = fc.tryLock();

        // attempt to write to locked file using another
        //
        RandomAccessFile raf2 =  new RandomAccessFile(lf , "rw");
        // the following write is failing on windows.
        raf2.writeChars("Derby is great ");
    }
}

For example , in the above code. Last write will fail with the error:
Exception in thread "main" java.io.IOException: The process cannot access the 
file because another process has locked a portion of the file. 

I did not verify, if this is the case in the non-window environment too. This
fix is mainly  for non-window environment, so If on other platforms this is 
not issue then  the getLockedFile() can be replaced with the 
StorageFile.getRandomAccesFile(). My concern is, How to confirm all 
non-window environments will not give the above error. 

First I thought of   putting the new intraJVM lock code in the storage
factory, where getExclusiveFileLock() is implemented, For me 
It looked worse alternative too  getLockedFile() method, because then 
getExlusiveFileLock() method semantics gets more confusing. 

Another solution I was thinking that may work without adding the 
*getLockedFile() is  to use the range lock. like FileLock lock = 
fc.tryLock(0, 10 ,false), and write to the file after the 10th byte. 
This may need a new method getExclusiveLock() , which takes range.

May be simple solution is to add a new call, getExclusiveFileLock() 
method that takes RandomAcceesFile as the argument.

To start with the reason we are in this mess is the getExclusiveLock() 
implementation is not matching the way java interfaces work. Ideally 
store code should hold on to the RandomAccessFile used for the lock,
not the storage factory implementraion. Ideally StorageRandomAccessFile 
should give handle to the StorageFileChannel, which has the tryLock() 
method, that returns FileLock.  


Thanks
-suresh



> Derby does not prevent dual boot of database from different classloaders on 
> Linux
> ---------------------------------------------------------------------------------
>
>                 Key: DERBY-700
>                 URL: https://issues.apache.org/jira/browse/DERBY-700
>             Project: Derby
>          Issue Type: Bug
>          Components: Store
>    Affects Versions: 10.1.2.1
>         Environment: ava -version
> java version "1.4.2_08"
> Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_08-b03)
> Java HotSpot(TM) Client VM (build 1.4.2_08-b03, mixed mode)
>            Reporter: Kathey Marsden
>            Assignee: Kathey Marsden
>            Priority: Critical
>             Fix For: 10.3.0.0
>
>         Attachments: DERBY-700.diff, DERBY-700.stat, 
> derby-700_06_07_07_diff.txt, derby-700_06_07_07_stat.txt, derby-700_diff.txt, 
> derby-700_stat.txt, DERBY-700_v1_use_to_run_DualBootrepro_multithreaded.diff, 
> DERBY-700_v1_use_to_run_DualBootrepro_multithreaded.stat, 
> derby-700_with_NPE_fix_diff.txt, derby-700_with_NPE_fix_stat.txt, derby.log, 
> derby700_singleproperty_v1.diff, derby700_singleproperty_v1.stat, 
> DualBootRepro.java, DualBootRepro2.zip, DualBootRepro_mutltithreaded.tar.bz2, 
> releaseNote.html
>
>
> Derby does not prevent dual boot from two different classloaders on Linux.
> To reproduce run the  program DualBootRepro with no derby jars in your 
> classpath. The program assumes derby.jar is in 10.1.2.1/derby.jar, you can 
> change the location by changing the DERBY_LIB_DIR variable.
> On Linux the output is:
> $java -cp . DualBootRepro
> Loading derby from file:10.1.2.1/derby.jar
> 10.1.2.1/derby.jar
> Booted database in loader [EMAIL PROTECTED]
> FAIL: Booted database in 2nd loader [EMAIL PROTECTED]
> On Windows I get the expected output.
> $ java -cp . DualBootRepro
> Loading derby from file:10.1.2.1/derby.jar
> 10.1.2.1/derby.jar
> Booted database in loader [EMAIL PROTECTED]
> PASS: Expected exception for dualboot:Another instance of Derby may have 
> already booted the database D:\marsden\repro\dualboot\mydb.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to