Daniel Pitts’ Tech Blog

Please vote no on 8.
Please vote no on 8.

Archive for October, 2008

Polish ’till it shines

Thursday, October 30th, 2008

Recently I’ve been faced with the same lesson over and over again.  Polishing is a necessary and oft overlooked step in the creative process.  It takes significantly more effort polishing your final product than just making it work.

By “polishing” I mean putting the final pieces in place, cleaning up any mess, and making sure that your creation shines!  Often times we think about polishing only in regards to one aspect of what we create. For application programmers, it may be improving the user interface; for writers it could be reorganizing the essay.  But there is so much more that needs to sparkle.

I’ve come to the realization that I need to spend more time polishing in almost everything I do. From writing these blogs, to my personal relationship, and many levels of my programs.  Often, since I’m so enthusiastic about a topic,  I am so anxious to share the enthusiasm that I skip vital information, don’t proof read, or try to expand too much on all the implications.  Even now, I feel like expanding on other “things” that software developers need to worry about polishing (I’ll make that another post).

I’m now determined to write more polished articles, as well as and code. You can expect my future articles to be better written. I might even cleaned up and re-post so old articles.  I’ll even proof and edit before I publish. Hey, I even edited this article before I published!

JavaScript and Java applets

Saturday, October 11th, 2008

I know, Applets are almost dead, but we actually had use for them recently in a project.  We needed to upload multiple images at once, and since no one on our team knows Flash, we decided to use an Applet. Anyway, the trouble we came across was the Java to JavaScript bridge is flat-out broken.  What you are supposed to be able to do is well documented at Sun’s java_js page and Mozilla’s LiveConnect page. The trouble is, that they are wrong when it comes to calling a Java method from JavaScript. They also fail to mention the security implications of that altogether.

Signed applets with unsigned JavaScript

The first challenge we came to (which is actually the easiest to solve) was that we were getting AccessControlExceptions, even though we went through the trouble of signing the Applet jar. As it turns out, the permission context used is that of the JavaScript, so you need to elevate the permission to your Applets context, using AccessController, and PrivilegedAction.
Java:

public void javascriptCallsMe() {
    AccessController.doPrivileged(new PrivilegedAction() {
      public Void run() {
         // We can now
         readOrWriteFilesOrWhatever();
         return null;
      }
    });
 }

That solved that problem.

Passing JavaScript objects to Java

The next problem, which plagued me for a week, was that getting a JSObject in Java seems to be broken. There are two ways to get an instance of the netscape.javascript.JSObject class.  The first way, and this always seems to work, is the JSObject.getWindow(Applet applet).  This will get the JSObject wrapping the “window” browser object.  This is useful if you know the “path” to the JavaScript object your code cares about.  It is akin to using a static reference, and isn’t good design. The other way, is to have a Java method that takes an Object or JSObject reference: In Java:

public class MyApplet extends JApplet {
  public void doStuff(JSObject params) {
    System.out.println(params.getMember("foo"));
  }
}

Then in JavaScript you should be able to do this: documents.applets[0].doStuff({foo: “bar”}); Unfortunately, what really happens is you get a “broken” instance of JSObject.  Debugging the Applet, I found that the JSObject instance has a field called nac, which has a value for the JSObject.getWindow(…), but is null for values passed in from JavaScript. So, what solutions and work arounds have people come up with? None that I could find.  I searched high and low. Plenty of people have discovered this bug, but none of come up with a solution. Until now!  I thought about it and realized, JSObjects I get from the “window” JSObject all work, so maybe I can put my broken object into a working object, and pull it back out to get a working object. A little experiment proved that it worked (at least on FireFox, I’ll guess it works on IE too, anyone want to verify?). So, I decided to go ahead and create a JSObject resolver, that will fix any possibly broken object:

public class MyApplet extends JApplet {
  private JSObject appletTmp;

  public JSObject resolveObject(Object o) {
    final int hashCode = System.identityHashCode(o);

    appletTmp.setMember("toResolve" + hashCode, o);
    return (JSObject) appletTmp.getMember("toResolve" + hashCode);
  }

  public void init() {
    if (appletTmp == null) {
      final JSObject window = JSObject.getWindow(this);
      final String tmpName = "_AppletTmp" + System.identityHashCode(this);
      window.eval("var "+ tmpName +" = {}");
      appletTmp = (JSObject)window.getMember(tmpName);
    }
  }
}

Granted, this code doesn’t clean up after itself, so if you use it for a long time or on a lot of JS objects, you will need to add some clean up code to it. With that, I was finally able to fully use the Java Applet the way I wanted to: As a “service provider” to the JavaScript on our existing page.