下面列出了怎么用java.nio.channels.OverlappingFileLockException的API类实例代码及写法,或者点击链接到github查看源代码。
@Test(expected = OverlappingFileLockException.class)
public void test_repate_restart() throws Exception {
long totalMsgs = 100;
QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes();
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
messageStoreConfig.setMapedFileSizeCommitLog(1024 * 8);
messageStoreConfig.setMapedFileSizeConsumeQueue(1024 * 4);
messageStoreConfig.setMaxHashSlotNum(100);
messageStoreConfig.setMaxIndexNum(100 * 10);
MessageStore master = new DefaultMessageStore(messageStoreConfig, null, new MyMessageArrivingListener(), new BrokerConfig());
boolean load = master.load();
assertTrue(load);
try {
master.start();
master.start();
} finally {
master.shutdown();
master.destroy();
}
}
@Test(expected = OverlappingFileLockException.class)
public void test_repate_restart() throws Exception {
QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes();
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
messageStoreConfig.setMapedFileSizeCommitLog(1024 * 8);
messageStoreConfig.setMapedFileSizeConsumeQueue(1024 * 4);
messageStoreConfig.setMaxHashSlotNum(100);
messageStoreConfig.setMaxIndexNum(100 * 10);
MessageStore master = new DefaultMessageStore(messageStoreConfig, null, new MyMessageArrivingListener(), new BrokerConfig());
boolean load = master.load();
assertTrue(load);
try {
master.start();
master.start();
} finally {
master.shutdown();
master.destroy();
}
}
/**
* 锁住进程文件
*
* @throws IOException IO
*/
private void lockFile() throws IOException {
this.fileOutputStream = new FileOutputStream(ConfigBean.getInstance().getPidFile(), true);
this.fileChannel = fileOutputStream.getChannel();
while (true) {
try {
lock = fileChannel.lock();
break;
} catch (OverlappingFileLockException | IOException ignored) {
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Test(expected = OverlappingFileLockException.class)
public void test_repate_restart() throws Exception {
QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes();
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
messageStoreConfig.setMapedFileSizeCommitLog(1024 * 8);
messageStoreConfig.setMapedFileSizeConsumeQueue(1024 * 4);
messageStoreConfig.setMaxHashSlotNum(100);
messageStoreConfig.setMaxIndexNum(100 * 10);
MessageStore master = new DefaultMessageStore(messageStoreConfig, null, new MyMessageArrivingListener(), new BrokerConfig());
boolean load = master.load();
assertTrue(load);
try {
master.start();
master.start();
} finally {
master.shutdown();
master.destroy();
}
}
public TailableFile(File file) throws IOException {
this.file = file;
stateFile = new File(file + ".state");
stateFileChannel = FileChannel.open(stateFile.toPath(), CREATE, READ, WRITE);
try {
stateFileLock = stateFileChannel.tryLock();
if (stateFileLock == null) {
throw new IllegalStateException("This file is currently locked by another process: " + stateFile);
}
} catch (OverlappingFileLockException e) {
throw new IllegalStateException("This file is currently locked by this process: " + stateFile, e);
}
Properties state = readState();
if (!state.isEmpty()) {
restoreState(state);
} else {
tryOpenFile();
}
}
@Test(expected = OverlappingFileLockException.class)
public void test_repate_restart() throws Exception {
long totalMsgs = 100;
QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes();
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
messageStoreConfig.setMapedFileSizeCommitLog(1024 * 8);
messageStoreConfig.setMapedFileSizeConsumeQueue(1024 * 4);
messageStoreConfig.setMaxHashSlotNum(100);
messageStoreConfig.setMaxIndexNum(100 * 10);
MessageStore master = new DefaultMessageStore(messageStoreConfig, null, new MyMessageArrivingListener(), new BrokerConfig());
boolean load = master.load();
assertTrue(load);
try {
master.start();
master.start();
} finally {
master.shutdown();
master.destroy();
}
}
public synchronized boolean lock() throws IOException {
raFile = new RandomAccessFile(lockFile, "rw"); //$NON-NLS-1$
try {
/*
* fix for bug http://bugs.sun.com/view_bug.do?bug_id=6628575 and
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=44735#c17
*/
fileLock = raFile.getChannel().tryLock(0, 1, false);
} catch (OverlappingFileLockException e) {
// handle it as null result
fileLock = null;
} finally {
if (fileLock != null)
return true;
raFile.close();
raFile = null;
}
return false;
}
private void removeInvalidLock(File lockDir) {
try {
boolean revokeLock = false;
File lockedFile = new File(lockDir, LOCK_FILE_NAME);
try (RandomAccessFile raf = new RandomAccessFile(lockedFile, "rw")) {
FileLock fileLock = raf.getChannel().tryLock();
if (fileLock != null) {
logger.warn("Removing invalid lock {}", getLockedBy());
fileLock.release();
revokeLock = true;
}
} catch (OverlappingFileLockException exc) {
// lock is still valid
}
if (revokeLock) {
revokeLock();
}
} catch (IOException e) {
logger.warn(e.toString(), e);
}
}
@Test
public void testServerRestartOnException() throws Exception {
RaftProperties properties = new RaftProperties();
final MiniRaftClusterWithGrpc cluster
= MiniRaftClusterWithGrpc.FACTORY.newCluster(1, properties);
cluster.start();
RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
GrpcConfigKeys.Server.setPort(properties, cluster.getLeader().getServerRpc().getInetSocketAddress().getPort());
// Create a raft server proxy with server rpc bound to a different address
// compared to leader. This helps in locking the raft storage directory to
// be used by next raft server proxy instance.
final StateMachine stateMachine = cluster.getLeader().getStateMachine();
ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, properties, null);
// Close the server rpc for leader so that new raft server can be bound to it.
cluster.getLeader().getServerRpc().close();
// Create a raft server proxy with server rpc bound to same address as
// the leader. This step would fail as the raft storage has been locked by
// the raft server proxy created earlier. Raft server proxy should close
// the rpc server on failure.
testFailureCase("start a new server with the same address",
() -> ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, properties, null).start(),
IOException.class, OverlappingFileLockException.class);
// Try to start a raft server rpc at the leader address.
cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId));
}
@Test(expected = OverlappingFileLockException.class)
public void test_repeat_restart() throws Exception {
QUEUE_TOTAL = 1;
MessageBody = StoreMessage.getBytes();
MessageStoreConfig messageStoreConfig = new MessageStoreConfig();
messageStoreConfig.setMappedFileSizeCommitLog(1024 * 8);
messageStoreConfig.setMappedFileSizeConsumeQueue(1024 * 4);
messageStoreConfig.setMaxHashSlotNum(100);
messageStoreConfig.setMaxIndexNum(100 * 10);
MessageStore master = new DefaultMessageStore(messageStoreConfig, null, new MyMessageArrivingListener(), new BrokerConfig());
boolean load = master.load();
assertTrue(load);
try {
master.start();
master.start();
} finally {
master.shutdown();
master.destroy();
}
}
/**
* Locks the file, with a timeout (non-blocking).
* @param timeout_ms timeout duration in milliseconds.
* @throws IOException I/O exception occured.
* @throws InterruptedException current thread interrupted.
* @throws TimeoutException failed to obtain lock.
*/
public void obtain(long timeout_ms)
throws IOException, InterruptedException, TimeoutException
{
Long quit_time = System.currentTimeMillis() + timeout_ms;
if (fileLock != null && fileLock.isValid())
{
// lock has already been obtained.
return;
}
do
{
try
{
fileLock = fileToLock.tryLock();
return;
}
catch (OverlappingFileLockException e)
{
Thread.sleep(1000);
}
} while (System.currentTimeMillis() < quit_time);
throw new TimeoutException();
}
@Test
@SuppressWarnings("try")
public void testPersistentCachesColliding() throws Exception {
File folder = temporaryFolder.newFolder(testName.getMethodName());
try (PersistentCacheManager cm = CacheManagerBuilder.newCacheManagerBuilder()
.with(new CacheManagerPersistenceConfiguration(folder)).build(true)) {
CacheManagerBuilder.newCacheManagerBuilder()
.with(new CacheManagerPersistenceConfiguration(folder))
.build(true)
.close();
Assert.fail("Expected StateTransitionException");
} catch (StateTransitionException e) {
assertThat(e.getCause().getMessage(), containsString("Persistence directory already locked by this process"));
assertThat(e.getCause().getCause(), instanceOf(OverlappingFileLockException.class));
}
}
/**
* Attempts to acquire an exclusive lock on the directory.
*
* @return A lock object representing the newly-acquired lock or
* <code>null</code> if directory is already locked.
* @throws IOException if locking fails.
*/
@SuppressWarnings("resource")
private FileLock tryLock(File dir) throws IOException {
File lockF = new File(dir, FILE_LOCK);
lockF.deleteOnExit();
RandomAccessFile file = new RandomAccessFile(lockF, "rws");
FileLock res = null;
try {
res = file.getChannel().tryLock();
} catch(OverlappingFileLockException oe) {
file.close();
return null;
} catch(IOException e) {
LOGGER.error("Cannot create lock on " + lockF, e);
file.close();
throw e;
}
return res;
}
/**
* Attempts to acquire an exclusive lock on the storage.
*
* @return A lock object representing the newly-acquired lock or
* <code>null</code> if storage is already locked.
* @throws IOException if locking fails.
*/
FileLock tryLock() throws IOException {
File lockF = new File(root, STORAGE_FILE_LOCK);
lockF.deleteOnExit();
RandomAccessFile file = new RandomAccessFile(lockF, "rws");
FileLock res = null;
try {
res = file.getChannel().tryLock();
} catch(OverlappingFileLockException oe) {
file.close();
return null;
} catch(IOException e) {
LOG.error("Cannot create lock on " + lockF, e);
file.close();
throw e;
}
return res;
}
@Test
public void whenTryToLockFile_thenItShouldBeLocked() throws IOException {
final RandomAccessFile stream = new RandomAccessFile(fileName4, "rw");
final FileChannel channel = stream.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
} catch (final OverlappingFileLockException e) {
stream.close();
channel.close();
}
stream.writeChars("test lock");
lock.release();
stream.close();
channel.close();
}
/**
* To prevent 'buck kill' from deleting resources from underneath a 'live' buckd we hold on to the
* FileLock for the entire lifetime of the process. We depend on the fact that on Linux and MacOS
* Java FileLock is implemented using the same mechanism as the Python fcntl.lockf method. Should
* this not be the case we'll simply have a small race between buckd start and `buck kill`.
*/
private static void obtainResourceFileLock() {
if (resourcesFileLock != null) {
return;
}
String resourceLockFilePath = System.getProperties().getProperty("buck.resource_lock_path");
if (resourceLockFilePath == null) {
// Running from ant, no resource lock needed.
return;
}
try {
// R+W+A is equivalent to 'a+' in Python (which is how the lock file is opened in Python)
// because WRITE in Java does not imply truncating the file.
FileChannel fileChannel =
FileChannel.open(
Paths.get(resourceLockFilePath),
StandardOpenOption.READ,
StandardOpenOption.WRITE,
StandardOpenOption.CREATE);
resourcesFileLock = fileChannel.tryLock(0L, Long.MAX_VALUE, true);
} catch (IOException | OverlappingFileLockException e) {
LOG.warn(e, "Error when attempting to acquire resources file lock.");
}
}
private FileLock getLock() throws OverlappingFileLockException, InterruptedException, IOException {
File lockFile = localFs.pathToFile(new Path(lockPath, host + ".lock"));
final boolean created = lockFile.createNewFile();
if (created == false && !lockFile.exists()) {
// bail-out cleanly
return null;
}
// invariant - file created (winner writes to this file)
// caveat: closing lockChannel does close the file (do not double close)
// JDK7 - TODO: use AsynchronousFileChannel instead of RandomAccessFile
FileChannel lockChannel = new RandomAccessFile(lockFile, "rws")
.getChannel();
FileLock xlock = null;
xlock = lockChannel.tryLock(0, Long.MAX_VALUE, false);
if (xlock != null) {
return xlock;
}
lockChannel.close();
return null;
}
/**
* Attempts to acquire an exclusive lock on the storage.
*
* @return A lock object representing the newly-acquired lock or
* <code>null</code> if storage is already locked.
* @throws IOException if locking fails.
*/
FileLock tryLock() throws IOException {
File lockF = new File(root, STORAGE_FILE_LOCK);
lockF.deleteOnExit();
RandomAccessFile file = new RandomAccessFile(lockF, "rws");
FileLock res = null;
try {
res = file.getChannel().tryLock();
} catch(OverlappingFileLockException oe) {
file.close();
return null;
} catch(IOException e) {
LOG.info(StringUtils.stringifyException(e));
file.close();
throw e;
}
return res;
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}
/**
* tries to obtain the lock or throws an exception
*/
public static void tryGetLock() {
try {
f = new File(REFRESH_FILE_LOCKED_PATH);
synchronized (f) {
// create the lock file
channel = new RandomAccessFile(f, "rw").getChannel();
// create it with correct user
FileSystem fileSystem = FileSystems.getDefault();
UserPrincipalLookupService service = fileSystem.getUserPrincipalLookupService();
UserPrincipal rootUser = service.lookupPrincipalByName("root");
UserPrincipal tomcatUser = service.lookupPrincipalByName("tomcat");
if (Files.getOwner(f.toPath(), LinkOption.NOFOLLOW_LINKS).equals(rootUser)) {
Files.setOwner(f.toPath(), tomcatUser);
}
lock = channel.tryLock();
if (lock == null) {
// File is lock by other application
channel.close();
log.warn("SCC refresh is already running.");
throw new OverlappingFileLockException();
}
log.info("Got the Lock for scc refresh");
// Add on exit handler to release lock when application shutdown
OnExitHandler onExitHandler = new OnExitHandler();
Runtime.getRuntime().addShutdownHook(onExitHandler);
}
}
catch (IOException e) {
throw new RuntimeException("Could not start process.", e);
}
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}
@Nullable
private static java.nio.channels.FileLock lock(FileChannel fileChannel) throws IOException {
try {
return fileChannel.tryLock();
}
catch (OverlappingFileLockException ex) {
return null;
}
}
private FileLock tryLock(final FileChannel channel) throws IOException {
try {
return channel.tryLock();
} catch (final OverlappingFileLockException e) {
return null;
}
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}
private static FileLock tryLock(RandomAccessFile raf) throws IOException {
try {
return raf.getChannel().tryLock(333L, 1L, false);
} catch (OverlappingFileLockException ex) {
OUTPUT.log(Level.INFO, "tryLock fails in the same VM", ex);
// happens in CLIHandlerTest as it simulates running multiple
// instances of the application in the same VM
return null;
}
}
/**
* <pre>
* Acquires an exclusive lock on a file
*
* <b>Platform dependencies</b>
*
* - In Windows it works as expected
* - In Linux it depends on the locking mechanism of the system. The file locking types are two - advisory and mandatory:
*
* a) <b>Advisory locking</b> - advisory locking will work, only if the participating process are cooperative.
* Advisory locking sometimes also called as "unenforced" locking.
*
* b) <b>Mandatory locking</b> - mandatory locking doesn’t require cooperation from the participating processes.
* It causes the kernel to check every open, read and write to verify that the calling process isn’t
* violating a lock on the given file. To enable mandatory locking in Linux, you need to enable it on
* a file system level and also on the individual files. The steps to be followed are:
* 1. Mount the file system with "<i>-o mand</i>" option
* 2. For the lock_file, turn on the set-group-ID bit and turn off the group-execute bit, to enable
* mandatory locking on that particular file. (This way has been chosen because when you turn off
* the group-execute bit, set-group-ID has no real meaning to it )
*
* How to do mandatory locking:
* Note: You need to be root to execute the below command
* <i># mount -oremount,mand /</i>
* <i># touch mandatory.txt</i>
* <i># chmod g+s,g-x mandatory.txt</i>
* </pre>
*
* @param fileName file name
*/
@Override
public void lockFile(
String fileName ) {
synchronized (lockedFiles) {
if (lockedFiles.containsKey(fileName)) {
log.warn("File '" + fileName + "' is already locked");
} else {
try {
File fileToLock = new File(fileName);
@SuppressWarnings( "resource" )
//keep lock to the file
FileChannel channel = new RandomAccessFile(fileToLock, "rw").getChannel();
FileLock fileLock = channel.lock();
lockedFiles.put(fileName, fileLock);
} catch (FileNotFoundException fnfe) {
throw new FileSystemOperationException("File '" + fileName + "' is not found", fnfe);
} catch (OverlappingFileLockException ofle) {
throw new FileSystemOperationException("File '" + fileName
+ "' is already locked in the current JVM"
+ ", but not from this class, so we can't unlock it later.",
ofle);
} catch (Exception e) {
throw new FileSystemOperationException("Could not lock file '" + fileName + "'", e);
}
}
}
}
void runTestServerRestartOnException(MiniRaftClusterWithGrpc cluster) throws Exception {
final RaftServerImpl leader = RaftTestUtil.waitForLeader(cluster);
final RaftPeerId leaderId = leader.getId();
final RaftProperties p = getProperties();
GrpcConfigKeys.Server.setPort(p, leader.getServerRpc().getInetSocketAddress().getPort());
// Create a raft server proxy with server rpc bound to a different address
// compared to leader. This helps in locking the raft storage directory to
// be used by next raft server proxy instance.
final StateMachine stateMachine = cluster.getLeader().getStateMachine();
RaftServerConfigKeys.setStorageDir(p, Collections.singletonList(cluster.getStorageDir(leaderId)));
ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, p, null);
// Close the server rpc for leader so that new raft server can be bound to it.
cluster.getLeader().getServerRpc().close();
// Create a raft server proxy with server rpc bound to same address as
// the leader. This step would fail as the raft storage has been locked by
// the raft server proxy created earlier. Raft server proxy should close
// the rpc server on failure.
RaftServerConfigKeys.setStorageDir(p, Collections.singletonList(cluster.getStorageDir(leaderId)));
testFailureCase("start a new server with the same address",
() -> ServerImplUtils.newRaftServer(leaderId, cluster.getGroup(), gid -> stateMachine, p, null).start(),
IOException.class, OverlappingFileLockException.class);
// Try to start a raft server rpc at the leader address.
cluster.getServer(leaderId).getFactory().newRaftServerRpc(cluster.getServer(leaderId));
}
/**
* Attempts to acquire an exclusive lock on the storage.
*
* @return A lock object representing the newly-acquired lock or
* <code>null</code> if storage is already locked.
* @throws IOException if locking fails.
*/
private FileLock tryLock(File lockF) throws IOException {
boolean deletionHookAdded = false;
if (!lockF.exists()) {
lockF.deleteOnExit();
deletionHookAdded = true;
}
RandomAccessFile file = new RandomAccessFile(lockF, "rws");
String jvmName = ManagementFactory.getRuntimeMXBean().getName();
FileLock res;
try {
res = file.getChannel().tryLock();
if (null == res) {
LOG.error("Unable to acquire file lock on path " + lockF.toString());
throw new OverlappingFileLockException();
}
file.write(jvmName.getBytes(StandardCharsets.UTF_8));
LOG.info("Lock on " + lockF + " acquired by nodename " + jvmName);
} catch (OverlappingFileLockException oe) {
// Cannot read from the locked file on Windows.
LOG.error("It appears that another process "
+ "has already locked the storage directory: " + root, oe);
file.close();
throw new IOException("Failed to lock storage " + this.root + ". The directory is already locked", oe);
} catch(IOException e) {
LOG.error("Failed to acquire lock on " + lockF
+ ". If this storage directory is mounted via NFS, "
+ "ensure that the appropriate nfs lock services are running.", e);
file.close();
throw e;
}
if (!deletionHookAdded) {
// If the file existed prior to our startup, we didn't
// call deleteOnExit above. But since we successfully locked
// the dir, we can take care of cleaning it up.
lockF.deleteOnExit();
}
return res;
}
private void checkList(long position, long size)
throws OverlappingFileLockException
{
assert Thread.holdsLock(lockList);
for (FileLock fl: lockList) {
if (fl.overlaps(position, size)) {
throw new OverlappingFileLockException();
}
}
}