Spring 1.2.x Integration with WebLogic Server
by Andy Piper, Rod Johnson, Chris Wall and Nick Tran
Originally published on BEA Dev2Dev September 2005
Enterprise Spring
The non-invasive IoC development model of the Spring Framework relies on, and is designed to complement, the feature set available to a J2EE application server. Indeed, in demanding production environments the quality of service provided by the underlying application server infrastructure is all-important to the continued reliability, availability, and performance of the Spring application. WebLogic Server 9.0 provides enterprise-class features that can enhance all aspects of your Spring application. In this section, we describe in some detail these features and how to leverage them in your Spring application.
Cluster management and deployment
A WebLogic Server cluster consists of multiple WebLogic Server server instances running simultaneously and working together to provide increased scalability and reliability. A cluster appears to clients to be a single WebLogic Server instance. The server instances that constitute a cluster can run on the same machine, or be located on different machines. You can increase a cluster's capacity by adding additional server instances to the cluster on an existing machine, or you can add machines to the cluster to host the incremental server instances. WebLogic Server clusters provide an enterprise class deployment platform for Spring applications, and while other technology offerings support similar features, none have the richness and ease of use provided by WebLogic Server. See Understanding Cluster Configuration and Application Deployment for a full discussion on the configuration and management of WebLogic Server clusters.
Commonly Spring applications are packaged as webapps and in this scenario you do not need to change your application to take advantage of WebLogic Server clustering. You would simply deploy your application to the servers in the cluster and reap the benefits of enhanced scalability and availability.
Spring session replication
Spring Web applications habitually store information—such as order ids and user information—in HTTP sessions. To support automatic replication and failover for servlets and JSPs within a cluster, WebLogic Server supports several mechanisms for preserving HTTP session state. These can be used non-invasively with Spring Web applications simply by providing an appropriate weblogic.xml
deployment descriptor with your application. Get more information on configuring the various types of session persistence available with WebLogic Server 9.0.
Clustered Spring remoting
Spring provides powerful remoting support, allowing you to export and consume remote services with ease while still leveraging a consistent, POJO-based programming model. Vanilla Spring supports proxying POJO calls through a single RMI interface to the appropriate Spring bean. However this support was limited to JRMP (Sun's RMI implementation) or to using specific remote interfaces with JndiRmiProxyFactoryBean
. With the certification of Spring 1.2.5 on WebLogic Server 9.0, we have extended the JndiRmiProxyFactoryBean
and associated service exporter—so that it supports POJO proxying with any J2EE RMI implementation, including RMI-IIOP and T3. Included with this support is a WebLogic RMI deployment descriptor that enables clustering on the proxy RMI interface, so POJO calls can be load-balanced across a WebLogic Server cluster. The client configuration of such support looks something like this:
<bean id="proProxy"
class="org.springframework.remoting.rmi.JndiRmiProxyFactoryBean">
<property name="jndiName" value="t3://${serverName}:${rmiPort}/order"/>
</property>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.url.pkgs">
weblogic.jndi.factories
</prop>
</props>
</property>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
</bean>
The service exporter will look something like this:
<bean id="order-pro" class="org.springframework.remoting.rmi.JndiRmiServiceExporter">
<property name="service" ref="petStore"/>
<property name="serviceInterface"
value="org.springframework.samples.jpetstore.domain.logic.OrderService"/>
<property name="jndiName" value="order"/>
</bean>
The clustered descriptor is automatically included and requires nothing more than appropriate cluster configuration and the deployment of your Spring application to all cluster members.
Console support for Spring components
Included in the Spring on WebLogic Server kit is a WebLogic Server console extension that displays the Spring beans, attributes, and operations defined in your application. It is built on the WebLogic console extension portal framework, which can transform the look and feel, functionality, and layout of the WebLogic Administration console without the need for modifying server or console code. Console extensions are deployed when they are copied to the yourdomain/console-ext
directory and your server is restarted. For more details on deploying the console extension, consult the Spring on WebLogic Server kit.
The console extension works by automatically creating (JMX) management interfaces for Spring beans that are not MBeans (as is the case for most Spring beans) and is done by configuring an MBeanExporter
in the applicationContext.xml
and specifying which beans to expose via the assembler. This feature is a great example of Spring and WebLogic Server working seamlessly and non-invasively together. To JMX-enable your Spring application you only have to change the application context deployment descriptor—to Spring-enable your console you only have to deploy two jars to your existing domain.
To enable the Spring Console extension in WebLogic Server's Administration console, you need exactly two jar files—both are supplied as part of the Spring WebLogic package. Specifically, the jar files that are required are called spring-ext-server.jar
and spring-ext-client.jar
. The spring-ext-server.jar
needs to be copied into the yourdomain/console-ext
directory. The related spring-ext-client.jar
file needs to be deployed with your Web application (in the case of a .WAR file, place the spring-ext-client.jar
into the WEB-INF/lib
directory of your Web application).
With those two files in place, all that remains to be done is to define a few beans in your Spring XML configuration file. The first Spring bean that absolutely must be defined is the com.interface21.wl9.jmx.mediator.Mediator
bean. This is the bean that (as the name implies) mediates between your application and WebLogic Server's MBeanServer and Administrative console. It is a really simple bean definition, as the following example shows:
<!-- WLS console adapter bean -->
<bean id="consoleAdapter"
class="com.interface21.wl9.jmx.mediator.Mediator">
<property name="applicationName" value="my_app_name"/>
</bean>
This bean has to be 'plugged-in' (or dependency injected) into the second bean that (again) absolutely must be configured - the MBeanExporter
. The remit of the MBeanExporter
class is to simply export any number of disparate beans that have been defined in the Spring application context to the BEA WebLogic MBeanServer (or indeed any configured MBeanServer). Note that there is no need for those beans that are exported by the MBeanServer to be coded for JMX. The Spring JMX infrastructure code takes care of generating ModelMBean
s to describe the beans that are to be exported for management via JMX. An example of a typical MBeanExporter
bean definition can be found below:
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="assembler" ref="assembler"/>
<property name="server" ref="server"/>
<property name="beans">
<map>
<!-- these are the beans that are to be exported... -->
<entry key="my_app_name:type=MaintenanceControl"
value-ref="maintenanceInterceptor"/>
<entry key="my_app_name:type=ExceptionMonitor"
value-ref="exceptionHandler"/>
<entry key="my_app_name:type=RequestStatistics"
value-ref="requestStatisticsFilter"/>
</map>
</property>
<property name="registrationBehaviorName"
value="REGISTRATION_REPLACE_EXISTING"/>
<property name="listeners">
<list>
<!-- notice how we 'plug-in' the Mediator bean
that was defined previously... -->
<ref bean="consoleAdapter"/>
</list>
</property>
</bean>
Take note that in the above bean definition, another bean ('assembler') is being injected into the 'assembler' property of the MBeanExporter
. The definition of this bean can be seen below:
<bean id="assembler" class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="interfaceMappings">
<props>
<prop key="my_app_name:type=MaintenanceControl">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=ExceptionMonitor">fully.qualified.management.interface.name</prop>
<prop key="my_app_name:type=RequestStatistics">fully.qualified.management.interface.name</prop>
</props>
</property>
</bean>
It is beyond the scope of this article to actually describe the full breadth of Spring's JMX offerings. Suffice to say the InterfaceBasedMBeanInfoAssembler
bean that is defined above is one possible strategy for controlling what methods and properties of your beans are actually exposed for management as JMX operations and attributes. The InterfaceBasedMBeanInfoAssembler
uses (arbitrary) interfaces to decide which methods and properties are to be exported. For more information consult the references section at the end of this paper.
The second property of note on the bean definition of the MBeanExporter
is the server
property. This is where one injects an instance of WebLogic Server's MBeanServer into the MBeanExporter
. The MBeanExporter will export all of the beans it has been configured to export into this specific server. The bean definition follows:
<!-- WebLogic 9 MBeanServer -->
<bean id="server"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName"
value="java:comp/env/jmx/runtime"/>
</bean>
In this definition of the server
bean, the MBeanServer instance is actually being sourced from JNDI (using the value specified for the jndiName
property to do the lookup in the context). The fact that the MBeanServer is being sourced from JNDI is of no concern to the MBeanExporter
- this transparent sourcing of dependencies into the objects that require them is one of the big value-adds of the dependency injection approach (and Spring's injection support is quite sophisticated as evidenced by the easy-to-use-and-configure JndiObjectFactoryBean
seen above).
The final, and most interesting, part of the MBeanExporter
configuration is the beans
property. The beans
property is a simple mapping of (JMX) ObjectNames to the beans that are to be exported for management to the previously injected MBeanServer instance. The strategy for choosing the ObjectNames under which your beans are actually exported to the MBeanServer is totally configurable. In this case, the default strategy of simply using the keys of the beans
map as the ObjectNames is used (see the extensive JavaDoc that comes with the Spring distribution for a thorough rundown of the various ObjectName strategies).
Web services enablement
Another facet of Spring’s remoting capability is its support for RPC-style Web services. WebLogic Server provides Ant-based tools to generate JAX-RPC stubs based on the WSDL description of a Web service. Web service clients use these generated stubs to obtain a remote interface representing server-side operations. Spring simplifies this procedure by providing a JaxRpcPortProxyFactoryBean
.
We found that configuring the JaxRpcPortProxyFactoryBean
correctly in a WebLogic Server environment was a little tricky, so to save you some time this snippet demonstrates how to configure proxy generation for a document literal wrapped Web service that contains complex types.
Most of the attributes are self-explanatory. A few attributes are of note:
-
The
serviceInterface
is the byproduct of Spring’s setter injection. This class will represent the Web services operations. -
The
customProperties
property allows for custom WebLogic Server Web service stub properties. -
The
jaxRpcService
value is set to WebLogic Server’s generated JAX-RPC implementation service. The JAX-RPC service is responsible for Web service authentication and loading complex type mapping. To satisfy the latter, WebLogic Server’s JAX-RPC service implementation must be configured as a Spring bean. This ensures the execution of the JAX-RPC service constructor; this is where type mapping files are loaded.
Setting lookupServiceOnStartup
to false on JaxRpcPortProxyFactoryBean
turns off JAX-RPC service lookup during startup. Instead, the lookup will be fetched upon first access. This is required for clients that communicate with WebLogic Server reliable request/response Web services where the client must also be a Web service. Often in these cases, the originating client is deployed along with the Web service client. Because Web service activation does not occur until application deployment is finalized, the client Web service is not available for Spring’s context loading.
<!-- reliable asynchronous Web service for sending new
medical records to medrec -->
<bean id="reliableClientWebServicesPortType"
class="org.springframework.remoting.jaxrpc.JaxRpcPortProxyFactoryBean"
lazy-init="true">
<property name="wsdlDocumentUrl"
value="http://${WS_HOST}:${WS_PORT}/ws_phys/PhysicianWebServices?WSDL"/>
<property name="portName" value="PhysicianWebServicesPort"/>
<property name="jaxRpcService">
<ref bean="generatedReliableService"/>
</property>
<property name="serviceInterface"
value="com.bea.physician.webservices.client.PhysicianWebServicesPortType"/>
<property name="username" value="medrec_webservice_user"/>
<property name="password" value="weblogic"/>
<property name="customProperties">
<props>
<prop key="weblogic.wsee.complex">true</prop>
</props>
</property>
</bean>
<!-- allows the jaxRpcService class to execute its
constructor which loads in type mappings -->
<bean id="generatedReliableService"
class="com.bea.physician.webservices.client.PhysicianWebServices_Impl">
</bean>
See WebLogic Server's Overview of Invoking Web Services and Remoting and Web Services Using Spring for further information.
Security
The WebLogic Server security system supports and extends J2EE security while providing a rich set of security providers that can be customized to deal with different security databases or security policies. Besides using standard J2EE security, application programmers can use a wide array of proprietary extensions that allow an application to tightly integrate with the security system. WebLogic Server comes with several security providers offering, for example, choices of authentication databases that include most of the popular LDAP servers, Active Directory, native Windows, and a built-in authentication solution. The built-in providers can be augmented with custom providers to integrate with nearly any authentication database, authorization mechanism, and credential mapping service. Since Spring applications deployed as webapps leverage J2EE security you can get the benefit of WebLogic Server security without any changes to your application.
Seasoned Spring users will also be aware of Acegi—Spring's own security framework. Currently, you can use either Acegi, WebLogic Server security, or both in your application since each is mutually independent of the other. More on this later.
Distributed transactions
Spring provides infrastructure for transaction management. Along with support for various database vendors, Spring also supports distributed transactions through a J2EE vendor's JTA implementation. Spring's JTA manager can be configured to work in conjunction with WebLogic Server’s JTA implementation through the WebLogicJtaTransactionManager
.
WebLogicJtaTransactionManager
delegates responsibilities directly to WebLogic Server’s Java Transaction API. WebLogic Server’s JTA TransactionManager
interface is available to clients and bean providers through JNDI, and Spring manages this interaction. The transaction manager also enables scope of transactions; transactions can operate within and between clusters and domains.
The most powerful feature of WebLogicJtaTransactionManager
is its ability to manage distributed transactions and the two-phase commit protocol for enterprise applications. By employing WebLogicJtaTransactionManager
, applications can take advantage of transaction monitoring through the WebLogic Administration Console. The WebLogicJtaTransactionManager
also allows for per-database isolation levels, which enable complex transaction configuration.
<!-- spring's transaction manager delegates to WebLogic
Server's transaction manager -->
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName"
value="javax.transaction.TransactionManager"/>
</bean>
<!-- base transaction proxy for which medrec spring beans inherit-->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<props>
<prop key="activate*">
PROPAGATION_REQUIRED</prop>
<prop key="create*">
PROPAGATION_REQUIRED</prop>
<prop key="compose*">
PROPAGATION_REQUIRED</prop>
<prop key="deny*">
PROPAGATION_REQUIRED</prop>
<prop key="getRecord*">
PROPAGATION_REQUIRED,readOnly</prop>
<prop key="getPatient*">
PROPAGATION_REQUIRED,readOnly</prop>
<prop key="getLog*">
PROPAGATION_NOT_SUPPORTED</prop>
<prop key="process*">
PROPAGATION_REQUIRED</prop>
<prop key="save*">
PROPAGATION_REQUIRED</prop>
<prop key="send*">
PROPAGATION_REQUIRED</prop>
</props>
</property>
< /bean>
<!-- single point of service for all medrec clients -->
<bean id="medRecClientServiceFacade"
parent="baseTransactionProxy">
<property name="target">
<bean
class="com.bea.medrec.service.MedRecClientServiceFacadeImpl">
<property name="adminService">
<ref bean="adminService"/>
</property>
<property name="patientService">
<ref bean="patientService"/>
</property>
<property name="recordService">
<ref bean="recordService"/>
</property>
<property name="recordXmlProcessorService">
<ref bean="recordXmlProcessorService"/>
</property>
</bean>
</property>
</bean>
For more information, see Overview of Transactions in WebLogic Server Applications and Implementing Transaction Suspension in Spring.
Java Management Extensions
Java Management Extension (JMX) is a specification for monitoring and managing Java applications. It enables a generic management system to monitor an application, raise notifications when the application needs attention, and change the state of your application to remedy problems. Spring offers extensive JMX support, which includes the ability to expose WebLogic Server’s MBeanServer through Spring’s MBeanServerConnectionFactoryBean
. The MBeanServerConnectionFactoryBean
is a convenience factory whose byproduct is an MBeanServerConnection
. During application deployment, the connection is established and cached to be later operated on by referencing beans.
The MBeanServerConnectionFactoryBean
can be configured to return WebLogic Server’s Runtime MBean Server, which exposes monitoring, runtime control, and the active configuration of a specific WebLogic Server instance. This includes access to WebLogic Server’s Diagnostics Framework. Additionally, the Runtime MBean provides access to runtime MBeans and active configuration MBeans for the current server.
The MBeanServerConnectionFactoryBean
can also be configured to obtain a connection to WebLogic Server’s Domain Runtime MBean Server. The Domain Runtime MBean Server provides admission to domain-wide services such as application deployment, JMS servers, and JDBC data sources. It is also a single point for accessing the hierarchies of all runtime MBeans and all active configuration MBeans for all servers in the domain. This MBean Server also acts as a single point of access for MBeans that reside on managed servers.
Additionally, the MBeanServerConnectionFactoryBean
can be configured to obtain a connection to WebLogic Server’s Edit MBean Server. The Edit MBean Server provides the entry point for managing the configuration of the current WebLogic Server domain.
Note that WebLogic Server’s Domain Runtime MBean Server is not active during deployment. Because of this, the bean needs to be configured using Spring’s lazy initialization, which fetches the bean when it’s invoked.
Here is an example of configuring Spring’s MBeanServerConnectionFactoryBean
with WebLogic’s MBean Servers:
<!-- expose WebLogic Server's runtime
mbeanserver connection -->
<bean id="runtimeMbeanServerConnection"
class="org.springframework.jmx.support.MBeanServerConnectionFactoryBean">
<property name="serviceUrl" value="service:jmx:t3://${WS_HOST}:${WS_PORT}/jndi/weblogic.management.mbeanservers.runtime"/>
<property name="environment">
<props>
<prop key="java.naming.security.principal">
${WS_USERNAME}</prop>
<prop key="java.naming.security.credentials">
${WS_PASSWORD}</prop>
<prop key="jmx.remote.protocol.provider.pkgs">
weblogic.management.remote</prop>
</props>
</property>
</bean>
Support
Starting with WebLogic Server 9.0 and Spring 1.2.5, BEA is making available support and certification of the Spring Framework on WebLogic Server. This support is no mere sanity testing of the Spring libraries on WebLogic Server, but has involved intense effort and collaboration between BEA and Interface 21—the creators and maintainers of the Spring Framework. Not only have we tested all the features and configurations that we described above with Spring 1.2.5, but some of the new features were introduced in Spring 1.2.5 directly as a result of BEA and Interface 21 collaboration. Some features require fixes for WebLogic Server itself and will be available as a Spring combo-patch.
Download
The Spring Open Source Framework Support 1.2.5 download includes Spring 1.2.5 - certified on WebLogic Server 9.0 - the Spring-JMX console extension and the WebLogic Medical Records sample application re-written using the Spring Framework.Future Work
In the future we plan to provide deeper integration between WebLogic Server and the Spring Framework. Although we have several ideas, some of the most interesting are:
-
Spring Deployment Unit: Spring applications are normally deployed as webapps, but it would be possible to provide a dedicated deployment unit for Spring applications.
-
Acegi and WebLogic Server Security Integration: Acegi is Spring's security framework, and we plan to integrate this with WebLogic Server's enterprise class security framework.
-
Use of EJB 3.0 for persistence: Since Spring in general manipulates POJOs, you will likely need some kind of object-relational mapping technology in order to persist Spring beans. With the advent of EJB 3.0, WebLogic Server will provide a standardized mechanism for achieving this.
Summary
We have spent some time looking at Spring, WebLogic Server, and the integration of the two technologies. As we have shown, Spring enables enhanced developer productivity while WebLogic Server enables enhanced application quality of service. Both technologies are highly non-invasive, allowing you to concentrate on developing the business functionality of your application rather than the intricacies of technology specific APIs.
Andy Piper is a Senior Staff Engineer in the WebLogic Server advanced development group. Andy has worked on WebLogic Server for the past 6 years and is responsible for many features and innovations.
Rod Johnson is the founder of the Spring Framework and a well-known expert on Java and J2EE. Rod is CEO of Interface21, a consultancy devoted to providing expert J2EE and Spring Framework services.
Chris Wall Chris Wall is a Senior Software Engineer on the Blended Team at BEA. Chris has a background in consulting in many industries including communications, high tech, and international trade.
Nick Tran is a senior software engineer at BEA systems and the lead for the WebLogic Server samples team. He is involved in the development of core API examples and end-to-end applications such as Medical Records.