Showing posts with label OSGI. Show all posts
Showing posts with label OSGI. Show all posts

Saturday, 19 May 2007

WAS Startup and Eclipse/OSGI

I couldn't update the blog last night because I was working late - a distinct lack of Java programmers in a building of 1200 people!

To really understand what goes on with the WAS internals and how Eclipse/OSGI fits in we have to examine the startup. So, lets look first at startServer.sh in /usr/IBM/WebSphere/AppServer. In here we will find references to com.ibm.wsspi.bootstrap.wsLauncher, which used to be wsBootstrap in earlier was implementations:

...
"$JAVA_HOME"/bin/java \
"$OSGI_INSTALL" "$OSGI_CFG" \
$X_ARGS \
$WAS_DEBUG \
$CONSOLE_ENCODING \
$D_ARGS \
-classpath "$WAS_CLASSPATH" \
$USER_INSTALL_PROP \
$JVM_EXTRA_CMD_ARGS \
com.ibm.ws.bootstrap.WSLauncher \
$SHELL "$CONFIG_ROOT" "$WAS_CELL" "$WAS_NODE" "$@" $WORKSPACE_ROOT_PROP
...

The $SHELL variable refers to the management tools, (JMX?) that we will look at one another day i.e.

# Bootstrap values ...
SHELL=com.ibm.ws.management.tools.WsServerLauncher

The other environment variables refer to the configuration for the given profiles, i.e. the XML files (server.xml, serverindex.xml, etc).

In the past the bootstrap class used to check for license information, setup platform specific configuration for iSeries and zOS, and then used to load the WAS runtime, but the key change now is the relationship with OSGI/Eclipse.

To explore further just jar the file that contains the plug for com.ibm.ws.bootstrap.WSLauncher, i.e. go to the plugins directory and open up com.ibm.ws.bootstrap_6.1.0.jar. Look at the structure created and open up plugin.xml.

created: META-INF/
extracted: META-INF/MANIFEST.MF
created: com/
created: com/ibm/
created: com/ibm/ws/
created: com/ibm/ws/bootstrap/
created: com/ibm/ws/extension/
created: com/ibm/ws/extension/thinregistry/
created: com/ibm/ws/runtime/
created: com/ibm/ws/runtime/service/
created: com/ibm/ws/runtime/service/impl/
created: com/ibm/wsspi/
created: com/ibm/wsspi/bootstrap/
created: com/ibm/wsspi/bootstrap/osgi/
created: com/ibm/wsspi/extension/
created: com/ibm/wsspi/runtime/
created: com/ibm/wsspi/runtime/service/
created: schema/
inflated: com/ibm/ws/bootstrap/ClassLoaderGateway$1.class
inflated: com/ibm/ws/bootstrap/ClassLoaderGateway$2.class
inflated: com/ibm/ws/bootstrap/ClassLoaderGateway$3.class
inflated: com/ibm/ws/bootstrap/ClassLoaderGateway.class
inflated: com/ibm/ws/bootstrap/ProtectionMetaData.class
inflated: com/ibm/ws/extension/ExtensionRegistryFactoryImpl.class
inflated: com/ibm/ws/extension/thinregistry/ConfigurationElement.class
inflated: com/ibm/ws/extension/thinregistry/ConfigurationProperty.class
inflated: com/ibm/ws/extension/thinregistry/Constants.class
inflated: com/ibm/ws/extension/thinregistry/Extension.class
inflated: com/ibm/ws/extension/thinregistry/ExtensionPoint.class
inflated: com/ibm/ws/extension/thinregistry/ExtensionRegistry.class
inflated: com/ibm/ws/extension/thinregistry/PluginDescriptor.class
inflated: com/ibm/ws/extension/thinregistry/PluginModelObject.class
inflated: com/ibm/ws/extension/thinregistry/PluginParser.class
inflated: com/ibm/ws/extension/thinregistry/RegistryLoader$1.class
inflated: com/ibm/ws/extension/thinregistry/RegistryLoader.class
inflated: com/ibm/ws/extension/thinregistry/RegistryResolver.class
inflated: com/ibm/ws/extension/thinregistry/ResourceHelper.class
inflated: com/ibm/ws/extension/thinregistry/Status.class
inflated: com/ibm/ws/runtime/service/impl/BundleContextMap.class
inflated: com/ibm/wsspi/bootstrap/InvocationHandler.class
inflated: com/ibm/wsspi/bootstrap/WSLauncher.class
inflated: com/ibm/wsspi/bootstrap/osgi/WsBundleActivator.class
inflated: com/ibm/wsspi/extension/ExtensionRegistryFactory$Implementation.class
inflated: com/ibm/wsspi/extension/ExtensionRegistryFactory.class
inflated: com/ibm/wsspi/runtime/service/WsServiceRegistry$1.class
inflated: com/ibm/wsspi/runtime/service/WsServiceRegistry$2.class
inflated: com/ibm/wsspi/runtime/service/WsServiceRegistry.class
inflated: plugin.xml
inflated: schema/applications.exsd
inflated: schema/invocationHandler.exsd

The directory structure shows classnames that relate to a lightweight Eclipse Extension Registry manager and an Eclipse OSGI application, particularly the WsBundleActivator that provides the OSGI start and stop methods as in Eclipse RCP applications, the Service registry for registering services as for OSGI, and the Extension, ExtensionPoint, ExtensionRegistry, and RegistryLoader classes. So, starting with plugin.xml:

...
<extension
id="WSLauncher"
point="org.eclipse.core.runtime.applications">
<application>
<run class="com.ibm.wsspi.bootstrap.WSLauncher"/>
</application>
</extension>

<extension-point id="applications" name="applications" schema="schema/applications.exsd"/>
<extension-point id="invocationHandlers" name="InvocationHandlers" schema="schema/invocationHandler.exsd"/>
<extension-point id="manual-bundle-start" name="Manual Bundle Starter"/>
<extension-point id="resource-file" name="Resource File"/>
...

Yes, WAS is basically like an RCP application in that extends org.eclipse.core.runtime.applications. The class that extends this is com.ibm.wsspi.bootstrap.osgi.WsBundleActivator, and like all "plugins"/RCP applications that extend this and implement the BundleActivator interface the class must provide start() and stop() methods that receive BundleContext objects to interoperate with the Eclipse/OSGI runtime. These methods in the world of OSGI are usually used to initiate the registration and running of services, which is where the WSServiceRegistry classes we unzipped above come in. Ahh, but we've jumped ahead..... This is how it works in the case of an Eclipse RCP or OSGI application as outlined in books like "Eclipse Rich Client Platform", but what loads the Eclipse/OSGI runtime and how do we get to the WsBundleActivator from WSLauncher? Well, the WSLauncher class has a main method, that does all of the argument and license checking functions of earlier releases of WAS, but then checks to see if it is running inside an Eclipse runtime, and if it isn't it creates its own thin, lightweight runtime and runs its extensions and plugins upon it. It then offers up its own extension points as seen in the plugin.xml file.

So, it seems to me that WAS is essentially similar to an Eclipse RCP/OSGI application, but if has both a full Eclipse 3.1.2 runtime and a lightweight one, and applications can use JNDI to provide further plugin services that extend the exposed extesnion points. This new implementaion allows IBM to easily extend WAS and to even support multiple versions. Its a nice architecture...

To get a better understanding read the following books:

  • The Java Developers Guide to Eclipse - D'Anjou et al

  • Eclipse Rich Client Platform - McAffer et al

  • Eclipse: Building Commercial Quality Plugins - Clayberg et al

  • Official Eclipse 3.0 FAQs - Barry etc al


  • They are all good books! However, play with code and write something with it. Just even using the wizards to create a simple osgi plugin is useful, as code can be put into the start() and stop() methods of your BundleActivator class and with a simple change to the config.ini and a start clause and you can have the WAS startup outlined above load your own code as an extension of WAS! This is really powerful and can be used to extend WAS even into the base OS!

    Well, goodnight for now. I'll cover more soon in the next installment!

    Wednesday, 16 May 2007

    More on WAS

    You can learn a lot about how things work by really delving into the documentation for WAS. How to use the Eclipse Extension support is all documented, i.e. use JNDI to get access to the EclipseRegistry.

    However, looking at the XML, config and manifest files is also telling. There is also a reason why an OSGIConsole script is supplied with WAS now. If you jar xvf some of the plugins, like the main com.ibm.ws.runtime_6.1.0.jar you can learn a lot by looking at the MANIFEST.MF file that follows an Eclipse/OSGI pattern, i.e.

    Bundle-Activator: com.ibm.ws.runtime.component.RuntimeBundleActivator
    Bundle-Localization: plugin
    Bundle-ManifestVersion: 2
    Bundle-Name: WS_Server
    Bundle-SymbolicName: com.ibm.ws.runtime; singleton:=true
    Bundle-Vendor: IBM
    Bundle-Version: 6.1.0
    Eclipse-AutoStart: false
    J2EE-DeploymentFactory-Implementation-Class: com.ibm.ws.management.app
    lication.j2ee.deploy.spi.factories.DeploymentFactoryImpl
    Manifest-Version: 1.0
    Require-Bundle: com.ibm.ws.bootstrap; visibility:=reexport,
    org.eclipse.jdt.core
    DynamicImport-Package: com.ibm.etools.application,
    com.ibm.etools.application.impl,
    com.ibm.etools.application.util,
    com.ibm.etools.client,
    com.ibm.etools.client.impl,
    com.ibm.etools.client.util,
    ...
    Import-Package: com.ibm.ejs.models.base.bindings,
    com.ibm.ejs.models.base.bindings.applicationbnd,
    com.ibm.ejs.models.base.bindings.applicationbnd.impl,
    com.ibm.ejs.models.base.bindings.applicationbnd.util,
    com.ibm.ejs.models.base.bindings.clientbnd,
    com.ibm.ejs.models.base.bindings.clientbnd.impl,
    com.ibm.ejs.models.base.bindings.clientbnd.util,
    ...
    org.eclipse.xsd.util,
    org.osgi.framework,
    org.osgi.service.condpermadmin,
    org.osgi.service.packageadmin,
    org.osgi.service.permissionadmin,
    org.osgi.service.startlevel,
    org.osgi.service.url,
    org.osgi.util.tracker
    Export-Package: com.ibm.CBUtils; x-internal:=true,
    com.ibm.CORBA.services.redirector; x-internal:=true,
    com.ibm.CORBA.services; x-internal:=true,
    com.ibm.CSIv2Security; x-internal:=true,
    ...

    Note that BundleActivator. Note also that the bootstrap is re-exported, most other underlying library services are also re-exported, and that the main underlying runtime is a singleton. I believe it works like this....

    The Eclipse 3.1.2 runtime starts up and loads com.ibm.ws.runtime plugin after the updater has been loaded. This runtime provides the base services used by the rest of the app server, and is monolithic but well architected to provide true runtime services for use of the web container, ejb container, etc. Each of the rest of functional components and containers then sit on top of this runtime.

    Containers such as the SIP container are true plugins that make use of the com.ibm.ws.runtime extension points and services. This container even has an OSGI Activator of its own that subclasses the WsBundleActivator.

    All of this would make sense in allowing the feature packs and future extensions to be just added on top of the original code. This is really extensible.

    Still, I will continue digging and add to this blog....