Friday, February 4, 2011

Why no ClassShutter in Java6 JS engine?

There is one thing about Java6 I am in a way baffled by. As far as I remember the JavaScript scripting engine in Java6 has been based on Mozilla Rhino. How did it happen that the implementation in Java6 is missing the original Rhino functionality for restricting the set of classes that may be loaded by a script?

I assume the feature has been replaced by allowing a custom implementation of java.lang.ClassLoader in one of javax.script.ScriptEngineManager constructors. This offers unlimited flexibility for other scripting engines that might be plugged in the JVM instance. Then another question - is there any built-in ClassLoader in Java6 that supports class filtering? Because of safety reasons it is quite natural to limit the set of classes loadable by scripting extensions. However it seems there is no standard or default way to do that. So everybody willing to ensure better control over the extension scripts has to build their own implementation of essentially the same functionality. Not quite encouraging.

5 comments:

  1. I've been researching this for many hours and I'm still trying to figure out if ClassShutter can be used with the javax.script library. BTW I don't think setting a ClassLoader in ScriptEngineManager is the answer. It looks like it just determines which script engines are accessed.

    ReplyDelete
  2. to Glenn:
    Interesting, though, that there is com\sun\script\javascript\RhinoClassShutter.class in the rt.jar...
    Any idea how to make use of it?

    ReplyDelete
  3. com.sun.script.javascript.RhinoClassShutter appears to rely on the global SecurityManager for its security settings, which is more-or-less ok if you have control over that. However I'm writing a library, so I can't control the JVM environment. It's also a problem if you want different security settings for different scripts. I'm still trying to figure out if there is any way to override the RhinoClassShutter as I really just want to turn off LiveConnect altogether.

    ReplyDelete
  4. to Glenn:
    My understanding is that there's no other choice but to create a custom version of com.sun.script.javascript.RhinoScriptEngine. The problem lies in its static initializer where class shutter is set to the singleton com.sun.script.javascript.RhinoClassShutter.getInstance(). This one is very limited in functionality and cannot be used for the purpose. Plus, as I can see, Rhino internally allows shutter to be set only once leaving no chance to replace it later.

    I think the easiest way is to download OpenJDK6 source bundle, fork com.sun.script.javascript sources into a separate package, then hack them the way you need. It shouldn't be a problem to replace the engine at runtime with a javax.script.ScriptEngineManager.registerEngineName(String, ScriptEngineFactory) call.

    ReplyDelete
  5. The other alternative is to forget the JDK scripting and use the org.mozilla.javascript Rhino. It seems to be better supported with updates from Mozilla and you get a *lot" more control over the script engine. It means deploying another jar - but that's ok for me.

    ReplyDelete