deploying Applet with one-jar

Help
mansoor
2007-07-03
2013-05-23
  • mansoor

    mansoor - 2007-07-03

    I am facing a problem regarding Applet application.

    I have developed an applet that make a connection with server to transfer some data and for this I am using commons-httpclient-3.0.1.jar.

    But the application was giving me the error
    java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod

    Then I update the Manifest file with-in the applet's jar file, with property
    Class-Path: commons-httpclient-3.0.1.jar commons-logging-1.1.jar commons-codec-1.3.jar

    all these jar files are place on the root of the web application

    and i call the applet in the html as
    "<APPLET  ARCHIVE="TApplet.jar" CODE="A.B.TApplet.class" WIDTH=800 HEIGHT=700>
    </APPLET>"

    it works fine on my machine.......

    but when i try to access the applet from "some other machine" it gives me the error again
    java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod

    So i try to bundle all required packages by applet in the applet jar file to become one package to downloand and run on the client and keep the mainfest file same like
    Class-Path: commons-httpclient-3.0.1.jar commons-logging-1.1.jar commons-codec-1.3.jar

    but it doesn't work so i also try to change some other options like
    Class-Path: ./commons-httpclient-3.0.1.jar ./commons-logging-1.1.jar ./commons-codec-1.3.jar

    but I got the same error again and again
    java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod

    Then during the search i found one-jar

    My first question is will the one-jar will work for applet and if yes then how.

    Secondly if i place my applet jar file in the folder main as in your example jar file then how can i access it in the html

    Thanx in advance
    Mansoor

     
    • Enrico Stahn

      Enrico Stahn - 2008-07-29

      Hello everybody,

      I'm very interested in an answer to that thread. Are there any news?

      Enrico

       
    • npgall

      npgall - 2009-05-07

      Hi,

      I've looked into running a one-jar executable as an applet too. Basically I found the main issue centres on whether you need to build a signed or an unsigned applet.

      I've found so far that one-jar does two things which are not permitted in unsigned applets:

      1. it accesses system properties via System.getProperty and System.setProperty which causes it to fail at startup due to security exceptions

      2. it tries to create its own ClassLoader

      I fixed problem (1) by modifying one-jar's source code such that it calls a utility class (copied below) for accessing system properties indirectly instead of accessing them directly.

      If the utility class detects that it does not have permission to read a requested system property, it tries to read from a set of fallback properties it maintains before returning null (it does not relay the security exception). If it can't write a property, it writes it to the set of fallback properties instead. Subsequently the read method will be able to read the value from the fallback properties. So this means that when one-jar tries to set a property expecting to be able to retrieve it at a later point it works in both applets and regular programs.

      When I then hit problem (2) however since I need to create an unsigned applet I realised that there was no way to get around the problem of creating classloaders in an unsigned applet, so I gave up. After all one-jar's classloader is the core of the whole idea.

      In case it's of use to anyone running a signed applet (where the problems above don't apply) I did some investigation on how to actually start an applet packaged in the one-jar format too.

      One-jar's "Boot" class contains the main method for starting a regular application, and this method then loads your application and calls your application's own main method in the class you configured. However applets don't have a main method, they have 4 lifecycle methods instead: init, start, stop, destroy.

      To start an applet via one-jar I figure there are 2 options:
      - create a copy of the Boot class (called BootApplet or something) which supports the 4 applet methods instead of just a main method. This would be ideal but most work.
      - work within the constraints of the existing one-jar Boot class. This was the approach I took, though I never got to test it fully. I've copied my "OneJarApplet" implementation of this below in case it's of use to anyone.

      The idea of OneJarApplet is that this class would be added to the one-jar utility itself (i.e. beside Boot class etc.) as a generic way of using one-jar to start applets. In your HTML page you would list the OneJarApplet class as the applet you want to start.

      If you look at the code in OneJarApplet you'll see that the init method in that applet is configured to call the main method of the Boot class. The Boot class would then load your application and call the main method you specified in your application as normal (i.e. so far it's like using one-jar to start a regular application).

      However the main method in your application can detect (by looking at the main method arguments) that it is being started as an applet, and it can call the static method OneJarApplet.getBootApplet() to get the actual OneJarApplet object started by the browser. It can then add GUI content to the applet as applet implementations normally do, and additionally it can register listeners with OneJarApplet to receive callbacks when the browser calls the other lifecycle methods. So the idea was that OneJarApplet would be a minimalistic "hook" to get your code started as an applet. My code is below and I hope it will be helpful to someone.

      As I mentioned I stopped working on this when I hit the classloader in an unsigned applet issue; but the approach might work in signed applets if someone wants to continue work on it.

      By the way my solution for my current project (to build an unsigned applet containing classes from many dependency jars), was to simply build them into a "fat" jar instead using Maven's jar-with-dependencies option. This approach will work for my current project but I know it won't work for more complex projects where dependency jars have been sealed.

      *********** SystemPropertyUtil **************
      package com.simontuffs.onejar;

      import java.security.AccessControlException;
      import java.util.Properties;

      public class SystemPropertyUtil {

          private static final Properties fallbackProperties = new Properties();

          public static String getProperty_AppletSafe(String key) {
              return getProperty_AppletSafe(key, null);
          }

          protected static String getProperty_AppletSafe(String key, String def) {
              try {
                  return System.getProperty(key, def);
              }
              catch (AccessControlException e) {
                  String fallbackValue = fallbackProperties.getProperty(key);
                  if (fallbackValue != null) {
                      Boot.WARNING("Could not read system property '" + key + "' due to security restriction, using previously stored fallback value '" + fallbackValue + "'");
                      return fallbackValue;
                  }
                  else {
                      Boot.WARNING("Could not read system property '" + key + "' due to security restriction, using default '" + def + "'");
                      return def;
                  }
              }
          }

          protected static void setProperty_AppletSafe(String key, String def) {
              try {
                  System.setProperty(key, def);
              }
              catch (AccessControlException e) {
                  fallbackProperties.setProperty(key, def);
                  Boot.WARNING("Could not set system property '" + key + "' to value '" + def + "' due to security restriction, set as fallback property instead");
              }
          }
      }
      *********************************************

      *********** OneJarApplet ********************
      package com.simontuffs.onejar;

      public class OneJarApplet extends javax.swing.JApplet {

          private static OneJarApplet bootApplet = null;

          /**
           * Returns a reference to the BootApplet instance, if the init method of a <code>BootApplet</code> instance has
           * been called. Returns <code>null</code> if the init method has never been called (which might inidicate that the
           * application was started as a standalone application and is not running as an applet).
           * <p/>
           * Note that BootApplet ignores subsequent attempts to call the <code>init</code> method on any instance of
           * <code>BootApplet</code> after the first time, unless the <code>destroy</code> method has been called in the
           * meantime.
           * <p/>
           * @return A reference to the BootApplet instance, if the BootApplet's <code>init</code> method has been called.
           * <p/>
           *
           */
          public static OneJarApplet getBootApplet() {
              return bootApplet;
          }

          /** Initializes the applet AudienceManagerApplet */
          public void init() {
              if (bootApplet != null) {
                  // Ignore subsequent attempt to init this applet.
                  return;
              }
              bootApplet = this;
              try {
                  Boot.main(new String[] { "BootApplet.init" });
              }
              catch (Exception e) {
                  throw new RuntimeException("The main method of the One-Jar Boot class threw an exception:" + e, e);
              }
          }

          private Runnable startHandler = null;
          private Runnable stopHandler = null;
          private Runnable destroyHandler = null;

          public void start() {
              if (startHandler != null) {
                  startHandler.run();
              }
          }

          public void stop() {
              if (stopHandler != null) {
                  stopHandler.run();
              }
          }

          public void destroy() {
              if (destroyHandler != null) {
                  destroyHandler.run();
              }
              bootApplet = null;
          }

          public void setStartHandler(Runnable startHandler) {
              this.startHandler = startHandler;
          }

          public void setStopHandler(Runnable stopHandler) {
              this.stopHandler = stopHandler;
          }

          public void setDestroyHandler(Runnable destroyHandler) {
              this.destroyHandler = destroyHandler;
          }
      }
      *********************************************

       

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks