VisAD in an applet-- the resolution

VisAD works quite nicely in an applet.  Most of the programming is
straightforward, with one required trick/work-around.  I'll describe in this
email the techniques I employed, in case anybody else should need to run
VisAD in an environment similar to mine.

First off, here's a summary of the tasks which must be completed to run
VisAD in an applet:
1) Load the Sun JRE plug-in on your machine, and convert any html to make it
call the plug-in.
2) Load Java3d on your client machine, setting environmental variables as
needed.
3) Write a Java program that calls VisAD and which can run as an applet.
4) Make your html page spawn a new browser window, and send all VisAD
commands to that window.

The first 2 steps come right out of the documentation.  The 3rd step is
implied by the question, but deserves a couple notes: 1) I subclassed from
JApplet, though I'll bet that the AWT form would work too,  and 2) note that
the VisAD library only gets loaded once across all applet instances (at
least under IE 5.00) so you'll probably want to initialize variables the
first time through only, and also to make a few variables constant to
simplify subsequent invocations.  The 4th step is the work around I found to
get around a nasty garbage collection problem for which I couldn't find a
more elegant solution.  This problem first showed up when I tried to create
my second VisAD plot within a single browser session (the first was easy
enough).  To describe the issue more completely, I quote from my earlier
post:

>Under IE 5.0, using the Java plug-in 1.3, the JVM loads my applet and
>visad.jar the first time they're needed.  The next time around, the browser
>calls Class.newInstance() (which performs a shallow copy) to generate a new
>version of my applet class, while keeping the instantiations of any classes
...
> ... Now the trouble starts.  That first instance of my class is
>gone for good, so the garbage collector can start picking it to pieces, and
>since there are no explicit references to the information stored in VisAD's
>namespace, I think that the memory VisAD has allocated starts to be picked
>apart as well. The classloader doesn't bother to reload visad.jar from
>scratch, since it knows that it loaded visad.jar once already, and assumes
>that I've kept explicit pointers to any memory I want saved. 

I still agree with this description.  No matter which variables I held
static, my browser would crash soon after I tried my second plot, as long as
the new plot went into a new window.  My work-around was to send all the
graphics to one window.  Spawning this window and writing to it repeatedly
can be accomplished with a few lines of Javascipt:

<SCRIPT LANGUGE="JavaScript">
{
        var myw
window.open("","OneVisadWin","status=no,location=no,menu=no");
        myw.document.write("...");
}
</SCRIPT>

The first line of code creates a new window, or gets a pointer to a window
of the given name if one already exists.  The next line (and others that
must follow it) should contain code to launch your applet and send it any
parameters you like.  As long as your VisAD applet is launched within this
window you can repeatedly call VisAD routines, and everything ought to go
swimmingly.  As to why this work-around is necessary, I return to my
previous post:

>Note:  I think this IS NOT a VisAD bug (I'd call it instead a browser
and/or
>Java plug-in bug).  There may, however,  be aspects of VisAD that would
>allow me to get around the problem.  If, for example, I could get a pointer
>to the root of the data structure that VisAD uses internally, then I could
>set a static variable within my program to point to it, and everything
would
>be protected from the GC, and I could use the variables I created the first
>time through. ...

This is roughly the approach that the work-around takes, though I was a
little confused about the way in which the JVM garbage collector treats
static variables.  The key to a working solution is that the Frame the
applet uses must reference a VisAD variable, and the frame must never be
unloaded.  Specifically, I use the DisplayImpl.getComponent(), and add it to
a JPanel, which I then add to the applet frame.  As further evidence that my
proposed explanation is correct, I encountered the following situation:  I
wanted two VisAD displays, one for 2-d and one for 3-d.  If I created them
the first time I hit the applet, and stored them in static variables, to add
and remove from panels as I needed, my applet quickly crashed.  If instead I
put both displays on a panel and left them there, making one or the other
current as needed using the following two calls (as an example, I make the
2-d display current):
  panel3d.setSize(1,1);
  panel2d.setSize(480,480);
then the program worked quite reliably.

That's all for now.  I'll try to work up a minimal 'hello visad-applet
world' example sometime soon.  Thanks to everyone on the list who responded
to my queries, namely Dave Glowacki, Ng Sag Teong, and TomW.  Thanks also to
a few people who responded to me offline.  If anyone else tries this
approach then please let me know if it worked for you.  Thanks.

Ben


  • 2000 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the visad archives: