The Source for Java Technology Collaboration


Dual Stack Support

Goals

  • Isolate the CLDC/MIDP programs (MIDlets) from CDC/FP classes and methods that should not be visible to them.
  • Allow the CLDC/MIDP programs to use CLDC APIs which are not part of CDC/FP (because of version differences), as well as MIDP APIs which are not part of CDC/FP at all.
  • Isolate CDC/FP/PP code (applications and applets) from these additional interfaces, allowing one to run multiple threads requiring different APIs at the same time.
  • The sharing of the implementation of java.* package classes.

How Classloaders Implement API Hiding

MIDP API hiding is implemented using two special-purpose class loaders: sun.misc.MIDletClassLoader and sun.misc.MIDPImplementationClassLoader. Their exact parameters are established by sun.misc.MIDPConfig class:

/*
 * Use the default midlet permission collection to create a MIDletClassLoader.
 * The parent is set to the MIDPImplementationClassLoader.
 */
public static MIDletClassLoader
newMIDletClassLoader(String midPath[])

/*
 * This version allows the caller to specify a set of permissions when
 * creating MIDletClassLoader. The parent is set to the 
 * MIDPImplementationClassLoader.
 */
public static MIDletClassLoader
newMIDletClassLoader(String midPath[],
                     PermissionCollection perms)

/*
 * Set up the MIDPImplementationClassLoader.
 */
public static MIDPImplementationClassLoader
newMIDPImplementationClassLoader(File files[])

Above API's should be used to create the MIDletClassLoader? and MIDPImplementationClassLoader?.

These class loaders implement hiding on two levels:

* References by MIDlets to illegal members of otherwise legal classes are caught by the MIDletClassLoader? when the offending class is loaded. * References by MIDlets to classes not part of CLDC/MIDP are caught by the MIDPImplementationClassLoader? lazily, when the class lookup occurs.

Configuration Files

The legal classes and members that are allowed to be access by MIDlets are configurable. The src/share/lib/dualstack/[cldc/midp]/MIDPPermittedClasses.txt contains all visible classes for MIDlets. The src/share/lib/dualstack/[cldc/midp]/MIDFilterConfig.txt lists all the visible class members. The configuration files are generated offline using a cldc class zip (from a cldc binary) as the input using the following build command:

/usr/bin/make USE_MIDP=true \
TOOLS_DIR=/home/developer/svn/phoneme-adv/tools/trunk \
PCSL_DIR=/home/developer/svn/phoneme-adv/pcsl/trunk \
MIDP_DIR=/home/developer/svn/phoneme-adv/midp/trunk \
CVM_PRELOAD_LIB=true \
J2ME_CLASSLIB=foundation \
CVM_MIDPFILTERINPUT= \
gen_member_filter

Both the cldc and midp configuration files contains the same CLDC classes and members (methods and fields). The midp configurations have additional 13 classes. Please see Shared CDC and MIDP Classes section for details.

At build time the configuration files are copied to the lib/ directory. At runtime during system start up, the VM reads the class and method list from the configuration files, the classloaders check against the lists to determine if an access can be granted for midlet.

MIDletClassLoader?

The MIDletClassLoader? is a subclass of java.net.URLClassLoader. It is used to load midlet classes. It will prevent loading of certain packages (java.lang, java.io, java.util and javax.microedition) from the JAR, as required by the MIDP specification. It also prevents the loading of any class which contains a reference to a class member such that:

  • the class is in both CDC/FP and in CLDC/MIDP, but
  • the particular member is in CDC/FP but not in CLDC/MIDP

It does this with the assistance of an instance of class sun.misc.MemberFilter. The MemberFilter? code (much of it native) will inspect a class's constant pool during class loading, and report on any illegal member references found. The MemberFilter? is also configured by the MIDPConfig class.

When the MIDletClassLoader? is called to load a class:

  1. Check if the class has already be loaded. If the class is already loaded, return the class. Otherwise continue to the next step;
  2. Check package name. If the package name starts with java.lang, java.io, java.util or javax.microedition, loadClass fails;
  3. Search the MIDlet JAR for the requested class. If the class is found, look into the class' constant pool for any illegal access and mark the entry as illegal if it found any. The loadClass secceed even illegal access if found in the class' constant pool; Later during constant resolution and opcode quicken time the illegal access will be reported. If the class is not found, continue to the next step;
  4. Delegate classloading to the MIDPImplementationClassLoader?. If the class is not found, throws ClassNotFoundException?. Otherwise loadClass succeed.

The MIDletClassLoader? also restricts which resources are available to the MIDlet: items out of its own JAR which are not .class files.

MIDPImplementationClassLoader?

MIDPImplementationClassLoader? should be set up as the parent class loader of the MIDletClassLoader?. The NULL classloader should be set up as the parent class loader of the MIDPImplementationClassLoader?. The MIDPImplementationClassLoader? is also a subclass of the URLClassLoader?.

MIDPImplementationClassLoader? is used to load MIDP library classes.

When MIDlet classes reference to unloaded system classes (MIDP or CLDC classes), the MIDletClassLoader? delegates to the MIDPImplementationClassLoader? by calling MIDPImplementationClassLoader?'s loadClass(). It calls loadClass() with an extra flag indicating that a restricted namespace is to be used and only MIDP and CLDC classes are permitted. This restriction is essential because MIDlet classes is not allowed to access CDC/Foundation classes that are not part of the CLDC specification. This restriction however does not apply to MIDP library classes. That means if MIDPImplementationClassLoader?.loadClass() is called due to references from MIDP library classes, the restrict flag is not set. That is because MIDP classes are allowed to access all CDC/Foundation classes.

When the MIDPImplementationClassLoader? is called to load a class:

  1. Check if the class has already be loaded. If the class is already loaded, return the class. Otherwise continue to the next step;
  2. If this is not a restricted lookup (such as a request from within the implementation JAR itself) then the request is passed to the parent class loader. The parent class loader tries to load the class. But if the restricted flag is set (meaning the request started in a MIDlet class), then a list of allowed classes is consulted. If the requested class is not on the allowed list, the lookup fails and ClassNotFoundException? will be thrown. If the class is on the allowed list, the request is passed to the parent class loader. If the class is loaded by the parent classloader, then loadClass succeed;
  3. It looks for the requested class in its own JAR. If the class is present, it can be loaded successfully. Otherwise, loadClass fails with ClassNotFoundException?.

Notes on Classloaders and Sharing

If a single MIDPImplementationClassLoader? is shared by the whole MIDP implementation, global state can be easily shared, and there will be no duplication of class representation in memory. This is absolutely the preferred method.

If a single MIDletClassLoader? is shared by all the members of a MIDlet suite, then they can easily share global state, but MIDlet suites will not contaminate one another. This is the desired, if not required, behavior.

How Should tClassloaders Be Used by AMS

AMS is responsible for creating both MIDletClassLoader? and MIDPImplementationClassLoader?. During the system startup, the AMS should:

  1. Create MIDPImplementationClassLoader? by calling sun.misc.MIDPConfig.newMIDPImplementationClassLoader().
  2. Create MIDletClassLoader? by calling sun.misc.MIDPConfig.newMIDletClassLoader(). MIDPImplementationClassLoader? is the default parent classloader of the MIDletClassLoader?.

For examples, please see sr/share/javavm/test/dualstack/com/sun/javax/microedition/midlet.

MIDPLauncher

The sun.misc.MIDPLauncher is a standalone class. It is not part of the MIDP library. The launcher processes the comment-line arguments and creates the MIDPImplementationClassLoader?. It loads com.sun.midp.main.MIDletSuiteLoader using the MIDPImplementationClassLoader? and invokes it's main() method. The MIDletSuiteLoader? is the main MIDP library class. The midlet classes are loaded by the MIDletClassLoader?, which is created by MIDP library (MIDletStateHandler? class).

To use the MIDPLauncher:

bin/cvm sun.misc.MIDPLauncher -midppath -suitepath midletID midletName

Shared CDC and MIDP Classes

There are 13 classes exist in both CDC and MIDP spec. Instead of providing it's own implementation, MIDP uses the classes from CDC (foundation.jar or basis.jar). Thses classes are excluded from midpclasses.zip. At runtime, thses classes are loaded by the null classloader. In order to allow midlet access the shared classes, they need to be added to the midp configuration files (MIDPFilterConfig?.txt and MIDPPermittedClasses?.txt).

Following are the 13 classes:

java.lang.IllegalStateException
java.util.Timer
java.util.TimerTask
javax.microedition.pki.Certificate
javax.microedition.pki.CertificateException
javax.microedition.io.CommConnection
javax.microedition.io.HttpConnection
javax.microedition.io.HttpsConnection
javax.microedition.io.SecureConnection
javax.microedition.io.SecurityInfo
javax.microedition.io.ServerSocketConnection
javax.microedition.io.SocketConnection
javax.microedition.io.UDPDatagramConnection

Above classes will be in a separate midpexcludedclasses.zip in the lib/ directory.

CLDC and MIDP Signature Test

The CLDC and MIDP signature tests check the jar file contents statically. Therefore, we cannot use foundation.jar for the signature tests. For the CLDC signature test, the cldc class zip file should be used. For the MIDP signature test, the cldc class zip + midpclasses.zip + midpexcludedclasses.zip will be used. That cldc class zip file is copied from a CLDC 1.1 RI binary and is the input for generating the API hiding configuration lists.

Supporting JSR Optional Packages on CDC

CDC and MIDP share the same implementation of JSROPs (such as JSR 75, JSR 82, JSR 135...). Some of the JSROPs are only visible to midlets but not to CDC applications (xlet, main application...). To hide the non-visible JSROPS, sun.misc.CDCAppClassLoader is created. ALL JUMP classloaders extend from it. CDCAppClassLoader? reads a configuration file (lib/ JSRRestrictedClasses?.txt) that contains prohibited JSROP class names and creates a hashset using the class names. The loadClass() method of sun.misc.CDCAppClassLoader checks with the hashset and throws ClassNotFoundException? if the requested class is in the set. The configuration file (lib/ JSRRestrictedClasses?.txt) is generated at build time using the APILister tool. HIDE_ALL_JSRS=true means all JSRs are hidden from CDC and all JSROP classes are added to the configuration file. That is the default setting. HIDE_JSR_<#>=true can be used to specify which specific JSROPs should be hidden.

On the other side, during build time if USE_JSR_<#> is specified, all public classes in the JSR are added to the MIDPPermittedClasses?.txt to allow midlet access.

Topic PhoneMEAdvancedCVMDualStack . { Edit | Ref-By | Printable | Diffs r1 | More }
 XML java.net RSS

Revision r1 - 16 Dec 2008 - 21:07:05 - Main.dbsears
Parents: WebHome > PhoneMEAdvanced