Name: dk106046 Date: 03/23/2004
This occurs on all Java verions.
The program below tries to open a FileWriter object for a file which is mounted on a linux machine using Samba mount.
//To demonstrate that JVM doesn't throw an IOException for Samba mounted drives on Linux platforms.
import java.io.*;
import java.nio.channels.*;
public class canWrite {
public static void main(String[] args) {
if (args.length != 0)
{
for (int i=0; i<args.length; i++)
{
boolean isWritable = true;
System.out.println("Testing: "+args[i]);
File file = new File(args[i]);
if (file != null && file.exists())
{
//canWrite checks for read only
isWritable = file.canWrite() && file.getAbsoluteFile().getParentFile().canWrite();
//need to use FileWriter for files on network shares we don't
//have write access to.
isWritable = true;
if (isWritable)
{
FileWriter writer = null;
try
{
System.out.println("Instantiating FileWriter...");
writer = new FileWriter(file, true); // this should fail
System.out.println("writing...");
writer.write("test", 0,4); // this definitely should fail
System.out.println("flushing...");
//writer.flush(); // this does fail
}
catch (IOException fnfe)
{
isWritable = false;
System.out.println("Exception creating or writing FileWriter: "+fnfe);
fnfe.printStackTrace();
}catch (Exception eee) {
eee.printStackTrace();
}
/*
// Uncommenting this piece of code also exhibits an exception while closing.
if (writer != null)
{
try
{
writer.close();
}
catch (IOException ioe)
{
System.out.println("Exception closing...");
//ioe.printStackTrace();
}
}*/
}
else
{
System.out.println("file.canWrite="+file.canWrite()+", parent.canWrite="+file.getAbsoluteFile().getParentFile().canWrite());
}
}
else
{
System.out.println(args[i]+" is null or does not exist.");
}
if (isWritable)
{
System.out.println("File can be written.");
}
}
}
else
{
System.out.println("Specify at least one file name.");
}
}
}
The mounted device is read only and hence ideally we expect an IOException either while creating the FileWriter or while writing into the file. Such an exception is never thrown.
If we uncomment the "flush" or the "close" calls to the FileWriter object an exception is thrown. These IOExceptions are either while closing the FileWriter or while flushing the same. If a programmer doesn't flush or close the file writer object there are no exceptions thrown.
The behavior should be such that an IO exception is thrown while we attempt to write the bytes to this read only file.
Steps to reproduce.
1. On a windows machine share a drive ( say d: as ntDrive ) after making the drive read-only.
2. Mount this drive on a linux machine using Samba. ( Ex : mount -t smbfs -o username=administrator //windowsMac/ntDrive /mnt/temp_win )
3. Compile and execute the canWrite.java as "java canWrite /mnt/temp_win/dev_win.txt. Note that dev_win.txt is read-only file.
4. Even though the file is not writable the output of the program would be "File can be written". This is wrong and an IOException should have been thrown.
Here is a sample output.
[root@lolo fileIO]# /workarea/builds/jdk1.4.2/bin/java canWrite /mnt/temp_win/dev_win.txt
Testing: /mnt/temp_win/dev_win.txt
Instantiating FileWriter...
writing...
flushing...
File can be written.
5. Uncomment the writer.flush() call on line number 34 and re-run the tests. This throws an IOException while flushing the file.
Additional Info:
If the same kind of setup is reversed for windows and linux, i.e., a read only directory from a linux machine is mapped on a windows machine the exception is thrown while creating the FileWriter Object.
======================================================================
This occurs on all Java verions.
The program below tries to open a FileWriter object for a file which is mounted on a linux machine using Samba mount.
//To demonstrate that JVM doesn't throw an IOException for Samba mounted drives on Linux platforms.
import java.io.*;
import java.nio.channels.*;
public class canWrite {
public static void main(String[] args) {
if (args.length != 0)
{
for (int i=0; i<args.length; i++)
{
boolean isWritable = true;
System.out.println("Testing: "+args[i]);
File file = new File(args[i]);
if (file != null && file.exists())
{
//canWrite checks for read only
isWritable = file.canWrite() && file.getAbsoluteFile().getParentFile().canWrite();
//need to use FileWriter for files on network shares we don't
//have write access to.
isWritable = true;
if (isWritable)
{
FileWriter writer = null;
try
{
System.out.println("Instantiating FileWriter...");
writer = new FileWriter(file, true); // this should fail
System.out.println("writing...");
writer.write("test", 0,4); // this definitely should fail
System.out.println("flushing...");
//writer.flush(); // this does fail
}
catch (IOException fnfe)
{
isWritable = false;
System.out.println("Exception creating or writing FileWriter: "+fnfe);
fnfe.printStackTrace();
}catch (Exception eee) {
eee.printStackTrace();
}
/*
// Uncommenting this piece of code also exhibits an exception while closing.
if (writer != null)
{
try
{
writer.close();
}
catch (IOException ioe)
{
System.out.println("Exception closing...");
//ioe.printStackTrace();
}
}*/
}
else
{
System.out.println("file.canWrite="+file.canWrite()+", parent.canWrite="+file.getAbsoluteFile().getParentFile().canWrite());
}
}
else
{
System.out.println(args[i]+" is null or does not exist.");
}
if (isWritable)
{
System.out.println("File can be written.");
}
}
}
else
{
System.out.println("Specify at least one file name.");
}
}
}
The mounted device is read only and hence ideally we expect an IOException either while creating the FileWriter or while writing into the file. Such an exception is never thrown.
If we uncomment the "flush" or the "close" calls to the FileWriter object an exception is thrown. These IOExceptions are either while closing the FileWriter or while flushing the same. If a programmer doesn't flush or close the file writer object there are no exceptions thrown.
The behavior should be such that an IO exception is thrown while we attempt to write the bytes to this read only file.
Steps to reproduce.
1. On a windows machine share a drive ( say d: as ntDrive ) after making the drive read-only.
2. Mount this drive on a linux machine using Samba. ( Ex : mount -t smbfs -o username=administrator //windowsMac/ntDrive /mnt/temp_win )
3. Compile and execute the canWrite.java as "java canWrite /mnt/temp_win/dev_win.txt. Note that dev_win.txt is read-only file.
4. Even though the file is not writable the output of the program would be "File can be written". This is wrong and an IOException should have been thrown.
Here is a sample output.
[root@lolo fileIO]# /workarea/builds/jdk1.4.2/bin/java canWrite /mnt/temp_win/dev_win.txt
Testing: /mnt/temp_win/dev_win.txt
Instantiating FileWriter...
writing...
flushing...
File can be written.
5. Uncomment the writer.flush() call on line number 34 and re-run the tests. This throws an IOException while flushing the file.
Additional Info:
If the same kind of setup is reversed for windows and linux, i.e., a read only directory from a linux machine is mapped on a windows machine the exception is thrown while creating the FileWriter Object.
======================================================================