Published on dev2dev (http://dev2dev.bea.com/)
 http://dev2dev.bea.com/pub/a/2007/04/spring-2-weblogic-server-9-integration.html
 See this if you're having trouble printing code examples

Spring 2.0.1 and BEA WebLogic Server 9.2 Integration

by Andy Piper and Eric Hsiao, Rod Johnson, Chris Wall
04/23/2007

Editor's note: The Spring 2.0.2 kit was announced after this article was written, and is now available for download.

Abstract

Over a year ago we described the integration of the Spring 1.2.x Integration with WebLogic Server 9.2. Since then we have certified further versions of Spring and BEA WebLogic Server, culminating in the combination of WebLogic Server 9.2 against Spring 2.0. Both these versions represent significant leaps in functionality, useability, and performance, and we decided it was time to update this article to reflect this.

BEA WebLogic Server 9.2 is the leading implementation of Sun Microsystems' Java EE 1.4 platform. However, WebLogic Server's core value proposition is in areas not covered by the Java EE specification—enhanced management, ease-of-use, high availability, scalability, reliability, and performance. Indeed, WebLogic Server's value is not tied to any particular programming model, so it is therefore a natural fit with the new breed of non-Java EE Java programming models. The most exciting of these to emerge in recent years are models based on Inversion of Control (IoC), of which the Spring Framework is the de facto implementation. This article introduces new features of the Spring 2.0 Framework, WebLogic Server, and the integration of the two. As we shall see, the whole is greater than the sum of its parts.

Article Structure

In the first two sections, we give an overview of Spring and WebLogic Server and their respective features. If you are familiar with the Spring Framework, then you should skip over the first section, and if you are familiar with WebLogic Server, then you should skip over the second section. Since this article is primarily about the integration of the two technologies, we devote the rest of the article to this topic. To give it some context we first examine MedRec—a sample application shipped with WebLogic Server—both in its original Java EE form, and then recast using the Spring Framework. After this, we dive into some detail around specific integration points. If you are trying to develop Spring applications on top of WebLogic Server, then you will almost certainly find the level of detail helpful. If you just want an idea of what is possible, then read the titles and save the substance for later. Finally, we summarize and look at some of the future developments we are thinking about.

An Introduction to Spring

In this section, we briefly summarize the features of the Spring Framework, including some of the features new to 2.0.

Spring is a layered Java/Java EE application framework, based on code published in Expert One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002). Spring exists because we believe that Java EE should be easier to use and that it's possible to create a simpler approach to Java EE development without sacrificing the power of the platform.

Spring enables agile Java EE development, and allows Java EE applications to be developed using Plain Old Java Objects, commonly termed POJOs.

Enhanced development experience with Spring

At its core Spring provides an easy-to-configure, XML-driven, Inversion of Control (IoC) container. IoC is based on the so-called "Hollywood" principle: "Don't call us—we'll call you." In this scheme, relationships between Java objects in your application are injected by the container rather than programmed by you directly. This injection comes in two forms—constructor injection and setter injection—depending on whether the container injects information into a created Java object via its constructor or its mutator methods.

In Spring, injected properties—or references to other beans—are configured via an XML file, making configuration almost entirely trivial. This, coupled with an AOP framework that allows attributes such as transactions and security to be added non-invasively, means that developers can concentrate on creating a solution for your business problem rather than getting tied up in the complexity of Java EE development or configuration. Since the container is non-invasive, you can also relax knowing that your business code is not polluted with vendor-specific (and we include Spring here) artifacts.

Components of a Spring application

As we have mentioned, Spring provides a lightweight container offering centralized, automated configuration and wiring of your application objects. The container is non-invasive, capable of assembling a complex system from a set of loosely coupled components (POJOs) via IoC in a consistent and transparent fashion. The container brings agility and leverageability, and improves application testability and scalability by allowing software components to be first developed and tested in isolation, then scaled up for deployment in any environment (Java SE or Java EE). Additionally, Spring provides a number of other developer-friendly features that we enumerate below:

You can use all of Spring's functionality in any Java EE server, and most of it in non-managed environments too. A central focus of Spring is to allow for reusable business and data access objects that are not tied to specific Java EE services. Such objects can be reused across Java EE environments (Web or EJB), standalone applications, and test environments without any hassle.

Spring's layered architecture gives you a lot of flexibility. All its functionality builds on lower levels. So you can, for example, use the JavaBeans configuration management without using the MVC framework or AOP support. But if you use the Web MVC framework or AOP support, you'll find they build on the configuration framework, so you can apply your knowledge about it immediately.

An Introduction to BEA WebLogic Server 9.2

In this section, we briefly summarize the features of BEA WebLogic Server, with an emphasis on the underlying infrastructure—rather than on programming models—that it provides.

WebLogic Server is a scalable, enterprise-ready Java EE application server. The WebLogic Server infrastructure supports the deployment of many types of distributed applications and is an ideal foundation for building any kind of application.

The WebLogic Server implementation of the Sun Microsystems Java EE 1.4 specification provides a standard set of APIs for creating distributed Java applications that can access a wide variety of services, such as databases, messaging services, and connections to external enterprise systems. End-user clients access these applications using Web browser clients or Java clients. Since Java EE is so widely known, we will not discuss it in any more detail here. See the WebLogic Server documentation on programming models for more information.

In addition to the Java EE implementation, WebLogic Server enables enterprises to deploy mission-critical applications in a robust, secure, highly available, and scalable environment. These features allow enterprises to configure clusters of WebLogic Server instances to distribute load, and provide extra capacity in case of hardware or other failures. New diagnostic tools allow system administrators to monitor and tune the performance of deployed applications and the WebLogic Server environment itself. You can also configure WebLogic Server to monitor and tune application throughput automatically without human intervention. Extensive security features protect access to services, keep enterprise data secure, and prevent malicious attacks.

Enhanced quality of service with WebLogic Server

Like many other BEA products—and icebergs—WebLogic Server has more below the water line than above it. In particular, WebLogic Server provides a number of features and tools that support the deployment of highly available and scalable applications:

Let's now look at the synergy between these two systems.

Developing Applications in Java EE and Spring

To compare and contrast the different development approaches between Java EE and Spring, we took the MedRec sample application and rewrote it using the Spring 2.0 Framework, making use of many of the new and innovative features in Spring 2.0. In the next section, we give a brief overview of MedRec's general architecture, and then look at it in its Java EE form followed by its Spring form.

The Medical Records application

Avitek Medical Records (or MedRec) is a WebLogic Server sample application suite that concisely demonstrates all aspects of the Java EE platform. MedRec is designed as an educational tool for all levels of Java EE developers. It showcases the use of each Java EE component and illustrates design patterns for component interaction and client development. MedRec also illustrates best practices for developing and deploying applications with WebLogic Server.

The real-world concept behind MedRec is a framework for patients, doctors, and administrators to manage patient data using a variety of different clients. For patients, MedRec provides a Web-based application for users to view their medical record history and maintain a profile. For administrators, MedRec provides a Web-based application to manage incoming registrations, medical record uploads, and general application monitoring. MedRec also has resources for interfacing with independent medical institutions. To demonstrate this communication, MedRec consists of a physician application to request and provide data to MedRec’s system.

MedRec in Java EE—architectural overview

The Java EE and WebLogic Server version of MedRec is designed and implemented following the traditional three-tier architecture model in which the client, server, and data store are independent of one another:

For the patient and administration applications of MedRec, we developed Web applications (webapps) to expose services to their respective users. The webapps follow the Model-View-Controller pattern where Java Server Pages render the View to the user, the Model encapsulates the data presented to and captured from the user, and the Controller is the mechanism that manages the interaction of these components in addition to interfacing with the Service Tier. MedRec employs Jakarta Struts to accomplish this pattern.

The Service Tier provides services to requesting clients and manages interactions with backend applications and resources. MedRec’s Service Tier employs the Session Facade pattern to encapsulate business logic and business data. Session Facades simplify the complexity of an application by offering an interface into distributed services. In MedRec, the primary responsibility of Session Facades is to provide data throughput. In the Java EE and WebLogic Server version of MedRec, Session Facades are developed as stateless session Enterprise JavaBeans, and data is managed by entity Enterprise JavaBeans.

To interface with external entities, MedRec exposes application functionality through Web services, which allow for dynamic interaction between disparate systems using a series of open standards. By exposing services via Web services, MedRec can provide and accept data to and from independent parties, therefore achieving the primary goal of centralized medical record management.

Figure 1 illustrates the high-level architecture diagram of the Java EE and WebLogic Server version of MedRec.

Architecture diagram of the J2EE version of MedRec
Figure 1: Architecture diagram of the Java EE version of MedRec

Spring in action—MedRec reformulated

To establish that Spring can take advantage of the enterprise features of WebLogic Server, MedRec was rearchitected to replace core Java EE components with their Spring counterparts. We replicated the same functionality as the original version of MedRec with the Spring-based version of MedRec (MedRec-Spring).

Inversion of Control
The introduction of Spring’s IoC is the most prominent addition to MedRec-Spring. IoC is a powerful principle applied using a container that injects dependencies into configured components. IoC decouples application code from its configuration. For instance, objects are not concerned with their dependencies, so they may focus on their responsibilities. In MedRec-Spring’s case, enterprise resources such as DataSources, JMS services, MBean connections, and peer services are provided to MedRec-Spring’s objects during runtime. Additionally, by migrating resource configuration and referencing outside of compiled code, the application is more manageable to shifts from development-specific resources to production resources and environments that are in-between.

To properly employ IoC, we found that an application’s code needs to follow stricter Java programming principles—specifically coding to interfaces. Interfaces, among other things, promote better collaboration because dependencies are lightened and implementation changes are isolated. From an IoC perspective, interfaces allow for the pluggable nature of dependency injection. To take advantage of IoC, MedRec-Spring was refactored so that business objects were coded against interfaces.

POJOs
In MedRec-Spring, stateless session EJBs were replaced by Plain Old Java Objects (POJOs). The strength of stateless session EJBs is their remoting capabilities and transaction management. MedRec-Spring satisfied the remoting requirement by exposing service beans via Spring’s HTTP Invoker architecture. Transaction management was provided by Spring’s transaction abstraction layer. Transaction management exactly mirrors that of the original MedRec because the Spring transaction manager was configured to delegate responsibility to WebLogic Server’s JTA transaction manager.

Messaging
MedRec-Spring contains most of the original MedRec’s messaging functionality. We employed Spring’s JMS package to simplify some of the mundane tasks such as connection factory and destination lookups. Instead of programmatically obtaining a handle on a queue, Spring provides an object that represents a messaging destination. Like all Spring beans, these object representations—JNDI names, connection factory association, and so on—are configured outside of compiled code. We also used Spring 2.0's Message-Driven POJO (MDP) facility as the target of JMS messages in three areas:

AOP
MedRec-Spring uses Spring AOP for two main purposes:

JPA
MedRec-Spring now uses JPA for accessing and writing patient records. See Using the Java Persistence API with Spring 2.0 for more details.

Application Management
MedRec-Spring contains application management features. These features interact with WebLogic Server’s domain configuration as well as its runtime domain. MedRec-Spring must act upon WebLogic Server’s MBean Servers, and Spring offers connection management that simplifies the accessibility of MBean Server.

Web Services
Finally, MedRec-Spring exports its services using Web services. Spring offers a JAX-RPC factory that produces a proxy for a Web service. Similar to other Spring beans, the factory bean is configured outside compiled code, making the application more flexible.

Figure 2 shows a high-level architecture diagram of the Spring-based version of MedRec.

Architecture diagram of the Spring-based version of MedRec
Figure 2: Architecture diagram of the Spring-based version of MedRec

Spring Best Practice with WebLogic Server

Having compared the architecture of MedRec in both Java EE and Spring environments, we now describe some gems that we gleaned when implementing the MedRec-Spring application:

The Spring on WebLogic Server kit

To help you get the most from your Spring applications deployed on WebLogic Server, we have put together a certified BEA distribution that includes Spring 2.0, the MedRec on Spring application, and a host of other goodies. The kit can be downloaded from BEA's distribution Web site free of charge.

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 Java EE 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.2 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 they can 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 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.2.

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.2, we have extended the JndiRmiProxyFactoryBean and associated service exporter so that it supports POJO proxying with any Java EE 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 (applicationContext.xml):

<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 (also from applicationContext.xml):

<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. Get more information on failover support.

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"/>

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 ModelMBeans to describe the beans that are to be exported for management via JMX. An example of a typical MBeanExporter bean definition of a context configuration file 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="autodetect" value="true"/>
  <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 -->
<jndi:jndi-lookup id="server" jndi-name="java:comp/env/jmx/runtime"/>

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 is used of simply using the keys of the beans map as the ObjectNames. (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:

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's reliable request/response Web services where the client must also be a Web service. In these cases, the originating client often 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. Here's an excerpt from an applicationContext-ws.xml context configuration file:

<!-- 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 Web Services Invocation and Remoting and Web Services Using Spring for further information.

Security

The WebLogic Server security system supports and extends Java EE 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 Java EE 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 Java EE security, you can get the benefit of WebLogic Server security without any changes to your application.

Seasoned Spring users will also be aware of Spring Security—Spring's own security framework. Currently, you can use either Spring Security, 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 Java EE 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. Here's an excerpt from applicationContext-service.xml:

<bean id="serviceFacade" class="com.bea.medrec.web.service.ServiceFacadeImpl">
    <!-- .... -->
</bean>
<!-- 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>

<aop:config>
    <aop:advisor advice-ref="txAdvice"
                 pointcut="execution(* com.bea.medrec.web.service.ServiceFacade.*(..))"/>
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>

        <tx:method name="activate*" propagation="REQUIRED"/>
        <tx:method name="deny*" propagation="REQUIRED"/>
        <tx:method name="update*" propagation="REQUIRED"/>

        <tx:method name="process*" propagation="REQUIRED"/>
        <tx:method name="get*" propagation="REQUIRED" read-only="true"/>

        <tx:method name="search*" propagation="REQUIRED" read-only="true"/>
        <tx:method name="saveRecord" propagation="REQUIRED"/>

        <!-- ... -->
    </tx:attributes>
</tx:advice>

For more information, see Overview of Transactions in WebLogic Server Applications and Implementing Transaction Suspension in Spring.

Message-Driven POJOs

Message-Driven POJOs (MDP) are a substitute for Java EE's Message-Driven Beans (MDB). They have the advantage that, just like POJOs, they do not require any platform-specific API extension or scaffolding. They simply require the implementation of standard JMS APIs:

public class RegistrationMessageListener implements MessageListener {
    public void onMessage(Message message) {
        // Fetch Registration information from ObjectMessage.
        // Process new reg by invoking service (DI)
        // ...    }
}

As with most things in Spring, configuration of the MDP container is naturally simple. Here's an excerpt from applicationContext-jms.xml:

<!-- JMS ConnectionFactory and Queue -->

<jndi:jndi-lookup id="jmsConnectionFactory" jndi-name="com.bea.medrec.messaging.MedRecQueueConnectionFactory"/>
<jndi:jndi-lookup id="registrationQueue" jndi-name="com.bea.medrec.messaging.RegistrationQueue"/>

<!-- MDP -->

<bean id="registrationMessageListener" class="com.bea.medrec.service.messaging.RegistrationMessageListener">
    <!-- ... properties... -->
</bean>

<!-- MDP container -->
<bean id="registrationMessageListenerContainer"

          class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="concurrentConsumers" value="5"/>

    <property name="destination" ref="registrationQueue"/>
    <property name="messageListener" ref="registrationMessageListener"/>
    <property name="transactionManager" ref="transactionManager"/>

</bean>

For a more detailed discussion of implementing MDPs on WebLogic Server, take a look here.

JPA and AOP configuration

We have definied a Web service tier that allow us to switch Web service implementations easily between RMI, the Spring HTTP invoker, Hessian/Burlap, and JAXPRC. If we want to transfer objects using a serializable mechanism when invoking the remote service, the objects themselves must be serializable. Unfortunately OpenJPA's Find result is a private List implementation and doesn't support Serializable, so we need to wrap these Lists with something more suitable such as ArrayList or LinkedList from the Java SE collections library. We can use the spring aop to help us do that without having to change the application source code:

@Aspect
public class ReturningValuePostProcessorAspect {
    @Pointcut("execution(java.util.List com.bea.medrec.dao.PatientDao.*(..))")
    public void postProcessPatientDao() {
    }

    @Pointcut("execution(java.util.List com.bea.medrec.dao.RecordDao.*(..))")
    public void postProcessRecordDao() {
    }

    @Pointcut("execution(java.util.List com.bea.medrec.dao.UserDao.*(..))")
    public void postProcessUserDao() {
    }
}

Here's the associated ReturningValuePostProcessor class.

@Aspect
public class ReturningValuePostProcessor {
    public ReturningValuePostProcessor() {
    }

    @Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessPatientDao()")
    public Object postProcessPatientDao(ProceedingJoinPoint pjp) throws Throwable {
        return doPostProcess(pjp);
    }

    @Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessRecordDao()")
    public Object postProcessRecordDao(ProceedingJoinPoint pjp) throws Throwable {
        return doPostProcess(pjp);
    }

    @Around("com.bea.medrec.dao.jpa.ReturningValuePostProcessorAspect.postProcessUserDao()")
    public Object postProcessUserDao(ProceedingJoinPoint pjp) throws Throwable {
        return doPostProcess(pjp);
    }

    private Object doPostProcess(ProceedingJoinPoint pjp) throws Throwable {
        Object retVal = pjp.proceed();
        if (retVal == null) {
            return null;
        }
        if (!(retVal instanceof List)) {
            return retVal;
        } else {
            //noinspection unchecked
            return new ArrayList((List) retVal);
        }
    }
}

And here's an excerpt from applicationContext-jpa.xml that puts it all together:

<bean id="patientDao" class="com.bea.medrec.dao.jpa.PatientDaoImpl"/>

<bean id="recordDao" class="com.bea.medrec.dao.jpa.RecordDaoImpl"/>
<!-- ... -->
<bean id="returningValuePostProcessor" class="com.bea.medrec.dao.jpa.ReturningValuePostProcessor"/>
<aop:aspectj-autoproxy/>

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>

For more information, see Understanding WebLogic Server MBeans and Spring’s JMX Support.

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 2.0, but some of the new features were introduced in Spring 2.0 directly as a result of the BEA and Interface 21 collaboration.

Download

The Spring Open Source Framework Support 2.0 download includes Spring 2.0—certified on WebLogic Server 9.2—the Spring-JMX console extension and the WebLogic Medical Records sample application rewritten using the Spring 2.0 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:

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.

References

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.


Return to Dev2Dev.