List of usage examples for java.nio.channels FileLock release
public abstract void release() throws IOException;
From source file:dk.netarkivet.harvester.indexserver.FileBasedCache.java
/** * Ensure that a file containing the appropriate content exists for the ID. * If the content cannot be found, this method may return null (if I is a * simple type) or an appropriate subset (if I is, say, a Set) indicating * the data that is actually available. In the latter case, calling cache * on the returned set should always fill the file for that subset (barring * catastrophic failure).// w w w. j ava 2s.co m * * Locking: If the file is not immediately found, we enter a file-creation * state. To avoid corrupted data, we must ensure that only one cache * instance, and only one thread within any instance, creates the file. Thus * as long as somebody else seems to be creating the file, we wait and see * if they finish. This is checked by having an exclusive lock on a * ".working" file (we cannot use the result file, as it has to be created * to be locked, and we may end up with a different cached file than we * thought, see above). The .working file itself is irrelevant, only the * lock on it matters. * * @param id Some sort of id that uniquely identifies the item within the * cache. * * @return The id given if it was successfully fetched, otherwise null if * the type parameter I does not allow subsets, or a subset of id if * it does. This subset should be immediately cacheable. */ public I cache(I id) { ArgumentNotValid.checkNotNull(id, "id"); File cachedFile = getCacheFile(id); try { File fileBehindLockFile = new File(cachedFile.getAbsolutePath() + ".working"); FileOutputStream lockFile = new FileOutputStream(fileBehindLockFile); FileLock lock = null; // Make sure no other thread tries to create this log.debug("Waiting to enter synchronization on " + fileBehindLockFile.getAbsolutePath().intern()); // FIXME Potential memory leak. intern() remembers all strings until JVM exits. synchronized (fileBehindLockFile.getAbsolutePath().intern()) { try { // Make sure no other process tries to create this. log.debug("locking filechannel for file '" + fileBehindLockFile.getAbsolutePath() + "' (thread = " + Thread.currentThread().getName() + ")"); try { lock = lockFile.getChannel().lock(); } catch (OverlappingFileLockException e) { // Exception is logged below throw new IOException(e.getMessage(), e); } // Now we know nobody else touches the file. // If the file already exists, just return it. if (cachedFile.exists()) { return id; } return cacheData(id); } finally { if (lock != null) { log.debug("release lock on filechannel " + lockFile.getChannel()); lock.release(); } lockFile.close(); } } } catch (IOException e) { String errMsg = "Error obtaining lock for file '" + cachedFile.getAbsolutePath() + "'."; log.warn(errMsg, e); throw new IOFailure(errMsg, e); } }
From source file:org.geoserver.platform.resource.FileLockProvider.java
public Resource.Lock acquire(final String lockKey) { // first off, synchronize among threads in the same jvm (the nio locks won't lock // threads in the same JVM) final Resource.Lock memoryLock = memoryProvider.acquire(lockKey); // then synch up between different processes final File file = getFile(lockKey); try {// ww w .j av a 2s. c o m FileOutputStream currFos = null; FileLock currLock = null; try { // try to lock int count = 0; while (currLock == null && count < maxLockAttempts) { // the file output stream can also fail to be acquired due to the // other nodes deleting the file currFos = new FileOutputStream(file); try { currLock = currFos.getChannel().lock(); } catch (OverlappingFileLockException e) { IOUtils.closeQuietly(currFos); try { Thread.sleep(20); } catch (InterruptedException ie) { // ok, moving on } } catch (IOException e) { // this one is also thrown with a message "avoided fs deadlock" IOUtils.closeQuietly(currFos); try { Thread.sleep(20); } catch (InterruptedException ie) { // ok, moving on } } count++; } // verify we managed to get the FS lock if (count >= maxLockAttempts) { throw new IllegalStateException( "Failed to get a lock on key " + lockKey + " after " + count + " attempts"); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock " + lockKey + " acquired by thread " + Thread.currentThread().getId() + " on file " + file); } // store the results in a final variable for the inner class to use final FileOutputStream fos = currFos; final FileLock lock = currLock; // nullify so that we don't close them, the locking occurred as expected currFos = null; currLock = null; return new Resource.Lock() { boolean released; public void release() { if (released) { return; } try { released = true; if (!lock.isValid()) { // do not crap out, locks usage is only there to prevent duplication of work if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock key " + lockKey + " for releasing lock is unkonwn, it means " + "this lock was never acquired, or was released twice. " + "Current thread is: " + Thread.currentThread().getId() + ". " + "Are you running two instances in the same JVM using NIO locks? " + "This case is not supported and will generate exactly this error message"); return; } } try { lock.release(); IOUtils.closeQuietly(fos); file.delete(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock " + lockKey + " released by thread " + Thread.currentThread().getId()); } } catch (IOException e) { throw new IllegalStateException( "Failure while trying to release lock for key " + lockKey, e); } } finally { memoryLock.release(); } } @Override public String toString() { return "FileLock " + file.getName(); } }; } finally { if (currLock != null) { currLock.release(); memoryLock.release(); } IOUtils.closeQuietly(currFos); file.delete(); } } catch (IOException e) { throw new IllegalStateException("Failure while trying to get lock for key " + lockKey, e); } }
From source file:org.geowebcache.locks.NIOLockProvider.java
public LockProvider.Lock getLock(final String lockKey) throws GeoWebCacheException { File file = null;/*from w ww. j a va 2 s.c om*/ // first off, synchronize among threads in the same jvm (the nio locks won't lock // threads in the same JVM) final LockProvider.Lock memoryLock = memoryProvider.getLock(lockKey); // then synch up between different processes try { file = getFile(lockKey); FileOutputStream currFos = null; FileLock currLock = null; try { // try to lock int count = 0; while (currLock == null && count < maxLockAttempts) { // the file output stream can also fail to be acquired due to the // other nodes deleting the file currFos = new FileOutputStream(file); try { currLock = currFos.getChannel().lock(); } catch (OverlappingFileLockException e) { IOUtils.closeQuietly(currFos); try { Thread.sleep(20); } catch (InterruptedException ie) { // ok, moving on } } catch (IOException e) { // this one is also thrown with a message "avoided fs deadlock" IOUtils.closeQuietly(currFos); try { Thread.sleep(20); } catch (InterruptedException ie) { // ok, moving on } } count++; } // verify we managed to get the FS lock if (count >= maxLockAttempts) { throw new GeoWebCacheException( "Failed to get a lock on key " + lockKey + " after " + count + " attempts"); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock " + lockKey + " acquired by thread " + Thread.currentThread().getId() + " on file " + file); } // store the results in a final variable for the inner class to use final FileOutputStream fos = currFos; final FileLock lock = currLock; // nullify so that we don't close them, the locking occurred as expected currFos = null; currLock = null; final File lockFile = file; return new LockProvider.Lock() { boolean released; public void release() throws GeoWebCacheException { if (released) { return; } try { released = true; if (!lock.isValid()) { // do not crap out, locks usage in GWC is only there to prevent duplication of work if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock key " + lockKey + " for releasing lock is unkonwn, it means " + "this lock was never acquired, or was released twice. " + "Current thread is: " + Thread.currentThread().getId() + ". " + "Are you running two GWC instances in the same JVM using NIO locks? " + "This case is not supported and will generate exactly this error message"); return; } } try { lock.release(); IOUtils.closeQuietly(fos); lockFile.delete(); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Lock " + lockKey + " released by thread " + Thread.currentThread().getId()); } } catch (IOException e) { throw new GeoWebCacheException( "Failure while trying to release lock for key " + lockKey, e); } } finally { memoryLock.release(); } } }; } finally { try { if (currLock != null) { currLock.release(); } IOUtils.closeQuietly(currFos); file.delete(); } finally { memoryLock.release(); } } } catch (IOException e) { throw new GeoWebCacheException("Failure while trying to get lock for key " + lockKey, e); } }
From source file:org.apache.manifoldcf.agents.output.filesystem.FileOutputConnector.java
/** Add (or replace) a document in the output data store using the connector. * This method presumes that the connector object has been configured, and it is thus able to communicate with the output data store should that be * necessary./*from w w w .j av a 2 s . c o m*/ * The OutputSpecification is *not* provided to this method, because the goal is consistency, and if output is done it must be consistent with the * output description, since that was what was partly used to determine if output should be taking place. So it may be necessary for this method to decode * an output description string in order to determine what should be done. *@param documentURI is the URI of the document. The URI is presumed to be the unique identifier which the output data store will use to process * and serve the document. This URI is constructed by the repository connector which fetches the document, and is thus universal across all output connectors. *@param outputDescription is the description string that was constructed for this document by the getOutputDescription() method. *@param document is the document data to be processed (handed to the output data store). *@param authorityNameString is the name of the authority responsible for authorizing any access tokens passed in with the repository document. May be null. *@param activities is the handle to an object that the implementer of an output connector may use to perform operations, such as logging processing activity. *@return the document status (accepted or permanently rejected). */ @Override public int addOrReplaceDocumentWithException(String documentURI, VersionContext outputDescription, RepositoryDocument document, String authorityNameString, IOutputAddActivity activities) throws ManifoldCFException, ServiceInterruption, IOException { // Establish a session getSession(); FileOutputConfig config = getConfigParameters(null); FileOutputSpecs specs = new FileOutputSpecs(getSpecNode(outputDescription.getSpecification())); ; StringBuffer path = new StringBuffer(); String errorCode = "OK"; String errorDesc = null; try { /* * make file path */ if (specs.getRootPath() != null) { path.append(specs.getRootPath()); } // If the path does not yet exist at the root level, it is dangerous to create it. File currentPath = new File(path.toString()); if (!currentPath.exists()) throw new ManifoldCFException("Root path does not yet exist: '" + currentPath + "'"); if (!currentPath.isDirectory()) throw new ManifoldCFException("Root path is not a directory: '" + currentPath + "'"); String filePath = documentURItoFilePath(documentURI); // Build path one level at a time. This is needed because there may be a collision at // every level. int index = 0; while (true) { int currentIndex = filePath.indexOf("/", index); if (currentIndex == -1) break; String dirName = filePath.substring(index, currentIndex); File newPath = new File(currentPath, dirName); index = currentIndex + 1; int suffix = 1; while (true) { if (newPath.exists() && newPath.isDirectory()) break; // Try to create it. If we fail, check if it now exists as a file. if (newPath.mkdir()) break; // Hmm, didn't create. If it is a file, we suffered a collision, so try again with ".N" as a suffix. if (newPath.exists()) { if (newPath.isDirectory()) break; newPath = new File(currentPath, dirName + "." + suffix); suffix++; } else { errorCode = activities.CREATED_DIRECTORY; errorDesc = "Could not create directory '\"+newPath+\"'. Permission issue?"; throw new ManifoldCFException(errorDesc); } } // Directory successfully created! currentPath = newPath; // Go on to the next one. } // Path successfully created. Now create file. FileOutputStream output = null; String fileName = filePath.substring(index); File outputPath = new File(currentPath, fileName); int fileSuffix = 1; while (true) { try { output = new FileOutputStream(outputPath); break; } catch (FileNotFoundException e) { // Figure out why it could not be created. if (outputPath.exists() && !outputPath.isFile()) { // try a new file outputPath = new File(currentPath, fileName + "." + fileSuffix); fileSuffix++; continue; } // Probably some other error errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Could not create file '" + outputPath + "': " + e.getMessage(); throw new ManifoldCFException(errorDesc, e); } } try { /* * lock file */ FileChannel channel = output.getChannel(); FileLock lock = channel.tryLock(); if (lock == null) { errorCode = ServiceInterruption.class.getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Could not lock file: '" + outputPath + "'"; throw new ServiceInterruption(errorDesc, null, 1000L, -1L, 10, false); } try { /* * write file */ InputStream input = document.getBinaryStream(); byte buf[] = new byte[65536]; int len; while ((len = input.read(buf)) != -1) { output.write(buf, 0, len); } output.flush(); } finally { // Unlock try { if (lock != null) { lock.release(); } } catch (ClosedChannelException e) { } } } finally { try { output.close(); } catch (IOException e) { } } } catch (URISyntaxException e) { errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Failed to write document due to: " + e.getMessage(); handleURISyntaxException(e); return DOCUMENTSTATUS_REJECTED; } catch (FileNotFoundException e) { errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Failed to write document due to: " + e.getMessage(); handleFileNotFoundException(e); return DOCUMENTSTATUS_REJECTED; } catch (SecurityException e) { errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Failed to write document due to: " + e.getMessage(); handleSecurityException(e); return DOCUMENTSTATUS_REJECTED; } catch (IOException e) { errorCode = e.getClass().getSimpleName().toUpperCase(Locale.ROOT); errorDesc = "Failed to write document due to: " + e.getMessage(); handleIOException(e); return DOCUMENTSTATUS_REJECTED; } finally { activities.recordActivity(null, INGEST_ACTIVITY, new Long(document.getBinaryLength()), documentURI, errorCode, errorDesc); } return DOCUMENTSTATUS_ACCEPTED; }
From source file:org.deegree.maven.PortnumberMojo.java
@Override public void execute() throws MojoExecutionException, MojoFailureException { PrintStream out = null;/*w w w. j a v a 2 s . com*/ BufferedReader reader = null; FileLock lock = null; FileInputStream fis = null; try { File portfile = new File(System.getProperty("java.io.tmpdir") + "/portnumbers"); int port = 1025; if (portfile.exists()) { fis = new FileInputStream(portfile); reader = new BufferedReader(new InputStreamReader(fis, "UTF-8")); boolean read = false; while (!read) { try { port = Integer.parseInt(reader.readLine()) + 1; read = true; } catch (NumberFormatException e) { // someone is currently writing try { Thread.sleep(100); } catch (InterruptedException e1) { return; } finally { closeQuietly(out); closeQuietly(reader); closeQuietly(fis); } } } reader.close(); } if (port > 18000) { port = 1025; } getLog().info("Using portnumber " + port + " for this run."); project.getProperties().put("portnumber", "" + port); FileOutputStream fos = new FileOutputStream(portfile); out = new PrintStream(fos, true, "UTF-8"); while ((lock = fos.getChannel().tryLock()) == null) { try { Thread.sleep(100); } catch (InterruptedException e) { return; } } out.println("" + port); lock.release(); out.close(); } catch (Throwable e) { getLog().error(e); } finally { closeQuietly(out); closeQuietly(reader); closeQuietly(fis); } }
From source file:org.spf4j.perf.tsdb.TimeSeriesDatabase.java
public void flush() throws IOException { synchronized (path) { List<Map.Entry<String, DataFragment>> lwriteDataFragments; synchronized (writeDataFragments) { if (writeDataFragments.isEmpty()) { return; }/* w w w.j av a 2 s . c o m*/ lwriteDataFragments = new ArrayList<>(writeDataFragments.entrySet()); writeDataFragments.clear(); } FileLock lock = ch.lock(); try { for (Map.Entry<String, DataFragment> entry : lwriteDataFragments) { DataFragment writeDataFragment = entry.getValue(); String groupName = entry.getKey(); file.seek(file.length()); writeDataFragment.setLocation(file.getFilePointer()); writeDataFragment.writeTo(file); TSTable colInfo = tables.get(groupName); colInfo = new TSTable(file, colInfo.getLocation()); // reread colInfo tables.put(groupName, colInfo); // update colInfo final long lastDataFragment = colInfo.getLastDataFragment(); final long location = writeDataFragment.getLocation(); if (lastDataFragment != 0) { DataFragment.setNextDataFragment(lastDataFragment, location, file); } else { colInfo.setFirstDataFragment(location, file); } colInfo.setLastDataFragment(location, file); } sync(); } catch (IOException | RuntimeException e) { try { lock.release(); throw e; } catch (IOException ex) { ex.addSuppressed(e); throw ex; } } lock.release(); } }
From source file:org.apache.htrace.impl.HTracedSpanReceiver.java
void appendToDroppedSpansLog(String text) throws IOException { // Is the dropped spans log is disabled? if (conf.droppedSpansLogPath.isEmpty() || (conf.droppedSpansLogMaxSize == 0)) { return;/*w w w. j a va2 s .c om*/ } FileLock lock = null; String msg = ISO_DATE_FORMAT.format(new Date()) + ": " + text; ByteBuffer bb = ByteBuffer.wrap(msg.getBytes(StandardCharsets.UTF_8)); // FileChannel locking corresponds to advisory locking on UNIX. It will // protect multiple processes from attempting to write to the same dropped // spans log at once. However, within a single process, we need this // synchronized block to ensure that multiple HTracedSpanReceiver objects // don't try to write to the same log at once. (It is unusal to configure // multiple HTracedSpanReceiver objects, but possible.) synchronized (HTracedSpanReceiver.class) { FileChannel channel = FileChannel.open(Paths.get(conf.droppedSpansLogPath), APPEND, CREATE, WRITE); try { lock = channel.lock(); long size = channel.size(); if (size > conf.droppedSpansLogMaxSize) { throw new IOException("Dropped spans log " + conf.droppedSpansLogPath + " is already " + size + " bytes; will not add to it."); } else if ((size == 0) && (DROPPED_SPANS_FILE_PERMS != null)) { // Set the permissions of the dropped spans file so that other // processes can write to it. Files.setPosixFilePermissions(Paths.get(conf.droppedSpansLogPath), DROPPED_SPANS_FILE_PERMS); } channel.write(bb); } finally { try { if (lock != null) { lock.release(); } } finally { channel.close(); } } } }
From source file:com.linkedin.helix.store.file.FilePropertyStore.java
@Override public boolean compareAndSet(String key, T expected, T update, Comparator<T> comparator, boolean createIfAbsent) { String path = getPath(key);//from w w w. jav a 2 s. c om File file = new File(path); // FileInputStream fin = null; // FileOutputStream fout = null; RandomAccessFile raFile = null; FileLock fLock = null; try { _readWriteLock.writeLock().lock(); if (createIfAbsent) { file.createNewFile(); } // fin = new FileInputStream(file); // FileChannel fChannel = fin.getChannel(); raFile = new RandomAccessFile(file, "rw"); FileChannel fChannel = raFile.getChannel(); fLock = fChannel.lock(); T current = getProperty(key); if (comparator.compare(current, expected) == 0) { // fout = new FileOutputStream(file); // // byte[] bytes = _serializer.serialize(update); // fout.write(bytes); setProperty(key, update); return true; } return false; } catch (FileNotFoundException e) { logger.error("fail to compareAndSet. path:" + path, e); return false; } catch (Exception e) { logger.error("fail to compareAndSet. path:" + path, e); return false; } finally { _readWriteLock.writeLock().unlock(); try { if (fLock != null && fLock.isValid()) { fLock.release(); } if (raFile != null) { raFile.close(); } // if (fin != null) // { // fin.close(); // } // // if (fout != null) // { // fout.close(); // } } catch (IOException e) { logger.error("fail to close file. path:" + path, e); } } }
From source file:com.socialmarketing.config.ApplicationPrefs.java
/** * Initializes preferences//from w w w . ja v a 2s.c o m * * @param context ServletContext */ public void initializePrefs(ServletContext context) { LOG.info("Initializing..."); // Load the application node name, if any try { Properties instanceProperties = new Properties(); instanceProperties.load(context.getResourceAsStream("/WEB-INF/instance.property")); node = instanceProperties.getProperty("node", DEFAULT_NODE); LOG.info("Node: " + node); } catch (Exception e) { LOG.info("Default Node: " + DEFAULT_NODE); node = DEFAULT_NODE; } // Determine the file library String fileLibrary = retrieveFileLibraryLocation(context); if (fileLibrary != null) { loadProperties(fileLibrary); this.add(FILE_LIBRARY_PATH, fileLibrary); configureDebug(); // verifyKey(context, fileLibrary); // configureConnectionPool(context); // configureFreemarker(context); // configureWebdavManager(context); // configureSystemSettings(context); // configureCache(context); if (isConfigured()) { if (ApplicationVersion.isOutOfDate(this)) { LOG.info("Upgrade triggered... obtaining lock to continue"); // Use a lock file to to start upgrading File upgradeLockFile = new File(fileLibrary + "upgrade.lock"); FileChannel fileChannel = null; FileLock fileLock = null; try { // Configure the file for locking fileChannel = new RandomAccessFile(upgradeLockFile, "rw").getChannel(); // Use fileChannel.lock which blocks until the lock is obtained fileLock = fileChannel.lock(); // Reload the prefs to make sure the upgrade isn't already complete loadProperties(fileLibrary); if (ApplicationVersion.isOutOfDate(this)) { // The application needs an update LOG.info("Installed version " + ApplicationVersion.getInstalledVersion(this) + " will be upgraded to " + ApplicationVersion.VERSION); // performUpgrade(context); } } catch (Exception e) { LOG.error("initializePrefs-> performUpgrade", e); } finally { try { if (fileLock != null) { fileLock.release(); } if (fileChannel != null) { fileChannel.close(); } } catch (Exception eclose) { LOG.error("initializePrefs-> lock", eclose); } } } if (!ApplicationVersion.isOutOfDate(this)) { // Start the services now that everything is ready initializeServices(context); } } } configureDefaultBehavior(context); loadApplicationDictionaries(context); }
From source file:net.ontopia.infoset.content.FileContentStore.java
private void allocateNewBlock() throws ContentStoreException { RandomAccessFile out = null;/*from www .j a v a 2 s . co m*/ boolean exception_thrown = false; try { out = new RandomAccessFile(key_file, "rws"); for (int i = 0; i < MAX_SPINS; i++) { // acquire exclusive lock FileLock l = out.getChannel().tryLock(); if (l == null) { // wait a little before trying again try { Thread.sleep(SPIN_TIMEOUT); } catch (InterruptedException e) { } continue; } else { try { // allocate new key int old_key; int new_key; String content = null; if (out.length() == 0) { old_key = 0; new_key = old_key + KEY_BLOCK_SIZE; } else { try { content = out.readUTF(); old_key = Integer.parseInt(content); new_key = old_key + KEY_BLOCK_SIZE; } catch (NumberFormatException e) { if (content.length() > 100) content = content.substring(0, 100) + "..."; throw new ContentStoreException( "Content store key file corrupted. Contained: '" + content + "'"); } } // truncate key file and write out new key out.seek(0); out.writeUTF(Integer.toString(new_key)); end_of_key_block = new_key; last_key = old_key; return; } finally { // release file lock try { l.release(); } catch (Throwable t) { throw new ContentStoreException("Could not release key file lock.", t); } } } } throw new ContentStoreException("Block allocation timed out."); } catch (ContentStoreException e) { exception_thrown = true; throw e; } catch (Throwable t) { exception_thrown = true; throw new ContentStoreException(t); } finally { if (out != null) { try { out.close(); } catch (IOException e) { if (!exception_thrown) throw new ContentStoreException("Problems occurred when closing content store.", e); } } } }