My Photo

Recent Comments

Powered by TypePad

January 30, 2007

MSJVM - No "Trusted Operations in init(), start(), stop(), or destroy()"

In our applet's startup, we tried to load an image and an associated annotation file from the users local disk. For some reason, the image would load fine, but the annotation file caused an com.ms.security.SecurityException, only in the MS JVM. Everything loaded fine under the Sun JVM.

I looked at the image-loading code and noticed that it was running in a separate thread. I moved the annotation loading to a separate thread and then everything worked great.

After some research, I found some documentation on this issue.

SecurityExceptionEx exception running a Java applet

-Alex

October 13, 2006

JavaScripting in Applets - Getting Out of the Sandbox

I'd like to describe a recent discovery with regards to using JavaScript with Applets, and running into security problems. First, I'll give an overview of "The Applet Sandbox", and using JavaScript to call into an Applet.

The Sandbox

When developers are introduced to Java Applet technology, one of the first things they learn about is the Java Applet Sandbox. The sandbox refers to a set of security restrictions imposed on an Applet. The sandbox exists to prevent potentially dangerous code from being executed on a user's machine when they simply browse to a website.

Three of the basic restrictions are as follows:

  • No access to the client's local file system.
  • No network access to a remote system other than the Applet's host machine.
  • No access to the client's printer.

There is a way to break out of the sandbox, via signing. A company can establish itself as a trusted vendor by purchasing certificates from a company like VeriSign. You can then "sign" your Applet and have the ability to do things such as read local files, and connect to an arbitrary URL. In order to write the most powerful Java Applets, this is the way to go.

Calling Applet methods via JavaScript

Since Applets are meant to be embedded in web pages, it would be nice to have your web page interact with your Applet. The way to do this is via JavaScript. Here's a really basic example.

Our Applet has one method, changeColor:

public class ColorApplet extends Applet
{   
    public void changeColor (String color)
    {
        if (color.equals("red"))
        {
            setBackground(Color.red);
        }
        else if (color.equals("blue"))
        {
            setBackground(Color.blue);            
        }   
    }   
}

This is a pretty worthless Applet without some kind of external access into the changeColor method. Here's the HTML to call into the method:

<html>
<body>
<applet height="100" width="100" code="ColorApplet.class" name="ColorApplet"></applet>
<a onclick="javascript:ColorApplet.changeColor('red');" href="#">Red</a>
<a onclick="javascript:ColorApplet.changeColor('blue');" href="#">Blue</a>
</body>
</html>

By clicking on the "Red" and "Blue" Links in the html page, the Applet's background would change accordingly.

Using JavaScript to call restricted methods.

Changing colors in an Applet doesn't seem very useful. But lets say I have an Applet that can open up images from a file name or from a URL. The JavaScript hyperlinks can be used to open different files and URLs in the applet. I implemented a public method,

       public void openFile (String filename) 

 

This method will open up a local file or URL and display the image in the Applet. This works fine with any filename or URL since our Applet is signed. However, when I tried to call this method from an html page with JavaScript, I got the following error:

java.security.AccessControlException: access denied (java.io.FilePermission C:\images\img1.tif read)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkWrite(Unknown Source)

 

I was baffled. I retested openFile via my file menu, and the image opened up fine, so I knew I had signed the applet properly. I tested the JavaScript again and no luck. Hmm. Then I tried another JavaScript method that simply printed out some text to the console and that worked. Finally, I figured that there must be some additional security layer that prevents JavaScript from calling into the sandbox-restricted methods, even if the Applet is signed. After a quick Google search, I found some forum threads such as this one, which confirmed my suspicions. So what to do? I figured I would use the JavaScript method just to set some properties in the Applet. I would then create a separate thread that could be responsible for listening to changes in these fields, and calling the openFile method on behalf of the JavaScript. Here's how that worked. I made a new method called jsOpenFile, like this:

  /**
     * @param name
     */
    public void jsOpenFile(String name)
    {
        gJavascriptFilename = name;
        gJavascriptCalled = true;
    }

Then I defined a thread in the init() method of my applet, like this:

            Thread javascriptListener = new Thread()
            {
                public void run()
                {
                    while (true)
                    {
                        if (gJavascriptCalled)
                        {
                            gJavascriptCalled = false;
                            openFile(gJavascriptFilename);
                        }
                        try
                        {
                            sleep(JAVA_SCRIPT_POLL_INTERVAL);
                        }
                        catch (Throwable t)
                        {
                            t.printStackTrace();
                        }
                    }
                }
            };
            javascriptListener.start();

Sure enough it works!

-Alex

September 18, 2006

The Microsoft JVM

With good regularity, Sun introduces their latest technology in the form of their Java Virtual Machine or JVM (aka JRE, or JDK; at their core, the acronyms are essentially synonymous). Functionality provided over the past years includes the following: mouse wheel support, "always on top" windows, full screen mode, internationalization, logging, security, and enhanced data structures. The latest version is JDK 1.5.0.8.

This is all great unless you're stuck with the Microsoft JVM. Some machines from a few years back were shipped with the MS-JVM. The problem is that it is based on JDK 1.1, which is over 8 years old at this point. It's easy enough for an individual to go to Sun's website and upgrade. But it is not necessarily easy for IT Managers at large corporations.

So that means if you provide Java applets for one of these large corporations, you have to make sure your applet will run on the MS-JVM, aka JDK 1.1, aka 1998 technology. This means no Swing, no Collections, no java.util.Logging, etc.

To make matters worse, Microsoft stopped shipping Java at all with new PCs, and they don't make their old JVM available. Luckily, some old versions of the install program are still kicking around. If you search on the filename msjavx86.exe, you'll find some results. I found my copy at filemirrors.com.

Once you install the JVM, it is still a bit tricky to get it to work. You need to navigate to Tools -> Internet Options -> Advanced and scroll down to the section on Java. Be sure to uncheck the option to use the Sun JVM and be sure to check the options for the console and logging for the MS JVM. Once you've restarted IE, your Java Console will now be available at View -> Java Console instead of Tools -> Sun Java Console. You'll  know you've successfully installed the JVM if  you console shows up and shows something like the following:

    Microsoft (R) VM for Java, 5.0 Release 5.0.0.3805

Welcome to 1998!

-Alex