views:

421

answers:

5

Sometime this weekend one of our databases (11.1.0.7) began having problems accessing certain folders on a portion of the network through Java. I have reproduced the problem using a small portion of java that does nothing but create a file object and attempt to delete the file. From the database this works for deleting local files and deleting network files on our \zion\dp\ share, but not from our \zion\it\ share.

We have another database that runs under the same domain users account that has no problems deleting files from this location. Also logged in as the same domain user on the server having problems I can run the java outside of Oracle and have no problems deleting files. The domain user has full control over the folder and logged in as the user I can create, modify, and delete files.

If I haven't granted my oracle database user the appropriate dbms_java permissions I get the appropriate java.security.AccessControlException error. After I grant the permission the java runs to completion, the delete command returns false (nothing deleted) and the file is not deleted.

I opened a case with Oracle, but it looks like they aren't going to help any more because it involves file commands being run from the java layer even though it is only reproducible from the Oracle environment.

Test Code:

import java.io.*;               
import java.sql.*;                 
import java.util.*;             

public class Ajclass
{
   public static void ajprocedure(String pdfFileName) throws Exception
   {
      boolean result;
      try {
         System.out.println("Start!");

         File file = new File(pdfFileName);
         //result = file.delete();
         result = file.exists();
         if (result == true) 
           System.out.println("xxFile deleted.");
         else
           System.out.println("xxFile NOT deleted!");
         System.out.println("End!");
      } catch ( Exception e ) {
         throw(e);
      }         
   }
}

Other code I recently found to be failing only against this share and only when run from inside this database:

import java.io.*;
import java.sql.*;

public class DirectoryListing
{
public static void getList(String directory) throws SQLException
   {
      File path = new File( directory );
      String[] list = path.list();
      String element;
      int CurrentFile;

      for(CurrentFile = 0; CurrentFile < list.length; CurrentFile++)
      {
        element = list[CurrentFile];
        #sql { INSERT INTO DIRECTORYLISTING (FILENAME) VALUES (:element) };
      }
   }
}
A: 

Commands run against the OS from inside the database run as the oracle account. So you need to grant read and write on \zion\it\ at the OS level to oracle as well as granting the Java permissions within the database.

Is deleting files what you actually want to do? Or is it just a test? Because we can delete files using the PL/SQL procedure UTL_FILE.FREMOVE().

APC
You are correct, and we have done so. The database service runs under a domain account that has full control on all network locations involved. Logged into the database server as that user I can do any file operations to the network locations and the java code running on the server under the domain account (but ouside of Oracle) also works fine. It is only from java run inside the database that has the problem.
Leigh Riffel
So what distinguishes your \zion\dp\ share from your \zion\it\ share? Alternatively, what happened over the weekend?
APC
+1 Good question. I've been trying to figure that out myself. I haven't been able to find anything that happened or anything that changed.
Leigh Riffel
A: 

If you have oracle admin permissions, Check your remote server (other domain server) host name and Port is available under Oracle Listeners list ?? (using Oracle Netmanager) and also check listener.ora file..

Red
I do have Oracle Admin permissions, but I don't see why I would even need a listener for the other machine.
Leigh Riffel
A: 

"but create a file object and attempt to delete the file" Can you determine if the delete fails because a) It can't find the file Something odd in the file name b) The file is locked / open by another process Might there be something looking at that share (replication, backup, virus scan) c) Insufficient permission

What are the underlying file systems ?

Gary
The file systems are all NTFS on Windows boxes. The file names are x.txt and y.txt in my testing. The files are created by the same domain user the oracle service is logged in as. I think we can rule out odd names and file locking because another Oracle server can delete the same files and java outside of Oracle. Permissions could be a problem, but the same domain user is being used, so that just leaves Oracle permissions. The same grants exist, so I'm not sure what other permissions to look at.
Leigh Riffel
Does the code just try a delete or does it check the file exists and is writable ? (like the code at http://www.java2s.com/Code/Java/File-Input-Output/DeletefileusingJavaIOAPI.htm )If it doesn't raise an Oracle exception, I can't see it being an Oracle permissions issue.Maybe some weird optimization which doesn't necessarily create the file immediately
Gary
The code just does a delete. I did the exists check separately in place of the delete. I create the file myself in advance of running the applilcation. I create it as the domain user the database service uses.
Leigh Riffel
A: 

How about posting the entire code chunk. Another forum suggests that you might not be able to use the same filehandle. "But I'd be willing to bet that you are trying to delete the file based on the variable 'handle' of the FileOutputStream. If that's the case, you can't; you need to create a File Object using the name of the file used when creating the FileOutputStream, and then delete() that."

The fact that it works in some cases might be 'luck' rather than documented behavior.

PS. using the delete method of a path rather than file looks like a failure will be more informative.

Gary
I don't use a FileOutputStream at all. Lucky that it has worked for the past 10 years and still works from other databases and still works on this database against other shared even on the same server? Not my definition of luck.Your suggestion to post the code is good though.
Leigh Riffel
Perhaps luck wasn't the right choice of words. More an undocumented, unexpected, unsupported side-effect that has ceased to be valid, perhaps due to a patch being applied. That said, the code looks pretty definite. Look for Filemon from microsoft and run it on the Windows box. Maybe there's an AV checker or indexing service that locks the file for a time.
Gary
+1 Good idea. I don't think anything could be locking a file I created every time I try the application, but succeed when I run java outside of Oracle, but it can't hurt to check.
Leigh Riffel
A: 

Oracle support suggested restarting the server after looking at the results of Process Monitor being run on the oracle executable while the delete/exist operation was taking place. They found that the action gets a result of STATUS_USER_SESSION_DELETED (0xC0000203) from the remote server, which means the communication between the local and remote server are not working correctly on a windows level. We plan to restart this weekend to see if that fixes the problem.

Leigh Riffel
A restart of the box solved the problem. If I had a bigger maintenance window I would have tried just restarting the database, but a full restart was necessary for unrelated reasons, so I didn't take the time to test that potential solution.
Leigh Riffel