Coverage Report - net.sourceforge.cobertura.util.FileLocker
 
Classes in this File Line Coverage Branch Coverage Complexity
FileLocker
0%
0/75
0%
0/16
4.4
 
 1  
 /* Cobertura - http://cobertura.sourceforge.net/
 2  
  *
 3  
  * Copyright (C) 2006 John Lewis
 4  
  * Copyright (C) 2006 Mark Doliner
 5  
  *
 6  
  * Note: This file is dual licensed under the GPL and the Apache
 7  
  * Source License 1.1 (so that it can be used from both the main
 8  
  * Cobertura classes and the ant tasks).
 9  
  *
 10  
  * Cobertura is free software; you can redistribute it and/or modify
 11  
  * it under the terms of the GNU General Public License as published
 12  
  * by the Free Software Foundation; either version 2 of the License,
 13  
  * or (at your option) any later version.
 14  
  *
 15  
  * Cobertura is distributed in the hope that it will be useful, but
 16  
  * WITHOUT ANY WARRANTY; without even the implied warranty of
 17  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 18  
  * General Public License for more details.
 19  
  *
 20  
  * You should have received a copy of the GNU General Public License
 21  
  * along with Cobertura; if not, write to the Free Software
 22  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 23  
  * USA
 24  
  */
 25  
 
 26  
 package net.sourceforge.cobertura.util;
 27  
 
 28  
 import java.io.File;
 29  
 import java.io.FileNotFoundException;
 30  
 import java.io.RandomAccessFile;
 31  
 import java.lang.reflect.InvocationTargetException;
 32  
 import java.lang.reflect.Method;
 33  
 
 34  
 /**
 35  
  * This class controls access to any file so that multiple JVMs will
 36  
  * not be able to write to the file at the same time.
 37  
  *
 38  
  * A file called "filename.lock" is created and Java's FileLock class
 39  
  * is used to lock the file.
 40  
  *
 41  
  * The java.nio classes were introduced in Java 1.4, so this class
 42  
  * does a no-op when used with Java 1.3.  The class maintains
 43  
  * compatability with Java 1.3 by accessing the java.nio classes
 44  
  * using reflection.
 45  
  *
 46  
  * @author John Lewis
 47  
  * @author Mark Doliner
 48  
  */
 49  
 public class FileLocker
 50  
 {
 51  
 
 52  
         /**
 53  
          * An object of type FileLock, created using reflection.
 54  
          */
 55  0
         private Object lock = null;
 56  
 
 57  
         /**
 58  
          * An object of type FileChannel, created using reflection.
 59  
          */
 60  0
         private Object lockChannel = null;
 61  
 
 62  
         /**
 63  
          * A file called "filename.lock" that resides in the same directory
 64  
          * as "filename"
 65  
          */
 66  
         private File lockFile;
 67  
 
 68  
         public FileLocker(File file)
 69  0
         {
 70  0
                 String lockFileName = file.getName() + ".lock";
 71  0
                 File parent = file.getParentFile();
 72  0
                 if (parent == null)
 73  
                 {
 74  0
                         lockFile = new File(lockFileName);
 75  0
                 }
 76  
                 else
 77  
                 {
 78  0
                         lockFile = new File(parent, lockFileName);
 79  
                 }
 80  0
                 lockFile.deleteOnExit();
 81  0
         }
 82  
 
 83  
         /**
 84  
          * Obtains a lock on the file.  This blocks until the lock is obtained.
 85  
          */
 86  
         public boolean lock()
 87  
         {
 88  0
                 String useNioProperty = System.getProperty("cobertura.use.java.nio");
 89  0
                 if (System.getProperty("java.version").startsWith("1.3") ||
 90  
                                 ((useNioProperty != null) && useNioProperty.equalsIgnoreCase("false")))
 91  
                 {
 92  0
                         return true;
 93  
                 }
 94  
 
 95  
                 try
 96  
                 {
 97  0
                         Class aClass = Class.forName("java.io.RandomAccessFile");
 98  0
                         Method method = aClass.getDeclaredMethod("getChannel", (Class[])null);
 99  0
                         lockChannel = method.invoke(new RandomAccessFile(lockFile, "rw"), (Object[])null);
 100  
                 }
 101  0
                 catch (FileNotFoundException e)
 102  
                 {
 103  0
                         System.err.println("Unable to get lock channel for " + lockFile.getAbsolutePath()
 104  
                                         + ": " + e.getLocalizedMessage());
 105  0
                         return false;
 106  
                 }
 107  0
                 catch (InvocationTargetException e)
 108  
                 {
 109  0
                         System.err.println("Unable to get lock channel for " + lockFile.getAbsolutePath()
 110  
                                         + ": " + e.getLocalizedMessage());
 111  0
                         return false;
 112  
                 }
 113  0
                 catch (Throwable t)
 114  
                 {
 115  0
                         System.err.println("Unable to execute RandomAccessFile.getChannel() using reflection: "
 116  
                                         + t.getLocalizedMessage());
 117  0
                         t.printStackTrace();
 118  0
                 }
 119  
 
 120  
                 try
 121  
                 {
 122  0
                         Class aClass = Class.forName("java.nio.channels.FileChannel");
 123  0
                         Method method = aClass.getDeclaredMethod("lock", (Class[])null);
 124  0
                         lock = method.invoke(lockChannel, (Object[])null);
 125  
                 }
 126  0
                 catch (InvocationTargetException e)
 127  
                 {
 128  0
                         System.err.println("---------------------------------------");
 129  0
                         e.printStackTrace(System.err);
 130  0
                         System.err.println("---------------------------------------");
 131  0
                         System.err.println("Unable to get lock on " + lockFile.getAbsolutePath() + ": "
 132  
                                         + e.getLocalizedMessage());
 133  0
                         System.err.println("This is known to happen on Linux kernel 2.6.20.");
 134  0
                         System.err.println("Make sure cobertura.jar is in the root classpath of the jvm ");
 135  0
                         System.err.println("process running the instrumented code.  If the instrumented code ");
 136  0
                         System.err.println("is running in a web server, this means cobertura.jar should be in ");
 137  0
                         System.err.println("the web server's lib directory.");
 138  0
                         System.err.println("Don't put multiple copies of cobertura.jar in different WEB-INF/lib directories.");
 139  0
                         System.err.println("Only one classloader should load cobertura.  It should be the root classloader.");
 140  0
                         System.err.println("---------------------------------------");
 141  0
                         return false;
 142  
                 }
 143  0
                 catch (Throwable t)
 144  
                 {
 145  0
                         System.err.println("Unable to execute FileChannel.lock() using reflection: "
 146  
                                         + t.getLocalizedMessage());
 147  0
                         t.printStackTrace();
 148  0
                 }
 149  
 
 150  0
                 return true;
 151  
         }
 152  
 
 153  
         /**
 154  
          * Releases the lock on the file.
 155  
          */
 156  
         public void release()
 157  
         {
 158  0
                 if (lock != null)
 159  0
                         lock = releaseFileLock(lock);
 160  0
                 if (lockChannel != null)
 161  0
                         lockChannel = closeChannel(lockChannel);
 162  0
                 lockFile.delete();
 163  0
         }
 164  
 
 165  
         private static Object releaseFileLock(Object lock)
 166  
         {
 167  
                 try
 168  
                 {
 169  0
                         Class aClass = Class.forName("java.nio.channels.FileLock");
 170  0
                         Method method = aClass.getDeclaredMethod("isValid", (Class[])null);
 171  0
                         if (((Boolean)method.invoke(lock, (Object[])null)).booleanValue())
 172  
                         {
 173  0
                                 method = aClass.getDeclaredMethod("release", (Class[])null);
 174  0
                                 method.invoke(lock, (Object[])null);
 175  0
                                 lock = null;
 176  
                         }
 177  
                 }
 178  0
                 catch (Throwable t)
 179  
                 {
 180  0
                         System.err.println("Unable to release locked file: " + t.getLocalizedMessage());
 181  0
                 }
 182  0
                 return lock;
 183  
         }
 184  
 
 185  
         private static Object closeChannel(Object channel)
 186  
         {
 187  
                 try
 188  
                 {
 189  0
                         Class aClass = Class.forName("java.nio.channels.spi.AbstractInterruptibleChannel");
 190  0
                         Method method = aClass.getDeclaredMethod("isOpen", (Class[])null);
 191  0
                         if (((Boolean)method.invoke(channel, (Object[])null)).booleanValue())
 192  
                         {
 193  0
                                 method = aClass.getDeclaredMethod("close", (Class[])null);
 194  0
                                 method.invoke(channel, (Object[])null);
 195  0
                                 channel = null;
 196  
                         }
 197  
                 }
 198  0
                 catch (Throwable t)
 199  
                 {
 200  0
                         System.err.println("Unable to close file channel: " + t.getLocalizedMessage());
 201  0
                 }
 202  0
                 return channel;
 203  
         }
 204  
 
 205  
 }