How can I make a browser execute a part of code before loading a jar? I want to make a splashscreen for a big applet that is contained in a jar, but the jars are loaded before the splashimage is displayed.

Finlay McWalter

To write an applet that shows a splashscreen, we need to know what happens when applets (and java classes in general) are loaded.

When you ask a java runtime to load a class (e.g. by giving it as a command-line argument to the java executable, or by loading a webpage containing an applet tag) the runtime tries to load that named class (e.g. "foo.class"). In general (as in this case), this can only complete once all the classes that foo depends on are also loaded. A class is dependant on any other class that:

  • is a superclass of it.
  • is an interface that it implements, or a superinterface of any such interface.
  • that it explicitly references.
Most of these will, in general, be system classes (part of the browser) and thus can be loaded very quickly (if they're not already loaded) - but (for applets that consist of a number of classes) the "root" class isn't finished loading (and thus can't run) until all other classes that it references are also loaded - and they aren't loaded until any classes they reference are loaded (and so on).

So the reason that a big applet isn't able to do anything (like painting a "loading..." message) quickly is because the browser has to wait until all of the classes of the applet are downloaded.

In order to have a "splashscreen" load quickly, and have it run before (and during) the loading of the rest of the applet, we have to break the explicit dependancy between the initial class and the other classes in the applet. The following example shows how to do this, and in the process shows off some of the amazing things you can do with the powerful java Classloader class.

The example shows a tiny "loader" applet (initial.java) which serves to purposes:

  1. it displays the splash screen
  2. it references the rest of the applet (by string), causing the remaining applet code to load.
The clever bit is that the loader doesn't explicitly reference the rest of the applet (in this case "second.java"), to the compiler doesn't pick this up as a dependancy - as far as it it concerned, initial is a freestanding class. Instead, initial references second programmatically, using the forName() method of class Class. Here's initial.java:

    import java.awt.*;
    import java.applet.Applet;

    public class initial extends Applet implements Runnable {
        private String classToLoad;

        private void fetchClass(String className) {
            classToLoad = className;
            Thread t = new Thread(this);
        public void run() {
            try {
                Class mainClass = Class.forName(classToLoad);
                Component mainInstance = 
             catch (Exception e) {
          *  Called when the applet is initialised -
          *  here we start the asynchronous load of the rest of
          *  the applet.
         public void init() {                
             setLayout(new BorderLayout());
          *  Display a simple message 
         public void paint(Graphics g) {

And here's second.java, the source for our simple example second-phase:

  import java.awt.*;

  public class second extends Canvas {
     public void paint(Graphics g){
       Dimension d = getSize();
       g.fillRect(0,0,d.width, d.height);

You'll see from initial that it loads the subsequent code in a new thread - this is because Class.forName() blocks - if we didn't spawn a new thread then init() wouldn't terminate until second was loaded - and initial can't paint until its init() method exits.

Here's the HTML code for loading the applet:

  <h1>multi-stage applet<h1>
  <applet code=initial.class width=300 height=300>

Notice that CODE points just to initial.class, not to subsequent classes like second.class - but the applet classloader will still need to be able to load second.class later, so it must be accessible, i.e. it must be in a place specified by the CODEBASE parameter.

Now, ideally we'd have many classes in the second part, and the logical place to keep them would be a JAR file, but we can't name that JAR file in the applet's ARCHIVE parameter, as the applet environment always loads all the JARs mentioned in the ARCHIVE parameter, even if they don't appear to be referenced initially. Thus we're stuck loading individual classfiles across the network.