Spaces in path to app causing RMI fits with MalformedURLException

K

Kerry Shetline

When my app's JAR file is stored somewhere like this:

C:\MyProgram\myprogram.jar

....my app runs fine. However, if I store the app someplace like this:

C:\Documents and Settings\Me\My Documents\myprogram.jar

....RMI keeps dying, with UnmarshallingException(s) caused by:

java.net.MalformedURLException: no protocol: and

It seems obvious that the so-called protocol "and" is most likely the
"and" from "Documents and Settings". What isn't obvious is why
something deep in the bowels of sun.rmi.server.* is stupidly trying to
create invalid URLs with spaces in them, rather than properly changes
spaces to + or %20.

I Googled around looking for help, finding a few similar problems, but
nothing quite the same. One suggestion I'd seen for fixing RMI
problems was explicitly setting the java.rmi.server.codebase System
property. That didn't help at all, whether I escaped spaces in the URL
to my app's directory or not. In fact, I made a duplicate application
directory, in a location that needed no spaces, and pointed the
codebase there, while still running from the app from its spaced-out
location, and nothing changed. Something, somewhere was determined to
use "C:\Documents and Settings..." as a bad URL, no matter what. (I've
tried both forward / and backward \ slashes too, just in case anyone
is wondering.)

I made some partial progress doing this:

System.setProperty("java.rmi.server.RMIClassLoaderSpi",
"com.mycom.mypackage.MyRMIClassLoaderSpi");

....where MyRMIClassLoaderSpi is simply a wrapper around the default
RMIClassLoaderSpi, a wrapper that turns spaces in the "codebase"
argument of getClassLoader(), loadClass(), and loadProxyClass() into
%20 before calling the default RMIClassLoaderSpi. I caught and fixed a
few problems this way, only to find an even stranger problem.

Sometimes loadClass() is being called with a null codebase and a class
name of "[B". I think this is probably shorthand for either a boolean
primitive or the Boolean class. At any rate, there's no codebase URL
for me to fix, yet somewhere within what the default RMIClassLoaderSpi
does, not having been given a URL, some wayward bit of code has a go
at making a bad URL anyway:

java.net.MalformedURLException: no protocol: and
at java.net.URL.<init>(URL.java:537)
at java.net.URL.<init>(URL.java:434)
at java.net.URL.<init>(URL.java:383)
at sun.rmi.server.LoaderHandler.pathToURLs
(LoaderHandler.java:747)
at sun.rmi.server.LoaderHandler.getDefaultCodebaseURLs
(LoaderHandler.java:120)
at sun.rmi.server.LoaderHandler.loadClass
(LoaderHandler.java:149)
at java.rmi.server.RMIClassLoader$2.loadClass
(RMIClassLoader.java:631)
at com.mycom.mypackage.MyRMIClassLoaderSpi.loadClass
(MyRMIClassLoaderSpi.java:56)
at java.rmi.server.RMIClassLoader.loadClass
(RMIClassLoader.java:257)
at sun.rmi.server.MarshalInputStream.resolveClass
(MarshalInputStream.java:200)
...

Sun's JDK doesn't seem to come with source code for the various sun.*
packages, so I can't dig into this code to figure out what's going on
and how to avoid this URL problem. Making my own MyRMIClassLoaderSpi
more and more complex to try to solve the problem doesn't seem like
the right course to take. Messing with java.rmi.server.codebase
doesn't seem to help either, so I'm at a loss about what to do next,
other than issue a ridiculous requirement that my app can't be
installed anywhere that there would be a space in the path that lead
up to the app.

Does anyone have any better ideas or useful suggestions? Any help
would be greatly appreciated!
 
K

Kerry Shetline

I found the problem... and it was me. Sort of. :)

About three months ago, I found some code online dealing with doing RMI
over SSL. The sample code included this line:

System.setProperty("java.rmi.server.codebase", "file:/" +
new File(".").getCanonicalPath() + File.separator;

Bad code. Very bad.

At the time this line kind of made sense, so I used it as-is, and
promptly forgot the line was even there. This is where the bad URL with
spaces in it was getting into the class loading procedure. I had so put
this code out of my mind that when I confronted the System property
"java.rmi.server.codebase" again while tracking down this bug, it didn't
even ring a bell.

Everything I'd tried recently to fix the bad URL problem executed before
this bit of sample code executed, making sure everything I tried to put
right was put wrong again. Once I stumbled across this line (quite by
accident) and fixed it, the bug went away.

Whew!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,084
Latest member
HansGeorgi

Latest Threads

Top