JDK
Versions for MI | Import
a .war file into a new project
Mobile Infrastructure Class Loader
MI Client has its own class loader (that is, a class that implement a java.lang.ClassLoader).
This class loader takes precedence over Tomcat's class loaders. This chapter
describes
What is a Class Loader?
A class loader is an object that is responsible for loading classes. Given
the name of a class, it should attempt to locate or generate data that constitutes
a definition for the class. A typical strategy is to transform the name into
a file name and then read a "class file" of that name from a file
system.
Applications (like MI or Tomcat) implement subclasses of java.lang.ClassLoader
in order to extend the manner in which the Java virtual machine dynamically
loads classes.
 |
For more information on class loaders, please consult the Java doc for java.lang.Classloader
at http://java.sun.com.
|
Why Is MI Using its own Class Loader ?
MI Client can be looked at as the server for all mobile applications: MI
controls the entire life-cycle of a mobile application and thus installs,
starts, stops, de installs applications, synchronizes application data etc.
In order to offer these framework services, MI needs to control which application
and framework classes are loaded. As MI for JSP is based on Tomcat 3.2.4,
we need to look closely at Tomcat's class loaders to describe why Tomcat's
class loading strategy is not sufficient for MI's purposes.
In Tomcat, a class loader is created for each web application that is deployed
under <TOMCAT_HOME>/webapps. All unpacked classes and resources in the
/WEB-INF/classes directory of your web application archive, plus classes and
resources in JAR files under the /WEB-INF/lib directory of your web application
archive, are made visible to the containing web application, but to no others.
This means that the web application class loader diverges from the default
delegation model for class loaders: When a request to load a class from the
web application's class loader is processed, this class loader will look in
the local repositories first, instead of delegating before looking.
From Tomcat's perspective, MI is only another web application (and has therefore
its own sub folder <ME_HOME>/webapps/me). Tomcat would thus disallow
MI to call other web applications - this obviously makes it impossible to
offer the above-mentioned framework services. If, for example, inbound containers
for a mobile applications are received by MI, they need to be dispatched to
the application that is responsible for their processing. When Tomcat does
not allow MI to call other applications, this would obviously not work.
We can therefore say: "In order to be a framework for mobile applications,
MI needs to have its own class loader that takes precedence over Tomcat's
class loaders".
Order for Loading Classes
MI's class loader loads classes in the following sequence:
- All Java archives (.jar) described in file <ME_HOME>/listOfJars.txt
are loaded in the order in which they appear in that file. If SSL is enabled,
these classes are loaded also. The SDK tools from <JDK root>/lib/tools.jar
are also loaded.
- The class loader then loops through all applications under <ME_HOME>/webapps
and loads for each application
- the classes in /WEB-INF/classes and then
- the libraries in /WEB-INF/lib/*.jar.
The order in which the applications appear in above loop is not defined.
This load sequence has very important implications:
- MI is able to actively load classes that it needs for controlling the life-cycle
of mobile applications and be a real 'framework' for them.
- MI can be patched dynamically: As the order of jars in file <ME_HOME>/listOfJars.txt
determines the load sequence of classes, the MI patch strategy simply places
a patch at the beginning of this file. After restart of MI, the patched class
will be loaded before the old, erroneous class of the same name.
- Unlike on Tomcat, applications on MI are NOT loaded by different class loaders.
If two applications contain the same class (for example, the same class file name
for the same Java package) in different versions, that class that is loaded
first will be used by BOTH applications! As the order in which the applications
appear in the loop (see above) is not defined, application developers need
to ensure that all classes in their application have unique names (for example, by
being in a application-specific Java package).
 |
The MI classloader is only used, if MI is using
JDK 1.3.*. If MI is using JDK 1.1.8, Tomcat's class loader will be used
by MI for JSP. MI for AWT will use the JVM default class loader. This implies
that inbound containers of applications that have not yet been started will
not be processed. They will be discarded and automatically be resent by
the WebAS on next synchronization. A corresponding error message will appear
in the trace file. |
 |
MI for AWT is also using the MI class loader
(if MI is running on 1.3.*). As there is no webapps folder for AWT, all
archives are loaded in the order in which they appear in file <ME_HOME>/listOfJars.txt.
In MI for AWT, this file contains the libraries for framework and
applications. |
 |
The MI class loader does not only load classes,
but any file that can be loaded via method getResourceAsStream(),
as property files, images etc. |
Consequences for Application Development
Application developers need to be aware of the implications of the class load
sequence described above:
- MI contexts (that are the web application in the <ME_HOME>/webapps
folder or the AWT applications in the <ME_HOME>/lib folder) are NOT
separated as they are in Tomcat. If the same class (i.e. class of same package)
is used in both contexts, the behavior is undetermined.
- If two contexts are using the same class and you want to make sure that
the right version of the class is used at runtime, you need to either...
- ...uninstall one context...
To uninstall an application, you should use the MI
Web Console. This will delete the application and unregister it from
MI.
A quick-and-dirty solution is to delete the corresponding subfolder of
<ME_HOME>/webapps only. This will of course not unregister the application
from MI. The application link will then still appear in MI Home page.
- ...OR refactor the class or package.
To refactor a class or package, you can rename or move it. Refactoring
is well-supported by Eclipse: simply select the class(es) or package(s)
in the Package explorer, right-click and select Refactor... Eclipse automatically
offers to update references in source code, Javadoc comments, regular
comments or string literals.
 |
Eclipse does NOT automatically update references to
classes or packages in JSP or web.xml. They need to be adjusted
manually. |
- If you are using an MI example as template for your own MI projects and
want to deploy the example and your own application, you need to import
the example into Eclipse via the MDK Plug-In and then refactor its classes.
The simplest way here is to rename the packages into names specific for your
company, product and application. Be sure to update all references in JSP
or web.xml also!
- The "Export a Project into a .war File" function of the MDK Plug-In
creates an entry in the "Launch" framework of Eclipse so that the
application can be started also using the Eclipse command Run -> Run...
(or Debug...) -> project name. The launched class is com.sap.ip.me.mdk.api.runtime.Start
that uses the standard classloader (that means, MI for JSP, Tomcat's class
loader is used; MI for AWT will use the JVM default class loader). If you
want to use the MI classloader you can use the class com.sap.ip.me.mdk.api.runtime.StartMCL
to launch your application. The MI classloader has only an effect, when you
use a JVM Version 1.3.
- If MI is patched, be sure to update the build path for your Eclipse project
so that Eclipse loads the MI libraries in the same order as MI does (use file
<ME_HOME>/listOfJars.txt for reference). You can use the MDK
Plugin to do that. Select a project in the navigator view, press the right
mouse button und select Properties - MDK. By just confirming the MDK Project
Properties menu with OK, the classpath is updated according to file <ME_HOME>/listOfJars.txt.