Forum Stats

  • 3,837,409 Users
  • 2,262,256 Discussions
  • 7,900,271 Comments

Discussions

OHJ, Java Web Start and class loaders


Greetings,

Our application runs under webstart on Windows 2000 and we use OHJ as on-line help. Our application uses a different version of the ICE browser, so we are forced to load the four OHJ jars into a separate URLClassLoader. This works fine when running from the command line, but we've seen various problems running under webstart, varying from the Help object unable to find its images to an inability to create an instance of oracle.help.htmlBrowser.ICEBrowser. We suspect these issues are due to the fact that Java web start uses its own class loader. We've prototyped OHJ without the URLClassLoader, and it runs fine under webstart.

Does OHJ create its own class loader for any reason? Does it use getSystemClassLoader() to retrieve its images via getResource?

thanks for your help,

Elizabeth Dyer.

Comments

  • 307050
    307050 Member Posts: 163
    Elizabeth:

    Sorry it took so long to get you a response -- this was a pretty tricky problem (and one that was not aided
    by the fact that OHJ didn't print the true nature of the exception!). OHJ doesn't have any bad classloader
    manners -- it doesn't hard-code any references to the system loader or anything. The problem you encountered
    (which I was able to reproduce) is a Java security permissions issue.

    The problem is that the URLClassLoader, when running under Web Start, grants the loaded classes a fairly limited set of security permissions. The Ice browser uses a number of system properties to allow various settings to be changed. The problem you encountered is a SecurityException caused by Ice trying to call System.getProperty.

    To get around this, you can create a subclass of URLClassLoader and override the checkPermissions method to allow the Ice browser to read/write its permissions. (I'm not sure if write access is strictly needed here, but I don't think it hurts.) The code should be like this:
        protected PermissionCollection getPermissions(CodeSource codesource)
        {
          PermissionCollection perms = super.getPermissions(codesource);
          perms.add(new PropertyPermission("ice.*", "read,write"));
          return perms;
        } 
    Then, if Ice is loaded via this subclassed URLClassLoader, the problems should go away. Please let me
    know if this works or not.

    By the way, it sounded like you're loading all of OHJ via the class loader. While this certainly will work,
    I was thinking it might be easier if you loaded only the Oracle Ice browser into its own class loader.
    You could do this by implementing a proxying oracle.help.htmlBrowser.HTMLBrowser implementation that
    delegates to a real HTMLBrowser implementation it loaded via a custom URLClassLoader. You'd then have
    to package Oracle's Ice Browser, along with the regular IceHTMLBrowser implementation, in JAR that the
    proxy HTMLBrowser would load. Then you'd just pass the class of your proxying HTMLBrowser to the Help constructor. This would let you leave the rest of OHJ loaded by the normal mechanisms.

    Hope this helps!

    -brian
  • 328709
    328709 Member Posts: 48

    Brian,

    Thanks for this information; I was able to add it to our prototype help application and achieved some success. Extending the URLClassLoader to add permissions for the "ice." package did work, however, only if the URLs for the jars loaded into the extended URLClassLoader had a "http://..." protocol. If the URLs for the jars used a "file://" prototype, then the Help constructor fails with a NULL pointer exception...

    java.lang.NullPointerException
    at javax.swing.ImageIcon.<init>(ImageIcon.java:161)
    at oracle.help.DefaultNavigatorPanel.<init>(Unknown Source)
    at oracle.help.Help._initHelpSystem(Unknown Source)
    at oracle.help.Help.<init>(Unknown Source)
    at oracle.help.Help.<init>(Unknown Source)
    at oracle.help.Help.<init>(Unknown Source)
    at ead.OHJImpl.<init>(OHJImpl.java:32)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at java.lang.Class.newInstance0(Class.java:306)
    at java.lang.Class.newInstance(Class.java:259)
    at ead.myFrame.<init>(myFrame.java:58)
    at ead.myFrame.main(myFrame.java:83)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:324)
    at com.sun.javaws.Launcher.executeApplication(Unknown Source)
    at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
    at com.sun.javaws.Launcher.continueLaunch(Unknown Source)
    at com.sun.javaws.Launcher.handleApplicationDesc(Unknown Source)
    at com.sun.javaws.Launcher.handleLaunchFile(Unknown Source)
    at com.sun.javaws.Launcher.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:536)


    We added debug statements to our extended URLClassLoader to find out that it can't load the resource oracle/help/images/display.gif.

    If the jars are loaded into the extended URLClassLoader with the "http://" protocol, then there's no problems. Do you have any ideas why there's a difference between specifying the http: and the file: protocols? We'd really like to use the file: protocol to specify the jars for performance reasons.

    I'm also pursuing your idea of isolating only the oracle_ice-5_06_10.jar rather than all four Oracle jars. I had a question on the contents of the jars to be loaded separately into the URLClassLoader besides the oracle_ice-5_06_10.jar. Would I take apart the help-4_1_16.jar and extract all the classes that are in the oracle.help.htmlBrowser.HTMLBrowser package? Are there additional classes that need to be put into the jar that is also loaded by the URLClassLoader?

    thanks for your help, I can also send you my sample code for any of the above...

    Elizabeth Dyer.

  • 307050
    307050 Member Posts: 163
    >
    I'm also pursuing your idea of isolating only the oracle_ice-5_06_10.jar rather than all four Oracle jars. I had a question on the contents of the jars to be loaded separately into the URLClassLoader besides the oracle_ice-5_06_10.jar. Would I take apart the help-4_1_16.jar and extract all the classes that are in the oracle.help.htmlBrowser.HTMLBrowser package? Are there additional classes that need to be put into the jar that is also loaded by the URLClassLoader?


    The only things you should need to load with the URLClassLoader are the contents of oracle_ice and the Ice-dependent part of the htmlBrowser package, which should be:

    oracle\help\htmlBrowser\print\ICEPrintImplJava1.class
    oracle\help\htmlBrowser\print\ICEPrintImplJava2.class
    oracle\help\htmlBrowser\find\FindDialog.class
    oracle\help\htmlBrowser\ICEToolTipManager.class
    oracle\help\htmlBrowser\ICEBrowser.class

    Then, in your application code, you'd create this class loader and use it to load the ICEBrowser class:
    URLClassLoader loader = ... ;
    Class iceClass = loader.loadClass("oracle.help.htmlBrowser.ICEBrowser");
    Help help = new Help(iceClass);
    That should be it. It's important not to put the HTMLBrowser interface in the Ice jar because then you'll end up with two loaded versions of the interface!

    I think this should do it. Tell me how it goes.

    On the file: URL vs. http: URL front: I don't know what's going on there. I suspect, however, that the problem may go away by loading OHJ normally and only putting the Ice browser into its own class loader. Another thing to try to fix the file: problem, BTW, is to add a java.security.AllPermissions to the PermissionSet returned from getPermissions of your class loader. Perhaps that's the issue, a security thing?

    -brian

    PS: Out of curiosity, what version of Ice are you using in your application?
  • 328709
    328709 Member Posts: 48

    Brian,

    I haven't worked through isolating the ICE browser jars yet, but I did try out your suggestion to add all permissions. This did indeed work; I was able to bring up the navigator window and view the help topics without any problems under webstart. My extended URLClassLoader getPermissions() method now looks like...

    protected PermissionCollection getPermissions(CodeSource codesource)
    {
    PermissionCollection perms = super.getPermissions(codesource);
    perms.add(new PropertyPermission("ice.*", "read,write"));
    perms.add(new AllPermission());
    return perms;
    }

    Out of curiousity, how you deduce that the security permissions might be causing the problems? We were hoping to better understand what is going on with the security and webstart in case we come across this problem in another part of our application. Is there any public documentation available on the webstart and security issues?

    thanks,

    Elizabeth.
  • 307050
    307050 Member Posts: 163
    >
    Out of curiousity, how you deduce that the security permissions might be causing the problems? We were hoping to better understand what is going on with the security and webstart in case we come across this problem in another part of our application. Is there any public documentation available on the webstart and security issues?


    It was a guess, based on the fact that classes loaded by URLClassLoader are subject to security restrictions, such as this one pulled from the javadoc: "The classes that are loaded are by default granted permission only to access the URLs specified when the URLClassLoader was created."

    I don't know much more than this about Web Start and security. All I can recommend is starting from the Web page, which includes the FAQ at this address: http://java.sun.com/products/javawebstart/faq.html

    Glad you have OHJ working though!
    -brian
This discussion has been closed.