views:

183

answers:

3

While debugging slow startup of an Eclipse RCP app on a Citrix server, I came to find out that java.io.createTempFile(String,String,File) is taking 5 seconds. It does this only on the first execution and only for certain user accounts. Specifically, I am noticing it Citrix anonymous user accounts. I have not tried many other types of accounts, but this behavior is not exhibited with an administrator account.

Also, it does not matter if the user has access to write to the given directory or not. If the user does not have access, the call will take 5 seconds to fail. If they do have access, the call with take 5 seconds to succeed.

This is on a Windows 2003 Server. I've tried Sun's 1.6.0_16 and 1.6.0_19 JREs and see the same behavior.

I googled a bit expecting this to be some sort of known issue, but didn't find anything. It seems like someone else would have had to have run into this before.

The Eclipse Platform uses File.createTempFile() to test various directories to see if they are writeable during initialization and this issue adds 5 seconds to the startup time of our application.

I imagine somebody has run into this before and might have some insight. Here is sample code I executed to see that it is indeed this call that is consuming the time. I also tried it with a second call to createTempFile and notice that subsequent calls return nearly instantaneously.

public static void main(final String[] args) throws IOException {
        final File directory = new File(args[0]);
        final long startTime = System.currentTimeMillis();
        File file = null;
        try {
            file = File.createTempFile("prefix", "suffix", directory);
            System.out.println(file.getAbsolutePath());
        } finally {
            System.out.println(System.currentTimeMillis() - startTime);
            if (file != null) {
                file.delete();
            }
        }
    }

Sample output of this program is the following:

C:\>java.exe -jar filetest.jar C:/Temp
C:\Temp\prefix8098550723198856667suffix
5093
+1  A: 

It might be the intialisation of the secure random number generator which is causing the problem. In particular if a secure random seed is not obtainable from the operating system, then the fall-back mechanism attempts to gain entropy. IIRC, one of the things it does is to list temporary files, so if you have a large number of those that will not help start-up performance.

Tom Hawtin - tackline
I tested the secure random generation separately and that isn't the problem. I ran this in the debugger and looked at the implementation of createTempFile and noticed the secure random generation and suspected that myself but ruled it out after testing that piece specifically with a test program.Thanks for the suggestion though.I doubt if there will be a large number of temporary files on this system. I'm not sure what qualifies as a temporary file that would count against what you are speaking towards, but the c:/temp directory where I ran my specific test above only has 165 files.
Ben Roling
Ok, so I was wrong when I said it isn't the secure random generation. After a little more debugging I realized my initial test of the secure random part of this was insufficient. I had only tested the construction of new SecureRandom(). When I tested the first invocation of nextLong() on the SecureRandom, I saw that was the source of the 5 second delay.
Ben Roling
A: 

I'm not a Citrix expert, but I know someone who is, and who conjectures:

The accounts may be set up so that application reads/writes are redirected to non-local resources. The latency you're experiencing may be related to the initialization or performance of that resolution.

Another possibility is that the application isolation may be in effect, which means file reads/writes happen on virtualized versions of resources.

Noel Ang
Thanks for these suggestions, but the resources are local and the fact that an administrator user can write to the exact same location without this delay suggests to me this couldn't be the issue anyway.
Ben Roling
A: 

It looks like the slowness is due to the seeding of SecureRandom and only when the user is a member of the Guests group.

The SecureRandom seed initialization uses a Windows Crypto API which fails when the user is a guest as described here [1]. By setting the system property "java.security.debug" equal to "all", I can see the following when the program as run as a guest:

ProviderConfig: Loaded provider SUN version 1.6
provider: Failed to use operating system seed generator: java.io.IOException: Required native CryptoAPI features not available on this machine
provider: Using default threaded seed generator

When run as non-guest user, the output is this:

ProviderConfig: Loaded provider SUN version 1.6
provider: Using operating system seed generator

It appears the default threaded seed generator is quite slow. Here [2] is a very old bug logged to Sun about this.

[1] http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2003-12/0349.html

[2] http_://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4210047 (since I'm new to stackoverflow I can only include one hyperlink but you get the picture)

Ben Roling