File Locking Question

A

alejandrina

Hi,

I am trying to use Java's FileLock class to synchronize writing to a
file **across machines**. The file resides on a file server. Under
Windows, it works perfectly (ie, only one machine at a time can gain
access, the others wait,no clobbered file, everything is written in
order). Under Linux (same code) the file gets clobbered. No exceptions
are thrown.

Can anyone offer suggestions??


Here is the critical code segment:

//lock the file and wait till we can
FileChannel channel = fos.getChannel();
FileLock lock = null;
try {
while ((lock = channel.tryLock()) == null) {
System.out.println (Utils.getHostname() + " Failed lock...wait");
Thread.sleep(100);
}

System.out.println (Utils.getHostname() + " Locked:" + lock);
System.out.println (Utils.getHostname() + " Lock type is "+
((lock.isShared())?"shared":"exclusive"));

System.out.println (Utils.getHostname() + " Is lock valid: " +
lock.isValid());

//write the title first if noone's done it
//and they asked for one
if (channel.size() <= 0 && bbTitle != null)
channel.write (bbTitle);
channel.write(bb);

} catch (Exception e) {
throw (e);
} finally {
if (lock != null) {
System.out.println (Utils.getHostname() + " Releasing lock");
lock.release();
}
}
 
R

Roedy Green

I am trying to use Java's FileLock class to synchronize writing to a
file **across machines**. The file resides on a file server. Under
Windows, it works perfectly (ie, only one machine at a time can gain
access, the others wait,no clobbered file, everything is written in
order). Under Linux (same code) the file gets clobbered. No exceptions
are thrown.

Can anyone offer suggestions??

FileLock works only within a single JVM. You can use the indicator
file method described at http://mindprod.com/jgloss/lockedfiles.html
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Roedy said:
FileLock works only within a single JVM. You can use the indicator
file method described at http://mindprod.com/jgloss/lockedfiles.html

Which says:

#Starting with Java 1.4, there is the java.nio.channels. FileLock class.
#The locking is confined to a single JVM. Non-Java apps or Java running
#in other JVMs won't see it.

But some people may prefer to believe what the Java Doc says:

#Platform dependencies
#
#This file-locking API is intended to map directly to the native
#locking facility of the underlying operating system. Thus the locks
#held on a file should be visible to all programs that have access to
#the file, regardless of the language in which those programs are
#written.
#
#Whether or not a lock actually prevents another program from
#accessing the content of the locked region is system-dependent and
#therefore unspecified. The native file-locking facilities of some
#systems are merely advisory, meaning that programs must cooperatively
#observe a known locking protocol in order to guarantee data integrity.
#On other systems native file locks are mandatory, meaning that if one
#program locks a region of a file then other programs are actually
#prevented from accessing that region in a way that would violate the
#lock. On yet other systems, whether native file locks are advisory or
#mandatory is configurable on a per-file basis. To ensure consistent and
#correct behavior across platforms, it is strongly recommended that the
#locks provided by this API be used as if they were advisory locks.

Arne
 
L

Lew

Arne said:
#Whether or not a lock actually prevents another program from
#accessing the content of the locked region is system-dependent and
#therefore unspecified. The native file-locking facilities of some
#systems are merely advisory, meaning that programs must cooperatively
#observe a known locking protocol in order to guarantee data integrity.
#On other systems native file locks are mandatory, meaning that if one
#program locks a region of a file then other programs are actually
#prevented from accessing that region in a way that would violate the
#lock. On yet other systems, whether native file locks are advisory or
#mandatory is configurable on a per-file basis. To ensure consistent and
#correct behavior across platforms, it is strongly recommended that the
#locks provided by this API be used as if they were advisory locks.

Hey, that's the exact same quote that Oliver Wong cited when he answered the
OP's OP!

Oliver Wong a dit:
 
G

Guest

Lew said:
Hey, that's the exact same quote that Oliver Wong cited when he answered
the OP's OP!

No surprise in that.

I guess Oliver believe in the Java Doc too.

Arne
 
R

Roedy Green

But some people may prefer to believe what the Java Doc says:

#Platform dependencies

In other words you can't rely on it. When it works is not documented
and not guaranteed to continue working.

In other words, when it does work it is merely a curiosity. For all
practical purposes the lock is confined to single JVM. If it works
outside it is a lucky accident.
 
R

Roedy Green

#Starting with Java 1.4, there is the java.nio.channels. FileLock class.
#The locking is confined to a single JVM. Non-Java apps or Java running
#in other JVMs won't see it.

But some people may prefer to believe what the Java Doc says:

My job is to digest the lawyerly hedging and turn it into simple rules
of thumb. I point you to the original docs if you want to quibble.
 
E

Esmond Pitt

Roedy said:
FileLock works only within a single JVM.

On the contrary, it *doesn't* work within a single JVM: 'File locks are
held on behalf of the entire Java virtual machine. They are not suitable
for controlling access to a file by multiple threads within the same
virtual machine.' Further, 'This file-locking API is intended to map
directly to the native locking facility of the underlying operating
system. Thus the locks held on a file should be visible to all programs
that have access to the file, regardless of the language in which those
programs are written.'

The OP's problem seems to be that network file locking isn't working.
It's an optional part of NFS which is frequently omitted.
 
R

Roedy Green

On the contrary, it *doesn't* work within a single JVM: 'File locks are
held on behalf of the entire Java virtual machine. They are not suitable
for controlling access to a file by multiple threads within the same
virtual machine.'

I had to read that several times before it made sense. Just what good
ARE these fool things then?
 
E

Esmond Pitt

Roedy said:
I had to read that several times before it made sense. Just what good
ARE these fool things then?

They work where the platform works. They work on Windows, including over
an SMB network. They work where Unix advisory locking works, which
apparently generally *doesn't* include NFS.
 
A

alejandrina

I had to read that several times before it made sense. Just what good
ARE these fool things then?


We ran the above code on a multi-processor Linux box, to great
success. It says to me it does work on multiple JVMs, and it's
probably what it's designed for.
 
A

alejandrina

No surprise in that.

I guess Oliver believe in the Java Doc too.

Arne

I'll try to summarize what we know so far:

(a) FileLock seems to work across JVMs within a single client, but not
within a single JVM.
(b) "Across JVMs" in my problem means "across clients". The code I
posted
works in Windows (I think because the Windows file system can
enforce a file lock request) and also in Unix "where Unix advisory
locking works, which
apparently generally *doesn't* include NFS" .

We'll do some admin work on the Linux server and report back.

Thanks all!
 
M

Mark Thornton

Roedy said:
FileLock works only within a single JVM. You can use the indicator
file method described at http://mindprod.com/jgloss/lockedfiles.html

The JavaDoc has this to say about using createNewFile to implement locking:

"Note: this method should not be used for file-locking, as the resulting
protocol cannot be made to work reliably. The FileLock facility should
be used instead."

The indicator file mechanisms popular on Unix can't be made to work
reliably on Windows.

Mark Thornton
 
N

Nigel Wade

alejandrina said:
I'll try to summarize what we know so far:

(a) FileLock seems to work across JVMs within a single client, but not
within a single JVM.
(b) "Across JVMs" in my problem means "across clients". The code I
posted
works in Windows (I think because the Windows file system can
enforce a file lock request) and also in Unix "where Unix advisory
locking works, which
apparently generally *doesn't* include NFS" .

We'll do some admin work on the Linux server and report back.

Thanks all!

This is purely a suggestion for you to research, it's not something I've ever
done myself. I have no idea if it will work any better or reliably than NFS
locking.

How about using SMB/Samba rather than NFS to export/mount your filesystems?
Cursory reading suggests that Samba supports the same file locking mechanisms
which Windows does.
http://samba.org/samba/docs/man/Samba-HOWTO-Collection/locking.html
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Roedy said:
In other words you can't rely on it. When it works is not documented
and not guaranteed to continue working.

In other words, when it does work it is merely a curiosity. For all
practical purposes the lock is confined to single JVM. If it works
outside it is a lucky accident.

No.

It is implementation specific not undefined. Those are not the
same.

You are free to never write anything platform dependent in Java,
but assuming that nobody does is rather ignorant.

Arne
 
A

alejandrina

Hi,

I am trying to use Java's FileLock class to synchronize writing to a
file **across machines**. The file resides on a file server. Under
Windows, it works perfectly (ie, only one machine at a time can gain
access, the others wait,no clobbered file, everything is written in
order). Under Linux (same code) the file gets clobbered. No exceptions
are thrown.

Can anyone offer suggestions??

Here is the critical code segment:

//lock the file and wait till we can
FileChannel channel = fos.getChannel();
FileLock lock = null;
try {
while ((lock = channel.tryLock()) == null) {
System.out.println (Utils.getHostname() + " Failed lock...wait");
Thread.sleep(100);
}

System.out.println (Utils.getHostname() + " Locked:" + lock);
System.out.println (Utils.getHostname() + " Lock type is "+
((lock.isShared())?"shared":"exclusive"));

System.out.println (Utils.getHostname() + " Is lock valid: " +
lock.isValid());

//write the title first if noone's done it
//and they asked for one
if (channel.size() <= 0 && bbTitle != null)
channel.write (bbTitle);
channel.write(bb);

} catch (Exception e) {
throw (e);
} finally {
if (lock != null) {
System.out.println (Utils.getHostname() + " Releasing lock");
lock.release();
}
}


I found out we were using Samba on these computers. When we took that
away, file locking worked perfectly under NFS.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top