First of all: We usually blog in German. But we thought that the information of this post might be so helpful to other folks out there that we made an exception.
Ok, now that we’ve clarified that, let’s get straight on with the topic: Yes, we too chose Eclipse as platform for some software we had to implement. It was a good choice. Development was fast and if you really need something like OSGi (most people don’t need it and don’t tell me otherwise) you have it at your fingertips.
But when the time came to deploy the application in the customer’s environment we immediately realized that there was something strange going on – such poor startup performance! None of us ever experienced something like that before and so we were forced to do some investigation. I’m talking about 20 seconds and more!
Before we go into detail let it be said that we used Eclipse RCP 3.6 and Java 1.6. These were general requirements in our project.
No pain, no gain
First things first: CPU profiling. I mean the application is dying of thirst and a good drink would be a Xeon E5-2699 v3, right? So let’s see about that:
Wrong! Eclipse is doing some FTP call which is not being answered. What the hell? We didn’t code that and we didn’t provide any resources via FTP. So what’s going on? Well, time to warm up the debugger.
Hm, that doesn’t look like an FTP URL. We need to dig deeper. Grab your binary shovel for an adventure you’ve never experienced before! Ok, maybe I’m exaggerating here, but you’ll see what I’m getting at.
At this point I should probably tell you that the enterprise we implemented the application for uses Windows and Roaming User Profiles and that we configured our application parameters “‑configuration” and “‑data” to “@user.home/eth-blog-201409/slow-startup”. Ok, this is not entirely true: I’ve changed the path for the sake of this post. And if you think something like: “Why the hell did you use @user.home when dealing with Roaming user Profiles in the first place?” Because we thought it not to be a problem. The property user.home should match %USERPROFILE% on Windows machines which is a local directory in our case. You might’ve guessed it: The values don’t match. This is due to JDK‑4787931.
Back to debugging: We need to step into the java.net.URL.openConnection() method to figure out that the sun.net.www.protocol.file.Handler class is being used to handle our URL you can see above. Unfortunately it’s a proprietary implementation of java.net.URLStreamHandler. Luckily there are tools which can decompile Java classes, which I didn’t use of course. All I can tell is that in line 97 there’s a check that determines whether the file, pointed to by the passed in URL, which has been converted to a java.io.File object with a UNC path by then, exists. Turns out that it doesn’t. And that’s fine by us. Eclipse should fall back to its defaults here – that’s the way we want it.
Guess what happens next after determining that the file doesn’t exist? sun.net.www.protocol.file.Handler sure is a try hard: It converts the file URL to an FTP URL and delegates the operation. Yes, you read right: When a file with a UNC path with a host segment other than localhost doesn’t exist you get an FTP call for free. But relax; think about your blood pressure.
Long story short
- Using @user.home as part of the configuration of Eclipse in our Roaming User Profiles environment was a bad thing, because we don’t get something like “C:\Users\<User>” but “\\ADS.SERVER\<User>”. This means that all of our OSGi and workspace stuff was located on a network share. Not cool.
- The sun.net.www.protocol.file.Handler class is badly implemented. It works fine for local files. For remote files it’s fine too, but only if the files exist. It delegates operations to an FTP handler if remote files don’t exist. A very bad thing to do in my opinion. Let the programmer decide what to do if a remote file doesn’t exist.
What action did we take?
Pretty simple: We talked to the infrastructure guys and asked for a confirmation that the path “C:\Users\Public” always exists (not located on another drive, etc.). We then replaced the “‑configuration” and “‑data” parameters of our software with something like “C:\Users\Public\<file system friendly application name>-workspace”.
And from now on the users were unable to fetch themselves a cup of coffee when launching our application. Very sad!