Java.nio, FileChannel, FileLock conundrum...
Hey all--
I want to have multiple java machines on multiple clients to access a singe file. I want the first java machine to access it to lock the file so only it can write to the file. Other machines may come in later and read it.
Here's the trouble. If I simply access the file as, say, a RandomAccessFile in "rw" mode. All the clients may read and write to their hearts desire without throwing and exception.
So I found that if I obtain a FileChannel from the RandomAccessFile, I can tryLock(0,Long.MAX_VALUE,true) to obtain a Shared Lock.
Here's the trouble. A client can obtain the lock and prevent others from writing to it successfully while allowing them to read from it...great!. HOWEVER, even though that particular client has the lock, the client can't write to the file either!
myRandomAccessFile.write() methods NOR myRandomAccessFile.getChannel().write(myByteBuffer);NOR
FileLock myFileLock =myRandomAccessFile.getChannel().tryLock(0,Long.MAX_VALUE,true);
FileChannel lockedChannel = myFileLock.channel();
lockedChannel.write(myByteBuffer);all of these throw a java.io.IOException "The process cannot access the file because another process has locked a portion of the file"
I'm only running one process and one virtual machine. I also checked to make sure myFileLock != null and that myFileLock.isValid()==true So does obtaining a filelock also prevent my OWN program from writing to the file?! If so what's the use of a filelock? Because in order to write to the channel upon whose lock I have, I'd have to release the lock which would allow any other clients the ability to write to it concurrently.
Thanks for the help! The documentation seems a bit sparse on this...
I know they say it's platform dependent. But what's weird is that I know native Windows and native Mac apps (the two systems this program will run on) both allow the type of lock I describe. Yet, at least on Java on Windows, this locking system doesn't work.
"FileLock protects against other locks."
So this would be great too! It would at least let me sense when another jvm from a different machine was accessing my file and I, as the programmer, could say if someone else has a lock, my app won't do any writing.
The problem is that the only locks I appear to be able to get are 1) exclusive lock that boots everyone from coming within a Gigabyte of the file... or
2) a shared lock that let's no one write including the locker of the file.
Even if it doesn't let me have a "everybody read, only I write" lock, I wish it let me have a lock that just said, "someone's currently accessing the file besides you"...then I could fill in, "so don't do any writing."
Which brings me to what you said that's kind of exciting "Also be aware that you can lock bytes beyond the end of the file:"
So if I lock a RandomAccessFile only at the byte Long.MAX_VALUE-1, other's would be able to see that lock, even though that aspect of the file on others file systems didn't even exist? Because if so, you've answered my question. That would let me write and read the rest of the file but still have other apps detect whether there was a lock on the file or not.
I suppose I could also just lock the first byte of the file and ask the same question. I'm going to play around with that and see if it works.
Similar Messages
-
Need an example of how to use java.nio.channels.FileLock
Hi,
I need to use the Filelock, but can�t find any examples on how to implement it -
is it still used in Java 5.0?Would this be the correct way to check whether the file is already locked?
public static void main(String[] args) throws Exception {
FileOutputStream fos = new FileOutputStream("data.txt");
FileLock fl = fos.getChannel().tryLock();
if (fl != null) {
System.out.println("Locked File");
Thread.sleep(30000);
fl.release();
System.out.println("Released Lock");
else{
System.out.println("File is already locked!");
fos.close();
} -
Java.nio.FileChannel tryLock() method does not lock!!!
Hello,
I have the following:
RandomAccessFile raf = new RandomAccessFile(file, "rw");
try {
lock = raf.getChannel().tryLock();
} catch (OverlappingFileLockException e) {
System.out.println("File is locked"); // this never gets printed
if (lock != null) {
// successfully acquired a lock
System.out.println("acquired lock!!!"); // this gets printed alright
// check if lock is valid
System.out.println("is this lock valid? "+lock.isValid()); // it always is when I run my app
// do stuff with the file
....Note that I do NOT close the channel, which would make the lock invalid.
Well, as far as I know, the code above tries to acquire an EXCLUSIVE lock (no read or write) on a file. It means that no other java application should be able to access that file, right?
My problem is that I can still open that file with a second instance of my app, regardless of the lock.
What am I missing?
PS: don't know if it's relevant, but I do this right AFTER acquiring the lock:
InputStream stream = Channels.newInputStream(raf.getChannel());
XMLDecoder d = new XMLDecoder(new BufferedInputStream(stream));Thanks for the answer, mlk.
Well, I went through MSDN to find no answer. Anyway, now I noticed tryLock() blocks, and it shouldn't. I ran two instances of my app and the second one keeps waiting till I release the lock created on the first one!!! Here's some code:
try
lock = channel.tryLock();
System.out.println("File not locked");
catch (OverlappingFileLockException e)
// File is already locked in this thread or virtual machine
System.out.println("File locked");
try
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
String str = "";
while (str != null)
System.out.print("> prompt ");
str = in.readLine();
if (str.equalsIgnoreCase("status")) {
System.out.println("lock = "+lock);
} else if (str.equalsIgnoreCase("exit")) break;
...As stated in the API docs, tryLock() should return immediately. Therefore, the 'lock = channel.tryLock();' should either return cleanly or throw an exception. Then, no matter what, 'prompt >' should appear in the console. Except it doesn't for the second instance. Exiting the first instance makes the second one print out 'prompt'. I believe this shows tryLock() was blocking the execution. Am I missing something?
Not being able to use file lock functionality has been annoying me for quite some time now. Urgh!!!!
Has someone used it on Windows with success? Is there another way of doing it (I know one could use native code, but I could not find example) ?
Thanks -
Is java.nio.channels.FileLock thread safe ?
Hello,
I want to lock a file in exclusive mode. The 1.4.2 doc says the followings:
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.
File-lock objects are safe for use by multiple concurrent threads.
I'm confused. If They are not suitable for controlling access to a file by multiple threads within the same virtual machine, How can they be safe for use by multiple concurrent threads ?
thanks in advance...I think it means that you still need to synchronize your threads around the code that obtains the lock and writes data to the file.
-
Java NIO locking and NTFS network resources
Hi all - just ran into a really nasty situation and I was wondering if anyone else has hit it and might have some suggestions.
Platform: JRE 1.4_02 on a Win XP machine
The following test code locks a file, then copies it to another location using NIO.
When I run it with source path on my local drives (C), it works fine. If I run it with source path on a network shared resource, it fails with an IOException with description 'Error performing inpage operation'.
If I disable the lock immediately before the copy operation, it works fine.
My conclusion is that there is something about the NIO locking implementation that prevents it from working properly with NTFS volumes on other hosts. Can this be right? I've found the following bug report:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4774175
but this seems like a huge problem that would prevent folks from using NIO in many, many applications. Maybe I'm wrong on something here...
Anyway, here's the test code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
* Created on May 28, 2004
* (c) 2004 Trumpet, Inc.
* @author kevin
public class test {
private void createFile(File f) throws IOException{
FileOutputStream os = new FileOutputStream(f);
for(int i = 0; i < 10; i++){
os.write(i);
os.close();
public test() {
boolean testWithReleasingLockPriorToCopy = false;
final File f1= new File("w:/temp/test2.lok");
final File f2 = new File("w:/temp/test.lok");
f1.delete();
f2.delete();
try {
createFile(f1);
RandomAccessFile raf1 = new RandomAccessFile(f1, "rw");
RandomAccessFile raf2 = new RandomAccessFile(f1, "rw");
FileChannel ch1 = raf1.getChannel();
FileChannel ch2 = raf2.getChannel();
FileLock flock1 = ch1.lock();
if (!f2.getParentFile().exists() && !f2.getParentFile().mkdirs())
throw new IOException("Unable to create directories for destination file '" + f2 + "'");
if (testWithReleasingLockPriorToCopy)
flock1.release();
ch1.transferTo(0, raf1.length(), ch2);
raf1.close();
raf2.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
public static void main(String[] args) {
test t = new test();
}Does anyone have any pointers here? I need to be able to exclusively lock a file on a network drive (preventing any other applications from opening it), then make a copy of it. I can't use regular stream operations, because the lock prevents them from working properly (it appears that, once you grab a file lock using NIO, the only way your application can use the file is via the NIO operations - using stream operations fails...).
Thanks in advance for any help!
- Kevini've run into the same problem recently, channels working fine for local file locking, but when you turn to the network, they fail to accurately handle locks.
i ended up writing a jni utility to ship with my java application that locks files using native windows calls.
my .c file ends up looking something like this:
JNIEXPORT jint JNICALL Java_Mapper_NativeUtils_LockFile
(JNIEnv *env, jobject obj, jstring filename)
const char* ntvFilename = (*env)->GetStringUTFChars(env, filename, 0);
int retVal = (int)CreateFile
ntvFilename
, GENERIC_WRITE
, FILE_SHARE_READ
, 0
, OPEN_EXISTING
, FILE_FLAG_SEQUENTIAL_SCAN
, 0
//add code to throw java exceptions based on retVal
if (retVal == (int)INVALID_HANDLE_VALUE)
return retVal;
(*env)->ReleaseStringUTFChars(env, filename, ntvFilename);
return retVal;
JNIEXPORT jboolean JNICALL Java_Mapper_NativeUtils_UnlockFile
(JNIEnv *env, jobject obj, jint handle)
CloseHandle((void *)handle);
return 1;
it's a little shy on the error checking side, but it provides support for network file locking that java seems to lack. -
Java.nio.channels.FileChannel jar file
Hi
I have used java.nio.channels.FileChannel package in my program.
where can I get the jar file which has the above package?
Thanxi give here sample code.. use this it will work fine..
import java.nio.*;
import java.nio.channels.*;
import java.io.*;
public class copyImage
public static void main(String [] args) throws IOException
try {
// Create channel on the source
FileChannel srcChannel = new FileInputStream("dragonfly.jpg").getChannel();
FileChannel dstChannel =new FileOutputStream("1.jpg").getChannel();
// Copy file contents from source to destination
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
// Close the channels
srcChannel.close();
dstChannel.close();
} catch (IOException e) {
} -
Java.nio.channels.NonWritableChannelException
i have been facing this exception, please tell me how to remove it
java.nio.channels.NonWritableChannelException
here is my code
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class abc
public static void main(String arg[])
try
File ff=new File("aaa.txt");
FileInputStream fis=new FileInputStream(ff);
FileChannel fc=fis.getChannel();
FileLock lock=fc.lock();
lock.release();
fc.close();
catch(Exception e)
System.out.println("hello22"+e);
}what should i do then to make the channel writable . please tell me what to change in the code, i just want to lock the file and after that i will modify it.
-
Java.nio.channels.Pipe?
Someone explain what java.nio.channels.Pipe should be uses for, and how to use it?
You can use this class to transfer the content of a channel from one thread to another thread.
The writing thread blocks when the pipe is full.
package com.desoft.pipetest;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class PipeTest {
public static void main (String args[])
try
FileInputStream fis = new FileInputStream(args[0]);
FileChannel fc = fis.getChannel();
Pipe p = Pipe.open();
PipeReader pr = new PipeReader( p );
Thread t = new Thread( pr );
t.start();
fc.transferTo(0, fc.size(), p.sink() );
catch( IOException ioe )
ioe.printStackTrace();
* Read from a Pipe and write Content to System.out
static class PipeReader implements Runnable
Pipe p;
public PipeReader( Pipe p )
this.p = p;
public void run()
try
ByteBuffer buffer = ByteBuffer.allocate( 10 );
int len = 0;
while( (len=p.source().read( buffer )) > 0 )
buffer.rewind();
for( int i = 0; i < len; i++ )
System.out.print( (char)buffer.get());
buffer.rewind();
catch( IOException ioe )
ioe.printStackTrace(); -
Performance of java nio with dd in linux.
Hi
I ran this code in java to dump 0s in a file of size 1gb and tried the same with dd in linux.
Java code : I use a preinitialized array (the data) and fill a mappedbytebuffer with it.
package filePersistence.test;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class TimeLineTest {
private static final int BYTE_LENGTH = 1000;
//this is the input
static byte[] b = new byte[BYTE_LENGTH];
public static void main(String[] arg) throws Exception
//initializing the input
for (int i=0;i<BYTE_LENGTH;i++)
b[i] = 0;
File file = new File(arg[0]);
RandomAccessFile raFile = new RandomAccessFile(file,"rw");
FileChannel fChannel = raFile.getChannel();
int loopCount = 1000000;
MappedByteBuffer mbuffer = fChannel.map( FileChannel.MapMode.READ_WRITE ,0,loopCount * BYTE_LENGTH);
//System.out.println(" going to fill in a file" + file.getName());
long k = 0;
long startTime = System.currentTimeMillis();
for (int i=0;i<loopCount;i++)
//populate the mapped buffer
mbuffer.put(b);
//persist into the file
mbuffer.force();
long endTime = System.currentTimeMillis();
System.out.println(" file filled size1 "+file.length());
System.out.println(" time " + (endTime - startTime));
On a linux machine this takes around 7 secs while dd used as
"dd if=/dev/zero of=mytestfile.out bs=1000 count=1000000"
1000000+0 records in
1000000+0 records out
1000000000 bytes (1.0 GB) copied, 4.618 seconds, 217 MB/s
4.6 and 7 differ quite a lot. Is there a way the java code can be improved to match dd ?(-sever does not help)
Thanks
SumantaHi
Can this be called a dd equivalent code ?
package filePersistence.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class TimeLineTest {
private static final int BYTE_LENGTH = 1000;
//this is the input
static byte[] b = new byte[BYTE_LENGTH];
public static void main(String[] arg) throws Exception
//initializing the input
for (int i=0;i<BYTE_LENGTH;i++)
b[i] = 0;
String srcFile = arg[0] + "_src";
FileOutputStream fos = new FileOutputStream(srcFile);
fos.write(b);
fos.getFD().sync();
fos.flush();
fos.close();
RandomAccessFile srcraFile = new RandomAccessFile(srcFile,"rw");
FileChannel srcChannel = srcraFile.getChannel();
File file = new File(arg[0]);
RandomAccessFile raFile = new RandomAccessFile(file,"rw");
FileChannel raChannel = raFile.getChannel();
int loopCount = 1000000;
//MappedByteBuffer mbuffer = fChannel.map( FileChannel.MapMode.READ_WRITE ,0,loopCount * BYTE_LENGTH);
//System.out.println(" going to fill in a file" + file.getName());
long startTime = System.currentTimeMillis();
for (int i=0,position=0;i<loopCount;i++,position+=BYTE_LENGTH)
//populate the mapped buffer
//mbuffer.put(b);
raChannel.position(position);
srcChannel.transferTo(0, BYTE_LENGTH, raChannel);
//persist into the file
//mbuffer.force();
raFile.getFD().sync();
raChannel.close();
raFile.close();
long endTime = System.currentTimeMillis();
System.out.println(" file filled size1 "+file.length());
System.out.println(" time " + (endTime - startTime));
} -
Java.nio package Runtime error java.lang.UnsupportedClassVersionError.
Hi
I am using nio package and create a java program for file locking (FileLocking.java).
Here is the sample
try {
file = new File("C:/acc.txt");
channel = new RandomAccessFile(file, "rw").getChannel();
lock = channel.lock(0, Long.MAX_VALUE, true);
try {
lock = channel.tryLock(0, Long.MAX_VALUE, true);
catch (OverlappingFileLockException e) {
return true;
using wsad 5.1 and jdk1.4 i compiled this program.
While executing i got the following runtime error..
java.lang.UnsupportedClassVersionError: FileLocking (Unsupported major.minor version 48.0)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:703)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:133)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:319)
at java.net.URLClassLoader.access$400(URLClassLoader.java:92)
at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java:677)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:238)
at java.lang.ClassLoader.loadClass(ClassLoader.java:516)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:441)
at java.lang.ClassLoader.loadClass(ClassLoader.java:448)
Exception in thread "main"
Even if i try to recompile it in command prompt and run, i got the same error.
please suggest me how can i overcome this problem.UnsupportedClassVersionError means that you are trying to execute a class for a newer version of the JVM on an older version of the JVM.
Version 48.0 is for Java 1.4, so you have compiled your class with JDK 1.4.
The computer you are trying to run the class on, has an older version of Java than 1.4 - check it!
Try recompiling your source files with the "-target" switch, for example if you're running on Java 1.3, try compiling with:
javac -target 1.3 ... FileLocking.java -
I have copied this, one program from a book that would have to read file of gives to me to you mixed but it does not work, you could me why?
import java.io.FileInputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ReadPrimesMixedData {
public static void main(String[] args) {
File aFile = new File("C:/Beg Java Stuff/primes.txt");
FileInputStream inFile = null;
try {
inFile = new FileInputStream(aFile);
} catch(FileNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
FileChannel inChannel = inFile.getChannel();
try {
ByteBuffer lengthBuf = ByteBuffer.allocate(8);
int strLength = 0; // Stores the string length
ByteBuffer buf = null; // Stores a reference to the second byte buffer
byte[] strChars = null; // Stores a reference to an array to hold the string
while(true) {
if(inChannel.read(lengthBuf) == -1) // Read the string length, if its EOF
break; // exit the loop
lengthBuf.flip();
strLength = (int)lengthBuf.getDouble(); // Extract the length and convert to int
buf = ByteBuffer.allocate(strLength+8); // Buffer for the string & the prime
if(inChannel.read(buf) == -1) { // Read the string & binary prime value
assert false; // Should not get here!
break; // Exit loop on EOF
buf.flip();
strChars = new byte[strLength]; // Create the array for the string
buf.get(strChars); // Extract string & binary prime value
System.out.println("String length: " + strChars.length+ " String: " +
new String(strChars) + " Binary value: " + buf.getLong());
lengthBuf.clear(); // Clear the buffer for the next read
System.out.println("\nEOF reached.");
inFile.close(); // Close the file and the channel
} catch(IOException e) {
e.printStackTrace(System.err);
System.exit(1);
System.exit(0);
This e' the program that writes the file
import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;
public class PrimesToFile2 {
public static void main(String[] args) {
int primesRequired = 100; // Default count
if (args.length > 0) {
try {
primesRequired = Integer.valueOf(args[0]).intValue();
} catch (NumberFormatException e) {
System.out.println("Prime count value invalid. Using default of "
+ primesRequired);
long[] primes = new long[primesRequired]; // Array to store primes
primes[0] = 2; // Seed the first prime
primes[1] = 3; // and the second
// Count of primes found - up to now, which is also the array index
int count = 2;
long number = 5; // Next integer to be tested
outer:
for (; count < primesRequired; number += 2) {
// The maximum divisor we need to try is square root of number
long limit = (long) Math.ceil(Math.sqrt((double) number));
// Divide by all the primes we have up to limit
for (int i = 1; i < count && primes[i] <= limit; i++)
if (number % primes[i] == 0) // Is it an exact divisor?
continue outer; // yes, try the next number
primes[count++] = number; // We got one!
File aFile = new File("C:/Beg Java Stuff/primes.txt");
FileOutputStream outputFile = null;
try {
outputFile = new FileOutputStream(aFile);
} catch (FileNotFoundException e) {
e.printStackTrace(System.err);
System.exit(1);
FileChannel file = outputFile.getChannel();
final int BUFFERSIZE = 100; // Buffer size in bytes
ByteBuffer buf = ByteBuffer.allocate(BUFFERSIZE);
DoubleBuffer doubleBuf = buf.asDoubleBuffer();
buf.position(8);
CharBuffer charBuf = buf.asCharBuffer();
LongBuffer longBuf = null;
String primeStr = null;
for (int i = 0; i < primes.length; i++) {
primeStr = "prime = " + primes; // Create the string
doubleBuf.put(0,(double) primeStr.length());// Store the string length
charBuf.put(primeStr); // Store the string
buf.position(2 * charBuf.position() + 8); // Position for 3rd buffer
longBuf = buf.asLongBuffer(); // Create the buffer
longBuf.put(primes[i]); // Store the binary long value
buf.position(buf.position() + 8); // Set position after last value
buf.flip(); // and flip
try {
file.write(buf); // Write the buffer as before.
} catch (IOException e) {
e.printStackTrace(System.err);
System.exit(1);
buf.clear();
doubleBuf.clear();
charBuf.clear();
try {
System.out.println("File written is " + file.size() + " bytes.");
outputFile.close(); // Close the file and its channel
} catch (IOException e) {
e.printStackTrace(System.err);
System.exit(1);
System.exit(0);
This works correctlyI don't have problems when I compile the program but if I run the program ....I have this
String length: 9 String: prim Binary value: 7277852183226228736
String length: 0 String: Binary value: 162166969980682240
String length: 0 String: Binary value: 7854388801345436928
String length: 0 String: Binary value: 3573983215616
Stjava.lang.IllegalArgumentException
at java.nio.ByteBuffer.allocate(ByteBuffer.java:303)
at ReadPrimesMixedData.main(ReadPrimesMixedData.java:35)
ring length: 0 String: Binary value: 7566167222444367872
String length: 0 String: Binary value: 88089088
String length: 0 String: Binary value: 8214681170873443584
String length: 0 String: Binary value: 1856
String length: 0 String: Binary value: 8070575878335130880
Exception in thread "main" -
File Locking using java.nio package
I am trying to lock a file using FileChannel's lock method on a CIFS file system. My application is on windows and the CIFS is accessed using UNC format ( \\1.2.3.4\blah.. ). I get the following error
java.io.IOException: The network request is not supported
at sun.nio.ch.FileChannelImpl.lock0(Native Method)
at sun.nio.ch.FileChannelImpl.lock(FileChannelImpl.java:750)
at java.nio.channels.FileChannel.lock(FileChannel.java:865)
From the same machine using the same UNC formatm, when I lock the file using windows C API, I can successfull lock.
Anyone has any idea why JVM can not lock even using nio package. Shouldnt it use the same ( or similar ) API under the hood as its clear by the package name java.nio
The C program I am using is
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/locking.h>
#include <share.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main( int argc, char **argv )
int fh,numread;
char buffer[40];
char filename[500];
/* Quit if can't open file or system doesn't
* support sharing.
if ( argc > 1 )
strcpy(filename,argv[1]);
else
strcpy(filename,"locking.c");
fh = sopen(filename , O_RDWR, SHDENYNO, //_SH_DENYRW,
SIREAD | SIWRITE );
if( fh == -1 )
exit( 1 );
/* Lock some bytes and read them. Then unlock. */
if( locking( fh, LKNBLCK, 30L ) != -1 )
printf( "No one can change these bytes while I'm reading them\n" );
numread = _read( fh, buffer, 30 );
printf( "%d bytes read: %.30s\n", numread, buffer );
lseek( fh, 0L, SEEK_SET );
printf( "Press a key to unlock the file.....\n" );
getchar();
locking( fh, LKUNLCK, 30L );
printf( "Now I'm done. Do what you will with them\n" );
else
perror( "Locking failed\n" );
_close( fh );
}It uses LockFile and LockFileEx. Please check in the MSDN documentation the peculiarities of such APIs.
JNIEXPORT jint JNICALL
Java_sun_nio_ch_FileChannelImpl_lock0(JNIEnv *env, jobject this, jobject fdo,
jboolean block, jlong pos, jlong size,
jboolean shared)
jint fd = fdval(env, fdo);
HANDLE h = (HANDLE)_get_osfhandle(fd);
DWORD lowPos = (DWORD)pos;
long highPos = (long)(pos >> 32);
DWORD lowNumBytes = (DWORD)size;
DWORD highNumBytes = (DWORD)(size >> 32);
jint result = 0;
if (onNT) {
DWORD flags = 0;
OVERLAPPED o;
o.hEvent = 0;
o.Offset = lowPos;
o.OffsetHigh = highPos;
if (block == JNI_FALSE) {
flags |= LOCKFILE_FAIL_IMMEDIATELY;
if (shared == JNI_FALSE) {
flags |= LOCKFILE_EXCLUSIVE_LOCK;
result = LockFileEx(h, flags, 0, lowNumBytes, highNumBytes, &o);
if (result == 0) {
int error = GetLastError();
if (error != ERROR_LOCK_VIOLATION) {
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
return sun_nio_ch_FileChannelImpl_NO_LOCK;
if (flags & LOCKFILE_FAIL_IMMEDIATELY) {
return sun_nio_ch_FileChannelImpl_NO_LOCK;
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
return sun_nio_ch_FileChannelImpl_NO_LOCK;
return sun_nio_ch_FileChannelImpl_LOCKED;
} else {
for(;;) {
if (size > 0x7fffffff) {
size = 0x7fffffff;
lowNumBytes = (DWORD)size;
highNumBytes = 0;
result = LockFile(h, lowPos, highPos, lowNumBytes, highNumBytes);
if (result != 0) {
if (shared == JNI_TRUE) {
return sun_nio_ch_FileChannelImpl_RET_EX_LOCK;
} else {
return sun_nio_ch_FileChannelImpl_LOCKED;
} else {
int error = GetLastError();
if (error != ERROR_LOCK_VIOLATION) {
JNU_ThrowIOExceptionWithLastError(env, "Lock failed");
return sun_nio_ch_FileChannelImpl_NO_LOCK;
if (block == JNI_FALSE) {
return sun_nio_ch_FileChannelImpl_NO_LOCK;
Sleep(100);
return sun_nio_ch_FileChannelImpl_NO_LOCK;
} -
Java.nio select() method return 0 in my client application
Hello,
I'm developing a simple chat application who echo messages
But my client application loop because the select() method return 0
This is my code
// SERVER
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class Server {
private int port = 5001;
public void work() {
try {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(port);
serverSocketChannel.socket().bind(isa);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Listing on "+port);
while(selector.select()>0) {
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isAcceptable()) {
ServerSocketChannel keyChannel = (ServerSocketChannel)key.channel();
SocketChannel channel = keyChannel.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ );
} else if (key.isReadable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel );
Help.write(m.toUpperCase(), keyChannel );
} catch (IOException e) {
e.printStackTrace();
public static void main(String[] args) {
Server s = new Server();
s.work();
// CLIENT
package test;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private String host = "localhost";
private int port = 5001;
private SocketChannel socketChannel;
private Selector selector;
public void work() {
try {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(host, port);
socketChannel.connect(isa);
selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ );
while(true) {
selector.select();
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();) {
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isConnectable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
if (keyChannel.isConnectionPending()) {
System.out.println("Connected "+keyChannel.finishConnect());
} else if (key.isReadable()) {
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel);
display(m);
} catch (IOException e) {
e.printStackTrace();
private void display(final String m) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
area.append(m+"\n");
textFieed.setText("");
private void sendMessage(final String m) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Help.write(m, socketChannel);
} catch (IOException e) {
e.printStackTrace();
t.start();
public Client() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(1);
textFieed.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()== KeyEvent.VK_ENTER) {
String m = textFieed.getText();
sendMessage(m);
area.setEditable(false);
getContentPane().add(textFieed, "North");
getContentPane().add(new JScrollPane(area));
setBounds(200, 200, 400, 300);
show();
private String messageToSend;
private JTextArea area = new JTextArea();
JTextField textFieed = new JTextField();
public static void main(String[] args) {
Client s = new Client();
s.work();
// HELPER CLASS
package test;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class Help {
private static Charset charset = Charset.forName("us-ascii");
private static CharsetEncoder enc = charset.newEncoder();
private static CharsetDecoder dec = charset.newDecoder();
private static void log(String m) {
System.out.println(m);
public static String read(SocketChannel channel) throws IOException {
log("*** start READ");
int n;
ByteBuffer buffer = ByteBuffer.allocate(1024);
while((n = channel.read(buffer)) > 0) {
System.out.println(" adding "+n+" bytes");
log(" BUFFER REMPLI : "+buffer);
buffer.flip();
CharBuffer cb = dec.decode(buffer);
log(" CHARBUFFER : "+cb);
String m = cb.toString();
log(" MESSAGE : "+m);
log("*** end READ");
//buffer.clear();
return m;
public static void write(String m, SocketChannel channel) throws IOException {
log("xxx start WRITE");
CharBuffer cb = CharBuffer.wrap(m);
log(" CHARBUFFER : "+cb);
ByteBuffer buffer = enc.encode(cb);
log(" BUFFER ALLOUE REMPLI : "+buffer);
int n;
while(buffer.hasRemaining()) {
n = channel.write(buffer);
System.out.println(" REMAINING : "+buffer.hasRemaining());
log("xxx end WRITE");Here's the fix for that old problem. Change the work method to do the following
- don't register interest in things that can't happen
- when you connect register based on whether the connection is complete or pending.
- add the OP_READ interest once the connection is complete.
This doesn't fix all the other problems this code will have,
eg.
- what happens if a write is incomplete?
- why does my code loop if I add OP_WRITE interest?
- why does my interestOps or register method block?
For code that answers all those questions see my obese post Taming the NIO Circus
Here's the fixed up Client code
// CLIENT
package test
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Client extends JFrame {
private String host = "localhost";
private int port = 5001;
private SocketChannel socketChannel;
private Selector selector;
public void work() {
try {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
InetSocketAddress isa = new InetSocketAddress(host, port);
socketChannel.connect(isa);
selector = Selector.open();
int interest = 0;
if(socketChannel.isConnected())interest = SelectionKey.OP_READ;
else if(socketChannel.isConnectionPending())interest = SelectionKey.OP_CONNECT;
socketChannel.register(selector, interest);
while(true)
int nn = selector.select();
System.out.println("nn="+nn);
Set keys = selector.selectedKeys();
for(Iterator i = keys.iterator(); i.hasNext();)
SelectionKey key = (SelectionKey) i.next();
i.remove();
if (key.isConnectable())
SocketChannel keyChannel = (SocketChannel) key.channel();
System.out.println("Connected "+keyChannel.finishConnect());
key.interestOps(SelectionKey.OP_READ);
if (key.isReadable())
SocketChannel keyChannel = (SocketChannel) key.channel();
String m = Help.read(keyChannel);
display(m);
} catch (IOException e) {
e.printStackTrace();
private void display(final String m) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
area.append(m+"\n");
textFieed.setText("");
private void sendMessage(final String m) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
Help.write(m, socketChannel);
} catch (IOException e) {
e.printStackTrace();
t.start();
public Client() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(1);
textFieed.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()== KeyEvent.VK_ENTER) {
String m = textFieed.getText();
sendMessage(m);
area.setEditable(false);
getContentPane().add(textFieed, "North");
getContentPane().add(new JScrollPane(area));
setBounds(200, 200, 400, 300);
show();
private String messageToSend;
private JTextArea area = new JTextArea();
JTextField textFieed = new JTextField();
public static void main(String[] args) {
Client s = new Client();
s.work(); -
Problematic frame: # J java.nio.MappedByteBuffer.load()
Helo all...
I'm getting an error when generating a PDF using BIRT Framework in Eclipse. Nothing fancy, just compiling a simple report to pdf.
The problem is, the JVM crashes with the following error:
# A fatal error has been detected by the Java Runtime Environment:
# EXCEPTION_IN_PAGE_ERROR (0xc0000006) at pc=0x0190f0be, pid=5848, tid=2392
# JRE version: 7.0_09-b05
# Java VM: Java HotSpot(TM) Client VM (23.5-b02 mixed mode, sharing windows-x86 )
**# Problematic frame:
# J java.nio.MappedByteBuffer.load()Ljava/nio/MappedByteBuffer;**
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
# An error report file with more information is saved as:
# C:\Users\luis\Desktop\teste\birt\hs_err_pid5848.log
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
I already tried:
1. Run the program in another computers - it worked
2. Reinstall Java on the computer - It did nothing
3. I check the integrity of the disk C: - Nothing
I already spent two days trying to fix this and I don't have any progress. I can't find a solution on the web either.
Thanks in advanceThanks for the help.
But it can not be related to BIRT because it works in every other computer that I tried so far. There is only one computer that not works properly.
If it were BIRT's fault, it wouldn't work in any computer.
Thanks again -
Converting from CP1252 (Windows) to ISO 8859-1 doesn't work with java.nio?
Hi
I'm trying to write some code that checks whether an InputStream contains only characters with a given encoding. I'm using java.nio for that. For tests, I downloaded some character set examples from http://www.columbia.edu/kermit/csettables.html
When creating the CharsetDecoder, I want to get all errors:
Charset charset = Charset.forName( encoding );
CharsetDecoder decoder = charset.newDecoder();
decoder.onMalformedInput( CodingErrorAction.REPORT );
decoder.onUnmappableCharacter( CodingErrorAction.REPORT );I then read an InputStream and try to convert it. If that fails, it can't contain the desired encoding:
boolean isWellEncoded = true;
ByteBuffer inBuffer = ByteBuffer.allocate( 1024 );
ReadableByteChannel channel = Channels.newChannel( inputStream );
while ( channel.read( inBuffer ) != -1 )
CharBuffer decoded = null;
try
inBuffer.flip();
decoded = decoder.decode( inBuffer );
catch ( MalformedInputException ex )
isWellEncoded = false;
catch ( UnmappableCharacterException ex )
isWellEncoded = false;
catch ( CharacterCodingException ex )
isWellEncoded = false;
if ( decoded != null )
LOG.debug( decoded.toString() );
if ( !isWellEncoded )
break;
inBuffer.compact();
channel.close();
return isWellEncoded;Now I want to check whether a file containing Windows 1252 characters is ISO-8859-1. From my point of view, the code above should fail when it gets to the Euro symbol (decimal 128), since that's not defined in ISO-8859-1.
But all I get is a ? character instead:
(}) 125 07/13 175 7D RIGHT CURLY BRACKET, RIGHT BRACE
(~) 126 07/14 176 7E TILDE
[?] 128 08/00 200 80 EURO SYMBOL
[?] 130 08/02 202 82 LOW 9 SINGLE QUOTEI also tried to replace the faulty character, using
decoder.onUnmappableCharacter( CodingErrorAction.REPLACE );
decoder.replaceWith("!");but I still get the question marks.
I'm probably doing something fundamentally wrong, but I dont get it :-)
Any help is greatly appreciated!
EricAs a suggestion....create a complete example demonstrating the problem. It shouldn't have channel in it since that wouldn't appear to be the problem (decoding is.) You should create the byte array in the example code - populate it with the byte sequence that you think should work. And your code should then demonstrate that it doesn't. Then post that.
Maybe you are looking for
-
HP Photosmart e-ALL-IN-ONE C310 printer stuck on "initializing"
It seems like this "initializing" problem is common with this printer. Has anyone received better help or direction from HP, other than unplugging and plugging in the printer? The only other advice I received was to trade in my printer for another mo
-
Printing files on the application server
Hi, I am looking for ways to print files residing on the application server. Do you know of any function modules/transaction code that can do this? Here is my situation: I am using GRAPH_PRINT_POSTSCRIPT_FILE to print postscript file to the printer.
-
Can i open and edit a powerpoint doc in keynote?
can i open and edit a powerpoint doc in keynote?
-
How to create variant for HIER reports
Hello, I have to run program RKDBAT02(Background Processing for Drilldown Reports) from a FM that i created. i have to run this program with a variant that i need to update with the values from my FM. My problem is tha I am trying to use the regular
-
Dreamweaver not creating a directory within my site
When creating a spry asset (in this case a menu bar) it doesn't automatically set up a 'SpryAssets' folder within my root folder. I have gone to manage sites>edit>advanced settings and put in the desired location of the folder; however it doesn't cre