We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Loading on demand

sniles
sniles asked
on
Medium Priority
234 Views
Last Modified: 2010-03-30
I have a single package that is loaded in one .cab .zip or .jar.  In it is a large dialog implemented as a subclass of Frame. I would like to load this seperately, as it is sometimes never invoked, but contributes to the size of the .cab, .zip & .jar file that must be loaded.  What is the easiest way to load this seperately without changing the structure of the code too much? Answer must work for JDK 1.01.
Comment
Watch Question

Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
This would require *some* change to the code... it's setting up a different package.  I would have to include an IMPORT for that package, which I think would cause myframe.class to load at the same time as main.class.  Also, there would have to be some statement/function call that would requst (by name) that the file myframe.zip be loaded... could you provide some sample code to show how that is accomplished?

Commented:
sniles,

No code changes are required. You create one package, but two .zip files. I created an example package called "my.pkg" that has two classes: File1 and File2. Each is in its own .zip file. I then created a main class "mainclass" that imports my.pkg but only calls File1. Using the "verbose" option of the "java" command tells us that File2 was never loaded.

Here's the file structure:

main/
  mainclass.java
  mainclass.class
  file1.zip  -- inside the zip:
      my/
        pkg/
          File1.class
  file2.zip  -- inside the zip:
      my/
        pkg/
          File2.class

-------------------------

Here's mainclass.java:

import my.pkg.*;

public class mainclass {

  public mainclass() {
    new File1();

    // We never call File2, so we don't want it to load.
    if (0 == 1)
      new File2();  
  }

  public static void main(String[] args) {
    new mainclass();
  }
}

--------------------------------------

Here's File1.java:

package my.pkg;

public class File1 {
  public File1() { System.out.println("File1 Loaded"); }
}

---------------------------------------------------

Here's File2.java:

package my.pkg;

public class File2 {
  public File2() { System.out.println("File2 Loaded"); }
}

------------------------------------------------------------

Now, to run this, you'll need to add "file1.zip" and "file2.zip" to your classpath. Here's the classpath I used:

set CLASSPATH=.;d:\temp\multijava\file1.zip;d:\temp\multijava\file2.zip

Compile your classes. Then create your .zip files (the -0 is for no compression, which is needed for java archives):

zip -0 file1.zip my/pkg/File1.class
zip -0 file2.zip my/pkg/File2.class

Then run java in verbose mode. It will send the entire list of loaded classes to stderr, which you can check to see if File2 was loaded:

%java -verbose mainclass 2> loadedclasses.txt
File1 Loaded
%

In loadedclasses.txt you should see this line:

[Loaded my/pkg/File1.class from d:\temp\multijava\file1.zip]

but NOTHING from file2.zip.

Good luck,

Yuval

Author

Commented:
This is to support a web-based applet.  Will this force me to use applet tag parameter archive="file1.zip,file2.zip"?  Will that load both files at once? or one file, then the other (when needed)? Will this also work for .jar and .cab?

Commented:
Oh! Why didn't you say so :)

In that case, the answer is much easier. Just don't include your dialog class in the archive, but make sure you have an entire directory tree of all your classes. When the browser doesn't find a class in the archive, it looks in the code base.

<APPLET ARCHIVE="file1.zip" CODEBASE="multijava">

directory structure:

   main/
     file1.zip  -- inside the zip:
        mainclass.class
        my/
           pkg/
             File1.class

     mainclass.class
     my/
       pkg/
          File1.class
          File2.class

Commented:
In my last comment, I meant to have CODEBASE="main"

Author

Commented:
Wonderful! I'll try it right away. Thanks very much! :)

Author

Commented:
Hmm... I just tried it, and if I'm reading the Netscape Java Console correctly, the class I deleted from the .zip is being loaded at the same time as it was before, the only difference being that it's fetched from it's .class file, instead of loaded from the .zip -- all before the Applet is initialized.  

My goal was to load that class later (or never), because it's large and slows down the loading of the applet, but is sometimes never called.  Is there a way to defer this loading?  The class is not instantiated until the user issues a specific command.

Commented:
sniles,

I just tried it with my example and it worked, both on Netscape 3.03 and 4.5b1. Chances are that you're accidentally referring to it somewhere when you may not need to. Remember, even declaring a variable of that class type will cause the class to be loaded. You might want to try commenting out parts of your code to determine the code that's causing your large class to be loaded.

Author

Commented:
I tried that, and I'm still seeing the class loaded after the "Applet Loaded" message, but before the "Applet Initialized" and "Applet Started" message is sent to the console.  

I went through the code thoroughly, and made sure that no instances of that class would have been created (come into scope) during initialization and startup. Is that sufficient? Or is *any* declaration *anywhere* in the code (even if not brought into scope) enough to cause the class to be loaded?

I tried this both with NS 4.04 (deleted files from JAR and manifest) and NS 3.01 (deleted files from ZIP).

Thanks for bearing with me on this.

Commented:
Yoren's example works because the boolean condition in:


          // We never call File2, so we don't want it to load.
          if (0 == 1)
            new File2();  

is constant and the expression is optimized by the compiler.
When condition is not a constant and is really checked in the
run time, the File2 class is loaded no matter the condition
is true or false.
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.