Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 217
  • Last Modified:

Loading on demand

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.
0
sniles
Asked:
sniles
  • 5
  • 5
1 Solution
 
yorenCommented:
I think you can just put that dialog in a separate .zip file. Just make sure that both .zip files are in your CLASSPATH and you should be good to go. Keep the same directory structure in both files. Something like this:

main.zip:
  my/package/file1.class
  my/package/file2.class
  my/package/file3.class

myframe.zip:
  my/package/myframe.class
0
 
snilesAuthor 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?
0
 
yorenCommented:
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

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
snilesAuthor 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?
0
 
yorenCommented:
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
0
 
yorenCommented:
In my last comment, I meant to have CODEBASE="main"
0
 
snilesAuthor Commented:
Wonderful! I'll try it right away. Thanks very much! :)
0
 
snilesAuthor 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.
0
 
yorenCommented:
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.
0
 
snilesAuthor 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.
0
 
kolmCommented:
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.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 5
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now