UNC path error with InsufficientPermissionOnFileException: Permission of type [READ_DIRECTORY] is needed

402 views
Skip to first unread message

Kane

unread,
Nov 23, 2011, 10:50:20 AM11/23/11
to XADisk
I'm trying to use XADisk to write to a UNC path. It fails with a
InsufficientPermissionOnFileException. However, when I try to use
regular java.io.File methods to do the same thing, everything works
fine. I can also browse the UNC path with no trouble from the run
menu. My code and the output/stacktrace is below. I'm running java
1.6.0_026 on Windows 7 64 bit.

***************

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.xadisk.bridge.proxies.interfaces.Session;
import org.xadisk.bridge.proxies.interfaces.XAFileOutputStream;
import org.xadisk.bridge.proxies.interfaces.XAFileSystem;
import org.xadisk.bridge.proxies.interfaces.XAFileSystemProxy;
import org.xadisk.filesystem.exceptions.ClosedStreamException;
import org.xadisk.filesystem.exceptions.FileAlreadyExistsException;
import org.xadisk.filesystem.exceptions.FileNotExistsException;
import org.xadisk.filesystem.exceptions.FileUnderUseException;
import
org.xadisk.filesystem.exceptions.InsufficientPermissionOnFileException;
import org.xadisk.filesystem.exceptions.LockingFailedException;
import
org.xadisk.filesystem.exceptions.NoTransactionAssociatedException;
import
org.xadisk.filesystem.standalone.StandaloneFileSystemConfiguration;

/**
* Example implementation of XADisk with a couple of transactions.
*
* @author kbonnette
*
*/
public class Example {
// needs to be an absolute path
// see http://java.net/jira/browse/XADISK-94
String xadiskSystemDirectory = "C:\\xadisk";
XAFileSystem xafs = null;

/**
* Initializes the XADisk server.
*/
public void setUpXADisk() {

System.out.println("setup start");
StandaloneFileSystemConfiguration configuration = new
StandaloneFileSystemConfiguration(
xadiskSystemDirectory, "id-1");
// the line below resolves some errors that XADisk has with absolute
// paths and relative paths.
// directories are still written, but with java.io.File.mkdir()
instead
// of the XADisk method.
// see http://java.net/jira/browse/XADISK-95
configuration.setSynchronizeDirectoryChanges(false);
xafs = XAFileSystemProxy.bootNativeXAFileSystem(configuration);
try {
xafs.waitForBootup(-1);
System.out.println("setup end");
} catch (InterruptedException e) {
e.printStackTrace();
System.err.println("Unable to boot XADisk, killing process");
System.exit(1);
}
}

/**
* Shuts down the running XADisk server.
*/
public void shutDown() {
System.out.println("shutdown start");
if (xafs != null) {
try {
xafs.shutdown();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
System.out.println("shutdown end");
}

/**
* regular file io with UNC paths
*/
private void example2a() {

System.out.println("Example 2a ---------------------------------");
try {
File directory = new File("\\\\phfileserver\\development\\xadisk");
if (!directory.exists()) {
if (!directory.mkdir()) {
System.err.println("Could not create directory");
return;
}
}

System.out.println("Writing first");
File first = new File(
"\\\\phfileserver\\development\\xadisk\\first.txt");
if (!first.exists()) {
if (!first.createNewFile()) {
System.err.println("Could not create first");
return;
}
}

// populate text file
System.out.println("populating first");
FileOutputStream xos;
xos = new FileOutputStream(first, false);
xos.write("This is my file\nThis is my text\nThis is for writing
\nReading comes next"
.getBytes());
xos.flush();
xos.close();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* Example with UNC paths
*/
public void example2() {
System.out.println("Example 2 ---------------------------------");
Session session;
try {
session = xafs.createSessionForLocalTransaction();

// create directory
System.out.println("Writing Directory");
File directory = new File("\\\\phfileserver\\development\\xadisk");
if (!session.fileExistsAndIsDirectory(directory)) {
session.createFile(directory, true);
}

// create text file
System.out.println("Writing first");
File first = new File(
"\\\\phfileserver\\development\\xadisk\\first.txt");
if (!session.fileExists(first)) {
session.createFile(first, false);
}

// populate text file
System.out.println("populating first");
XAFileOutputStream xos = session.createXAFileOutputStream(first,
false);
xos.write("This is my file\nThis is my text\nThis is for writing
\nReading comes next"
.getBytes());
xos.flush();
xos.close();

System.out.println("precommit");
session.commit();
System.out.println("postcommit");
} catch (NoTransactionAssociatedException e) {
e.printStackTrace();
} catch (FileAlreadyExistsException e) {
e.printStackTrace();
} catch (FileNotExistsException e) {
e.printStackTrace();
} catch (InsufficientPermissionOnFileException e) {
e.printStackTrace();
} catch (LockingFailedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (FileUnderUseException e) {
e.printStackTrace();
} catch (ClosedStreamException e) {
e.printStackTrace();
}
}


/**
* Main method. sets up server, runs local, remote, and both
examples, then
* shuts down server.
*
* @param args
*/
public static void main(String[] args) {
Example example = new Example();
example.setUpXADisk();
example.example2a();
example.example2();
example.shutDown();
}

}
***************************************

setup start
setup end
Example 2a ---------------------------------
Writing first
populating first
Example 2 ---------------------------------
Writing Directory
shutdown start
shutdown end
org.xadisk.filesystem.exceptions.InsufficientPermissionOnFileException:
Permission of type [READ_DIRECTORY] is needed over the file/directory
with path [\\phfileserver\development] for the i/o operation to
succeed.
at
org.xadisk.filesystem.NativeSession.checkPermission(NativeSession.java:
1018)
at
org.xadisk.filesystem.NativeSession.fileExistsAndIsDirectory(NativeSession.java:
438)
at
org.xadisk.filesystem.NativeSession.fileExistsAndIsDirectory(NativeSession.java:
423)
at selected.Example.example2(Example.java:231)
at selected.Example.main(Example.java:349)

Nitin Verma

unread,
Nov 23, 2011, 2:38:19 PM11/23/11
to XADisk
Hi Kane,

I can see the same issue on my machine too (Windows XP 32 bit, Java
1.6.0_19). Some points from my investigation:

1. Behavior of some of the java.io.File APIs are little different in
case of UNC paths than in local paths. For example,
new File("\\\\host1").isDirectory() returns false, while
new File("C:\\").isDirectory() returns true.

Similarly,
new File("\\\\host1").listFiles() returns null.


Though, deeper paths like "\\\\host1\\folder1" are working fine with
these APIs.


2. During the fileExistsAndIsDirectory call, XADisk not only goes one
level up to the immediate ancestor, but goes two levels up (for the
moment, we can skip further internals behind this). As the paths in
your example were like "\\host\a\b", so XADisk landed up on the File
object for "\\host". There, the unexpected File.isDirectory() behavior
(as mentioned above) lead XADisk to believe that the directory "\
\host" does not exist.

3. The error message mentioning permission issue is actually
misleading. The code structure generalizes even the non-existent of an
ancestor directory to the case of "insufficient" permission. (I will
make a note to fix this too.)

4. Your example code runs fine when I replace the path "\\host\a\b"
with "\\host\a\b\\c" (of course, the directory "b" needs to be created
before we run the example). Though, I guess such a constrained
workaround (of having xadisk playground 3 levels below the root
folder) might not work in general.

5. For UNC paths, we will need to do little different handling than
the local paths (mostly around method
TransactionVirtualView:getVirtualViewDirectory). This should be doable
even with Java's behavior mentioned in (1) (look at each shared folder
like "\\host\a" as a separate file-system root instead of thinking "\
\host" to be the root).

I will update here once I have more to share.

Feel free to discuss more.

Thanks,
Nitin

Kane

unread,
Nov 23, 2011, 10:12:33 PM11/23/11
to XADisk
Hi Nitin,

Thanks again for your quick response.

I will try to workaround the "UNC paths not deep enough" issue until a
fix comes in. Would you like me to create a JIRA issue for this?

Thanks,
Kane

Nitin Verma

unread,
Nov 24, 2011, 1:20:46 PM11/24/11
to XADisk
Hi Kane,

I have filed the tracking bug: http://java.net/jira/browse/XADISK-96.

Thanks again for catching this!

Nitin

Kane

unread,
Nov 25, 2011, 10:22:51 AM11/25/11
to XADisk
Hi Nitil,

Sorry for not getting that bug in sooner; I was on holiday with the
family yesterday. I'll be following the issue you raised for me with
interest. Thanks again for your quick response.

Kane

Reply all
Reply to author
Forward
0 new messages