Container startup
Previously, in 5.4.4, WebSphere Application Server - startup and operation, you examined the first part of the WebSphere Application Server startup sequence, which involved shell scripts and the Eclipse/OSGI/Equinox runtime, and learned how this starts the WebSphere Application Server runtime. This sections examines how the WebSphere Application Server runtime startup creates the containers that form the basis of J2EE.
It is important to understand is that the core Eclipse/OSGI model is used extensively during the startup of the containers. Essentially, common code is provided in the WsContainer/ContainerImpl and WsComponent classes.
The ContainerImpl class is an implementation class that loads the WsComponent derived classes described in the com.ibm.ws.runtime_6.1.0.jar plugin.xml file for the given container, and maps the appropriate threads, transports and other runtime artifacts to the given environment. The target container that is being started is passed to the WsContainer/ContainerImpl implementation by the caller.
First, the core server environment itself is started up (that is, the management and runtime infrastructure). Then the appserver containers are started. This can be seen in the stacks we saw earlier, which are displayed again here in Example 5-58, Example 5-59, and Figure 5-15.
Example 5-58 WebSphere Application Server component startup
at com.ibm.ws.runtime.component.ContainerImpl.startComponents(ContainerImpl.java:977) at com.ibm.ws.runtime.component.ContainerImpl.start(ContainerImpl.java:673) at com.ibm.ws.runtime.component.ApplicationServerImpl.start(ApplicationServerImpl.java:1 91) at com.ibm.ws.runtime.component.ContainerImpl.startComponents(ContainerImpl.java:977) at com.ibm.ws.runtime.component.ContainerImpl.start(ContainerImpl.java:673) at com.ibm.ws.runtime.component.ServerImpl.start(ServerImpl.java:485) at com.ibm.ws.runtime.WsServerImpl.bootServerContainer(WsServerImpl.java:191) at com.ibm.ws.runtime.WsServerImpl.start(WsServerImpl.java:139) at com.ibm.ws.runtime.WsServerImpl.main(WsServerImpl.java:460)
Example 5-59 continues the component startup display.
Example 5-59 WebSphere Application Server component startup
at com.ibm.ws.runtime.component.ContainerImpl.initializeComponent(ContainerImpl.java:133 8) at com.ibm.ws.runtime.component.ContainerImpl.initializeComponents(ContainerImpl.java:11 36) at com.ibm.ws.runtime.component.ServerImpl.initialize(ServerImpl.java:347) at com.ibm.ws.runtime.WsServerImpl.bootServerContainer(WsServerImpl.java:177) at com.ibm.ws.runtime.WsServerImpl.start(WsServerImpl.java:139) at com.ibm.ws.runtime.WsServerImpl.main(WsServerImpl.java:460) at com.ibm.ws.runtime.WsServer.main(WsServer.java:59)
Figure 5-15 WebSphere Application Server container startup
Each component named in the appropriate section of the plugin.xml file related to the given container is initialized individually by the ContainerImpl class.
Now consider the two core containers. The EJB container is based around a CORBA ORB core and uses IIOP as a transport, with a requirement for thread pool management to handle multiple concurrent remote EJB requests. The Web container is based around a servlet engine core that uses HTTP as a transport, with a requirement for thread pool management to handle multiple concurrent HTTP requests. The commonality is why the mapping is done using the same core implementation to map configurations of containers, transports, and components in the plugin.xml file.
In the Web container, com.ibm.wsspi.runtime.component.WsContainer/ContainerImpl starts up a number of components (that support the com.ibm.wsspi.runtime.WsComponent interface) for the given container. The components are themselves Eclipse plug-ins. The extension registry is enumerated to find them. When they are loaded, the service registry is also used.
The extensions and extension points are enumerated to get their configuration information (that is, startup order, platform, recovery information, and so on), and then they are sorted on the startup order information and started (using the start method for each component), with a preference for asynchronous startup if the component supports it. The WsContainer class can also start, stop, and initialize the components.
When the Web container starts up, it has a default response buffer size of 32 K but reads its configuration to resize this response buffer size. It also sets up a fixed size pool of 100 WCChannelLinks to represent each virtual connection, so this is a hard limit. These are inbound request/response connections only.
Each WCChannelLink uses underlying classes and services to read the request, process it, and respond. However, it tries to do as much asynchronously as possible to minimize latency and resource constraints. The underlying methods favored by servlet coders eventually map to the WCCRequestImpl and WCCResponseImpl classes for handling, where they read and write the underlying request and response streams. At a higher level the servlet classes and methods themselves are mapped to the classes in com.ibm.ws.http.* package classes that implement the standard classes. This is all controlled in the com.ibm.ws.webcontainer.channel.WCChannel class.
The com.ibm.ws.http.HTTPServer class sets up a thread pool and an object pool of connections, and then does all of the things normally expected of a Web server in responding to connections. This is the internal HTTP server for representing J2EE JSP and servlet-based Web applications that must be fronted by a separate HTTP server process for support and security reasons. The HttpTransport class does a significant amount of the underlying work.
The com.ibm.ws.http.channel.impl.HttpChannelConfig reads the HTTP setup parameters, which are distinct from those of the Web container it runs on, and sets those up.
The channel factory makes use of the underlying TCP connection factory in com.ibm.wsspi.tcp.channel to get its environment. The com.ibm.ws.http.channel package classes make use of the com.ibm.wsspi.http.channel and com.ibm.wsspi.tcp.channel implementations to do the real work, using the strategy pattern interface which is seen throughout the WebSphere Application Server code.
The com.ibm.ws.tcp.channel.impl package code again uses the underlying implementation in the equivalent wsspi classes, but makes use of Asynchronous IO wherever possible, and using native platform code if available.
So, how is all of this related? The XML file used to start the containers from WsServerImpl starts the WsContainer/ContainerImpl containers that load the components using the extension registry mentioned. The containers load a component manager that uses the name of the subsystem to load the appropriate configuration section from the plugin.xml file for that subsystem, and then enumerate the "component" entries to load each component within it.
So, the base server that provides basic policy-less services (like the thread pool manager, the HAManager, the EndPoint Manager, and so on) loads the components in the section com.ibm.wsspi.extension.server-startup. One of these is the Application Server subsystem, which starts loading as a result of the entry in this Server subsystem configuration.
Then the core appserver services that provide the Web services support, the core object pool, the dynacache, the extension registry, and the EJBContainer environment, are loaded using the configuration in the com.ibm.wsspi.extension.application-server.startup section to identify and load the components from that environment in the appropriate order.
The EJB container starts loading at this point in the same way as it is named as a component in this section, and starts immediately after the client services startup. The EJB container is followed by the HA Manager subsystems (Group Manager, Agent, and so on), the Web container, the scheduler service, and finally the administration service (JMX connectors and the plug-in configuration service for the Web server plug-in).
The overall components that a WebSphere Application Server instance loads and runs are listed in com.ibm.wsspi.extension.server-components.
These details are all held in the com.ibm.ws.runtime_6.1.0.jar plugin in the plugin.xml file.
Figure 5-16 WebSphere Application Server containers
First, the base runtime services identified by the extension point com.ibm.wsspi.extension.server-startup are started by enumerating the components within that grouping. Although most platforms use a single JVM process to run WebSphere Application Server, z/OS uses multiple processes called servants, controls, and adjuncts to emulate the standard J2EE behavior. So, the processType attribute is used to tell the environment how the different components should be started on the z/OS platform (although this is irrelevant to distributed platforms such as AIX).
The platform attribute identifies components that should only be run on specific platforms such as z/OS, and for AIX, the distributed value or absence of the attribute identifies what is loaded. The startup attribute identifies the order in which the components load, with the lowest value loading first.
The recoveryType attribute is another z/OS-specific artifact. Note that there are also iSeries-specific components, showing that although the zSeries and iSeries core WebSphere Application Server shipped binaries are the same, the code that is run is not the same as the other platforms; see Example 5-60.
Example 5-60 Base runtime services startup: lower level components
<extension point="com.ibm.wsspi.extension.server-startup"> <components> <component startup="1000" class="com.ibm.ws.runtime.component.VirtualHostMgrImpl" platform="zos" processType="Control"/> <component startup="1999" class="com.ibm.ws.runtime.component.ThreadMonitorImpl" recoveryType="Control,Servant"/> <component startup="2000" class="com.ibm.ws.runtime.component.EndPointMgrImpl" recoveryType="Control,Servant"/> <component startup="2000" class="com.ibm.ws.runtime.component.ThreadPoolMgrImpl" type="services/threadpoolmanager.ThreadPoolManager" configurationDataRequired="false" recoveryType="Control,Servant"/> <component startup="2000" class="com.ibm.ws.runtime.component.TransportChannelLoaderImpl" platform="distributed,os400"/> ... <component startup="5000" type="services/orb.ObjectRequestBroker" recoveryType="Control,Servant"/> <component startup="5400" class="com.ibm.ws.hamanager.proxy.ProxyImpl" platform="zos" processType="Adjunct,Servant"/> <component startup="5400" class="com.ibm.ws.hamanager.runtime.CoordinatorComponentImpl" processType="Control"/> <component startup="5500" class="com.ibm.ws.management.component.MBeanActivationImpl" platform="zos" recoveryType="Control"/> ... <component startup="6600" type="services/applicationserver.DynamicCache" processType="Control"/> ... <component startup="13000" class="com.ibm.ws.odc.bb.BBMgr" processType="Control,Servant"/> <component startup="13010" class="com.ibm.ws.odc.ws390.proxy.ODCProxyManager" processType="Control,Servant"/> <component startup="13500" class="com.ibm.ws390.jfap.JFAPProxyComponentImpl" platform="zos" processType="Control"/> <component startup="14000" class="com.ibm.ws.dwlm.client.DWLMClientImpl" processType="Control,Servant"/> <component startup="14500" class="com.ibm.ws.cache.drs.ws390.ControllerCacheServiceImpl" platform="zos" processType="Control"/> <component startup="15000" class="com.ibm.ejs.container.drs.ws390.SfControllerServiceImpl" platform="zos" processType="Control"/> <component startup="15000" class="com.ibm.ws.messaging.component.JmsAdminService" processType="Adjunct,Servant"/> ... <component startup="25000" class="com.ibm.ws.runtime.component.TxServiceImpl" platform="zos" processType="Control" recoveryType="Control"/> <component startup="100000" class="com.ibm.ws.taskmanagement.mapper.TaskManagementServiceMapper" processType="Control"/> <component startup="100100" class="com.ibm.ws.taskmanagement.task.TaskManagementMBean" processType="Control"/> <component startup="999999" class="com.ibm.ws.wim.management.UserManagementProcess"/> <component startup="2147483647" class="com.ibm.ws.runtime.component.WLCImpl" platform="distributed,os400"/> <component startup="2147483647" class="com.ibm.ws.soapchannel.monitor.component.SOAPMonitorChannelComponentImpl" platform="zos" processType="Control"/> </components> </extension>
After the base runtime lower level support components have been loaded, the appserver container itself is loaded. This provides the generic container level services that the J2EE containers (such as the Web and EJB containers) use and sit within.
This is identified by the com.ibm.wsspi.extension.applicationserver-startup section of the plugin.xml file. The processType, platform, and startup attributes have the same meaning as before; see Example 5-61.
Example 5-61 Base runtime services startup: appserver container
<extension point="com.ibm.wsspi.extension.applicationserver-startup"> <components> <component startup="1000" type="objectpoolservice.ObjectPoolService" processType="Adjunct,Servant"/> <component startup="1000" class="com.ibm.ws.runtime.component.MetaDataMgrImpl" processType="Adjunct,Servant"/> <component startup="1000" class="com.ibm.ws.runtime.component.VirtualHostMgrImpl"/> <component startup="1001" class="com.ibm.ws.wccm.services.pme.metadata.impl.MetaDataHelperServiceImpl" processType="Adjunct,Servant"/> ... <component startup="5000" class="com.ibm.ws.webservices.component.WSServerImpl"/> ... <component startup="6600" type="services/applicationserver.DynamicCache" processType="Servant"/> <component startup="6800" class="com.ibm.wkplc.extensionregistry.wasservice.ExtensionRegistryService"/> <component startup="7000" type="components/applicationserver.ejbcontainer.EJBContainer" processType="Adjunct,Servant"/> ... <component startup="8700" class="com.ibm.ws.runtime.component.ThreadPoolImpl" processType="Adjunct,Servant"/> <component startup="9000" type="components" processType="Adjunct,Servant"/> <component startup="10000" class="com.ibm.ws.performance.tuning.serverAlert.ServerRuleDriverMBean" processType="Servant"/> <component startup="10000" class="com.ibm.ws.runtime.component.ApplicationMgrImpl" processType="Adjunct,Servant"/> <component startup="10000" class="com.ibm.ws.runtime.component.LibraryMgrImpl"/> <component startup="10001" class="com.ibm.ws.cluster.runtime.ApplicationServerRuntimeImpl" processType="Adjunct,Servant"/> ... <component startup="99999" class="com.ibm.ws.wccm.services.pme.PMECheckServerConfigService" processType="Adjunct,Servant"/> </components> </extension>
As illustrated in Example 5-62, the EJB container startup configuration shows that the EJB container code does not have any additional extensions to run beyond the code in com.ibm.ws.runtime_6.1.0.jar file and the separate com.ibm.ws.ejbportable_6.1.0.jar file that extends this.
Example 5-62 EJB container startup
<extension point="com.ibm.wsspi.extension.ejbcontainer-startup"> <components> <component startup="1000" type="services" /> </components> </extension>
The com.ibm.ws.ejbportable_6.1.0.jar file does not have its own plugin.xml file, but it does not need one. As shown in Example 5-63, its MANIFEST.MF file identifies itself as a singleton, as would be expected. However, it uses the Fragment-Host attribute to identify itself as an extension of the base WebSphere Application Server com.ibm.ws.runtime_6.1.0.jar bundle, so the plugin.xml file from that applies.
Example 5-63 EJB container manifest
Bundle-Localization: fragment Bundle-ManifestVersion: 2 Bundle-Name: ejbportable Bundle-SymbolicName: com.ibm.ws.ejbportable; singleton:=true Bundle-Vendor: IBM Bundle-Version: 6.1.0 Fragment-Host: com.ibm.ws.runtime; bundle-version=6.1.0
The Web container can support additional components for JSF and JSP, but currently this configuration is commented out in the plugin.xml file for the WebSphere runtime. So again, it would appear that only the base code in com.ibm.ws.runtime_6.1.0.jar and the com.ibm.ws.webcontainer_2.0.0.jar file that extends this are used.
However, examination of the plugin.xml file for the com.ibm.ws.webcontainer_2.0.jar file shows, in Example 5-64, that these components and their startup have been copied to this file and uncommented. With future Web services implementations, this is likely to be a heavily used configuration item in future WebSphere Application Server releases.
Example 5-64 webcontainer_2.0.jar in plugin.xml
com.ibm.ws.runtime_6.1.0.jar...
<!-- extension point="com.ibm.wsspi.extension.webcontainer-startup"> <components> <component startup="2000" type="services" /> <component startup="2147483647" class="com.ibm.ws.jsf.extprocessor.JSFComponentImpl" /> <component startup="2147483647" class="com.ibm.ws.jsp.runtime.JspComponentImpl" /> </components> </extension -->com.ibm.ws.webcontainer_2.0.0.jar...
<extension point="com.ibm.wsspi.extension.webcontainer-startup"> <components> <component startup="2000" type="services" /> <component startup="2147483647" class="com.ibm.ws.jsf.extprocessor.JSFComponentImpl"/> <component startup="2147483647" class="com.ibm.ws.jsp.runtime.JspComponentImpl" /> </components> </extension>
Other extensions for extension clients and the scheduler service are similarly configured to these containers. Most importantly, from the perspective of WebSphere Application Server, Network Deployment is the HAManager configuration. Without HAManager and the Distributed Replication Services, WebSphere Application Server ND has the same functionality as the standalone WebSphere Application Server base (although the management is still different.)
The Group Manager, Agent Factory and Bulletin Board Factory components are key to keeping the cluster functioning as a single entity with appropriate failover of singleton components and resilience; see Example 5-65.
Example 5-65 Extension for HAManager startup in plugin.xml
<extension point="com.ibm.wsspi.extension.hamanager-startup"> <components> <component startup="5401" class="com.ibm.ws.hamanager.runtime.GroupManagerComponentImpl" /> <component startup="5402" class="com.ibm.ws.hamanager.runtime.AgentFactoryComponentImpl" /> <component startup="5403" class="com.ibm.ws.hamanager.runtime.BulletinBoardFactoryComponentImpl" /> </components> </extension>
The com.ibm.wsspi.extensionXXXXX startups bring the thread pools and object pools into life, as well as the TCP transport channel loader. When this is loaded, the extension class framework configuration in the plugin.xml file is used to relate the configuration, interface, and runtime classes mentioned, thus distinguishing between the protocol handlers and the connectors, as shown in Example 5-66.
Example 5-66 Extension class framework configuration in plugin.xml
<extension point="com.ibm.wsspi.extension.channel-framework-channel-type"> <channel kind="ACCEPTOR" configurationClass="com.ibm.websphere.models.config.channelservice.channels.DCSInboun dChannel" runtimeClass="com.ibm.ws.hamanager.channel.DCSChannelFactory" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" id="DCSInboundChannel" validatorClass="com.ibm.ws.hamanager.channel.DCSChannelValidator"/> <channel kind="PROTOCOL" configurationClass="com.ibm.websphere.models.config.channelservice.channels.HTTPInbou ndChannel" runtimeClass="com.ibm.ws.http.channel.inbound.impl.WSHttpInboundChannelFactory" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" applicationInterface="com.ibm.wsspi.http.channel.inbound.HttpInboundServiceContext" id="HTTPInboundChannel" validatorClass="com.ibm.ws.http.channel.validation.HttpInboundChannelValidator"/> <channel kind="PROTOCOL" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" configurationClass="com.ibm.websphere.models.config.channelservice.channels.HTTPOutbo undChannel" runtimeClass="com.ibm.ws.http.channel.outbound.impl.WSHttpOutboundChannelFactory" applicationInterface="com.ibm.wsspi.http.channel.outbound.HttpOutboundServiceContext" id="HTTPOutboundChannel" validatorClass="com.ibm.ws.http.channel.validation.HttpOutboundChannelValidator"/> ... <channel kind="PROTOCOL" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" configurationClass="com.ibm.websphere.models.config.channelservice.channels.SSLInboun dChannel" runtimeClass="com.ibm.ws.ssl.channel.impl.WSSSLChannelFactory" applicationInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" id="SSLInboundChannel" validatorClass="com.ibm.ws.ssl.channel.impl.SSLChannelValidator"/> <channel kind="PROTOCOL" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" configurationClass="com.ibm.websphere.models.config.channelservice.channels.SSLOutbou ndChannel" runtimeClass="com.ibm.ws.ssl.channel.impl.WSSSLChannelFactory" applicationInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" id="SSLOutboundChannel" validatorClass="com.ibm.ws.ssl.channel.impl.SSLChannelValidator"/> <channel kind="ACCEPTOR" deviceInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" configurationClass="com.ibm.websphere.models.config.channelservice.channels.ORBInboun dChannel" runtimeClass="com.ibm.ws.iiop.channel.impl.IIOPInboundChannelFactory" id="ORBInboundChannel" validatorClass="com.ibm.ws.orb.channel.impl.ORBChannelValidator"/> <channel kind="CONNECTOR" configurationClass="com.ibm.websphere.models.config.channelservice.channels.TCPInboun dChannel" runtimeClass="com.ibm.ws.tcp.channel.impl.WSTCPChannelFactory" applicationInterface="com.ibm.wsspi.tcp.channel.TCPConnectionContext" id="TCPInboundChannel" validatorClass="com.ibm.ws.tcp.channel.impl.TCPChannelValidator" platform="distributed,os400"/> ... <channel kind="CONNECTOR" configurationClass="com.ibm.websphere.models.config.channelservice.channels.UDPOutbou ndChannel" runtimeClass="com.ibm.ws.udp.channel.outbound.impl.WSUdpOutboundChannelFactory" applicationInterface="com.ibm.wsspi.udp.channel.UDPContext" id="UDPOutboundChannel" validatorClass="com.ibm.ws.udp.channel.validation.UdpOutboundChannelValidator"/> </extension>
Similar configuration and startup behavior is used for the EJB container, although the communications are more complex because some communications use a JNI configuration and shared object for IIOP. The plugin.xml file shows this and similar usage for the Service Integration Bus and other WebSphere Application Server subsystems.