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!
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!