Resource injection using Rational Application Developer v7.5

Overcoming the lack of support in Java Persistence API architecture for the OUT parameter in stored procedures

Java™ platform Platform, Enterprise Edition has simplified the development of complete enterprise applications. Using resource injection through annotation, much standard code is eliminated, which contributes to maintainable code. Your organization might have numerous existing, complex stored procedures. You can continue to develop your applications that use stored procedures and take advantage of the Java platform. IBM® Rational® Application Developer provides a rich development environment and that is tightly integrated with IBM WebSphere® Application Server. With Rational Application Developer, you can readily make changes that can lead to an agile development cycle.

Share:

Dan Haim (dan.haim@ssa.gov), Lead Web Architect, Social Security Administration

Photo of Dan HaimDan Haim is currently a lead Web architect at the Social Security Administration



James Chung (jjchung@ca.ibm.com), Accelerated Value Specialist, IBM

Photo of James ChungJames works with the Rational Application Developer Accelerated Value Program team and is the Accelerated Value Leader/Specialist for SSA. He is located at the IBM Toronto Lab.



07 June 2010

Also available in Chinese

Overview

This article provides a quick introduction to Java™ Platform, Enterprise Edition and shows how the platform can help in achieving ease of development. To potentially make a typical application development task even simpler, you use IBM® Rational® Application Developer v7.5 for WebSphere®.

A step-by-step example demonstrates how you can quickly create a complete Java platform, Enterprise Edition application and deploy it to WebSphere v7.0.


Java Platform, Enterprise Edition

Java Platform, Enterprise Edition, or JEE, is a standard tool for implementing and deploying enterprise applications in the Java programming language. The latest is Java platform, Enterprise Edition version 6. With JEE and its many features and capabilities, developers can concentrate on the business logic of the components and stop worrying about infrastructure and integration tasks. With JEE, annotation capabilities reduce boilerplate code and make deployment descriptors optional.

The persistence architecture that was introduced in JEE 5 is Java Persistence API (JPA) architecture. JPA has a significant limitation: JPA does not fully support calling stored procedures with the OUT parameter.

Most organizations store their data in a relational database and designed their information system to rely on stored procedures for many reasons. Typically, workers have dedicated years of effort to tuning the stored procedures; the task to discard them and develop a better solution is prohibitive. The Java programming language provides the JDBC API, which defines how to access a relational database. Typically, in an enterprise application data source objects are retrieved through a JNDI lookup operation. When the data source object is available, the application can proceed to make JDBC calls. Even though the sequence of doing the JNDI lookup is well known, casting and handling the JNDI exception adds a lot of standard code.

Resource injection, also known as dependency injection, is a specific form of inversion of control. By using annotation, you can introduce references to resources, EJB, and so on where they are needed. This annotation reduces standard code and resolves each of the disadvantages mentioned earlier.

JEE 5 can handle injections transparently when the injections are used on these container-managed components:

  • Servlet (servlets, servlet filters, event listeners)
  • JSP (tag handlers, tag event listeners)
  • JSF (scoped managed beans)
  • EJB (beans, interceptors)
  • Java API for XML Web Services (JAX-WS; endpoint handlers)
  • Java platform (main (static), login callback handler)

Injection is limited only to first class constructs that are defined in the Java platform, including these constructs:

  • SessionContext object
  • DataSource object
  • EntityManager interface
  • TimerService interface
  • Other enterprise beans
  • Web services
  • Message queues and topics
  • Connection factories for resource adapters
  • Environment entries limited to String, Character, Byte, Short, Integer, Long, Boolean, Double, and Float.

The injection facilities in JEE 5 do not apply to any plain old Java objects (POJOs).

The following listing shows resource injection reduces standard code and simplifies code development.

Listing 1. Looking up a container- managed data source object using JNDI
public testGetDSConnection () {

try {
        // Obtain the initial Java Naming and Directory Interface 
        // (JNDI) context.
        InitialContext initCtx = new InitialContext ();
        // Perform JNDI lookup to obtain the resource.
        // Get the DataSource.
        DataSource ds = (DataSource) 
            initCtx.lookup("java:comp/env/jdbc/Sample"); 
        // Get a connection and execute the query.
        Connection conn = ds.getConnection();
    ...

    } catch (NamingException ex) {
        // Handle failure. 
    }
Listing 2. Getting a resource injected data source object
private @Resource DataSource ds;

public testGetDSConnection () {
    // Get a connection and execute the query.
    Connection con = ds.getConnection();
    ...
}

Rational Application Developer for WebSphere

Rational Application Developer for WebSphere is a Java integrated development environment (IDE) for designing, developing, and deploying applications. Version 7.5 fully supports JEE 5 specifications. See an overview of the newest features in this developersWorks article: What's new in IBM Rational Application Developer Version 7.5

Requirements

In order to follow the sample steps in this article, you must have a basic familiarity with Rational Application Developer for WebSphere. Additionally, the following components must be installed:

  1. Rational Application Developer V7.5 with the either one of the following application servers from the WebSphere family:
    • IBM WebSphere Application Server v7.0
    • IBM WebSphere Application Server v6.1 with EJB 3.0 feature pack
  2. IBM DB2® with its sample database and Stored Procedures

A project interchange file is included in the Downloads section below. Modify the stored procedure invocation in the session bean to your particular database schema before you deploy the application.

Calling a stored procedure through JDBC

Instructions for installing a stored procedure, compiling and running the sample Java test program can be found in the README file in the DB2 installation location: sqllib\samples\java.

Figure 1. The README file location
In Windows Explorer, the README file location

The JPA limitation

JPA cannot call stored procedures that have an OUT parameter. This limitation is significant because most useful stored procedures have an OUT parameter that provide some sort of data to the calling program.

The SpClient.java sample program in the sqllib\samples\java\jdbc directory demonstrates how to call various kinds of stored procedures, including some with OUT parameters.

By following the instructions in the README file, you can generate the sample SpClient program output that Figure 2 shows.

Figure 2. Output from the SpClient program
SpClient output in a command-line environment

Calling a stored procedure with a resource injection

You can create a JEE application by using Rational Application Developer for WebSphere. You use annotation to add references to the data source, with which you can avoid creating an EJB deployment descriptor. Because you do not create an EJB deployment descriptor, you need to generate a WebSphere Bindings deployment descriptor to complete the data source binding. You must have this binding deployment descriptor to test within the IDE. You also need to create a simple web module with a servlet to call the session bean.and finally to deploy and test the application on a server that runs WebSphere Application Server v7 or v6.1 with EJB 3.0 feature pack

Create a JEE application

Figure 3 shows how to launch the EAR Application Project wizard.

  1. Click File > New > Enterprise Application Project.
  2. Enter a project name.
Figure 3. The EAR Application Project wizard
Input fields in the EAR Application Project wizard
  1. Click Next.
  2. Click New Modules
Figure 4. The new JEE module
Selections for creating a JEE module
  1. Select only the EJB module and Web module.
  2. Click Finish twice.

Add a session bean

  1. Select the EJB module.
  2. Select File > New > Session Bean.
Figure 5. Create EJB 3.0 Session Bean wizard
Fields in the Create EJB 3.0 Session Bean wizard
  1. Name the package and class.
  2. Click Next twice.
  3. Clear the Add bean to Class Diagram check box.
  4. Click Finish.

Create a resource injection

Rational Application Developer for WebSphere provides an integrated editor that features code assist, validation, quick fixes, and refactoring support.

  1. Open the session bean source code that you created earlier, and add the following code from Listing 3.
Listing 3. A resource injection from an annotation
@Stateless
public class MySession implements MySessionLocal {
@Resource
DataSource ds;
  1. Press Ctrl+Alt+O to automatically organize the import statements.
  2. Create a public method to be called later by a client program.
  3. Add the code from Listing 4.
Listing 4. The EJB method
public void CallStoredProc(){
        try {
        System.out.print("\nTesting Database Resource Injection");
                Connection con = ds.getConnection();
                double outMedian = 0;
        // call INOUT_PARAM stored procedure using the median returned
        // by the call to OUT_PARAM
    System.out.println("\nCall stored procedure named INOUT_PARAM");
    System.out.println("using the median returned by the call to " + 
                                 "OUT_PARAM");
              callInoutParameter(con, outMedian);
            
                } catch (SQLException e) {
                        e.printStackTrace();
                }
  }
}
  1. Add the callInoutParameter(con, outMedian) method from Listing 5, which is taken directly from the SpClient.java program.
Listing 5. The SpClient stored procedure call
private void callInoutParameter(Connection con, double median) {
                try {
                        // prepare the CALL statement for INOUT_PARAM
                        String procName = "INOUT_PARAM";
                        String sql = "CALL James." + procName + "(?)";
                        CallableStatement callStmt = con.prepareCall(sql);

                        // set input parameter to median value passed back by OUT_PARAM
                        callStmt.setDouble(1, median);

                        // register the output parameters
                        callStmt.registerOutParameter(1, Types.DOUBLE);

                        if (median == 99999.99) {
                        System.out.println("-- The following error is expected! --");
                        }
                        callStmt.execute();

                        // retrieve output parameters
                        double inoutMedian = callStmt.getDouble(1);

                        System.out.println(procName + " completed successfully");
                        System.out.println("Median salary returned from " + procName
                                        + " = " + inoutMedian);

                        // clean up resources
                        callStmt.close();

                } catch (SQLException e) {
                        System.out.println(e.getMessage());
                }
        }
  1. Promote the CallStoredProc method: Right-click CallStoredProc, and then select Java EE Tools > Promote Method. This action adds the method signature to the Business Interface, enabling clients to call the method.
Figure 6. Method promotion
Menu selections for promoting a method
  1. Select the CallStoredProc() method.
Figure 7. Select the method to promote
A list of methods that are available for promotion
  1. Click Ok.
  2. Save the class source.

Generate the WebSphere Bindings deployment descriptor

  1. Right-click the EJB module.
  2. Select Java EE > Generate WebSphere Bindings Deployment Descriptor.
Figure 8. Generate the WebSphere Bindings deployment descriptor
WebSphere Bindings deployment descriptor menus
  1. With the Bindings deployment descriptor (meta-data\ibm-ejb-jar-bnd.xml) open in the Deployment Descriptor editor, click Add.
Figure 9. Configure the WebSphere Bindings deployment descriptor
Configure the bindings in the EJB Bindings editor
  1. Select Session, and then click Ok.
  2. Select the session bean that you created earlier.
  3. Click Next.
  4. Select Resource Reference, and click Next.
  5. The wizard automatically inspects the source and returns the appropriate resource that can be bound.
  6. Select the resource. (The default name is the package name.Class name or data source name.)
  7. Click Next.
  8. Enter the binding name (Figure 10). This is the same JNDI name that is used in the data sources definition on the server (Figure 11). Use the WebSphere Administrative Console to configure the data source. The data source connects to your DB2 server that has the sample database and stored procedures installed
Figure 10. The binding name
The name field for the Session Bean binding
Figure 11. The data source JNDI name on the WebSphere Administrative Console
The Administrative Console Data sources page
  1. Click Finish.
  2. Save the WebSphere Binding deployment descriptor.
Figure 12. The EJB bindings editor
Name and binding name in the EJB bindings editor

Test the Web client

  1. Click Web Module Properties > Java EE Module Dependencies, and select the EJB module.
Figure 13. The Java EE module dependencies
Settings to add dependencies to the module
  1. Open the New Servlet Wizard by clicking File > New > Servlet), and create a servlet in the Web Module.
  2. Use resource injection again to make the servlet to refer to the session bean (Listing 6).
Listing 6. The resource injection to make the servlet refer to the session bean
private static final long serialVersionUID = 1L;
@EJB
MySessionLocal mySession;
  1. After the servlet has a reference to the session bean, call the exposed method as show in Listing 7.
Listing 7. Call the exposed method
protected void doGet(HttpServletRequest request, HttpServletResponse response) 
                throws ServletException, IOException {
                mySession.CallStoredProc();
        }

Deploy and test the program

  1. Start the WebSphere server.
  2. Run the artifact on the server: In the Enterprise Explorer view click Run As> Run on Server.
  3. Select the servlet.
Figure 14. Run the artifact on the server
Selections for running the artifacts on the server
  1. Select the Started WebSphere server.
  2. Click Finish.

This action deploys the application to the server and runs the servlet in the browser. The servlet then calls the EJB, which calls the stored procedure. Notice that the console output (Listing 7) displays the same output as the stored procedure call from the JDBC program as shown in Figure 2.

Listing 8. Console output
[5/18/10 15:11:55:562 EDT] 00000013 ApplicationMg A   WSVR0221I: Application started: 
ResourceInjectedEAR
[5/18/10 15:11:55:562 EDT] 00000013 CompositionUn A   WSVR0191I: Composition unit 
WebSphere:cuname=ResourceInjectedEAR in BLA WebSphere:blaname=ResourceInjectedEAR started.
[5/18/10 15:11:55:593 EDT] 00000013 AppBinaryProc I   ADMA7021I: Distribution of 
application ResourceInjectedEAR completed successfully.
[5/18/10 15:11:55:609 EDT] 00000013 FileRepositor A   
ADMR0009I: Document cells/jamescNode05Cell/applications/ResourceInjectedEAR.ear/deltas/
ResourceInjectedEAR/delta-1274209912171 is created.
[5/18/10 15:11:55:656 EDT] 00000013 FileRepositor A   
ADMR0010I: Document cells/jamescNode05Cell/applications/
ResourceInjectedEAR.ear/deployments/
ResourceInjectedEAR/deployment.xml is modified.
[5/18/10 15:11:55:718 EDT] 00000013 FileRepositor A   
ADMR0010I: Document cells/jamescNode05Cell/applications/
ResourceInjectedEAR.ear/deployments/
ResourceInjectedEAR/META-INF/ibm-application-runtime.props is modified.
[5/18/10 15:12:12:265 EDT] 00000020 servlet       I 
com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: 
[ResourceInjectedEAR] [/ResourceInjectedEARWeb] [MyServlet]: Initialization successful.
[5/18/10 15:12:12:593 EDT] 00000020 SystemOut     O 
Testing Database Resource Injection
[5/18/10 15:12:12:593 EDT] 00000020 PrivExAction  W   
J2CA0144W: No mappingConfigAlias found for ConnectionFactory or DataSource jdbc/Sample.

[5/18/10 15:12:19:015 EDT] 00000020 WSRdbDataSour W   DSRA9542W: The JDBC Driver
 that is configured with the data source for the Application Server does not support
  the extending data source properties feature. The Application Server will not honor
   the extended data source properties.

[5/18/10 15:12:19:046 EDT] 00000020 InternalGener I   
DSRA8203I: Database product name : DB2/NT

[5/18/10 15:12:19:046 EDT] 00000020 InternalGener I   
DSRA8204I: Database product version : SQL09010

[5/18/10 15:12:19:062 EDT] 00000020 InternalGener I   
DSRA8205I: JDBC driver name  : IBM DB2 JDBC Universal Driver Architecture

[5/18/10 15:12:19:078 EDT] 00000020 InternalGener I   
DSRA8206I: JDBC driver version  : 3.1.57

[5/18/10 15:12:19:078 EDT] 00000020 InternalDB2Un I   
DSRA8212I: DataStoreHelper name is: 
com.ibm.websphere.rsadapter.DB2UniversalDataStoreHelper@78387838.

[5/18/10 15:12:19:093 EDT] 00000020 WSRdbDataSour I   
DSRA8208I: JDBC driver type  : 4


Call stored procedure named INOUT_PARAM
[5/18/10 15:12:19:359 EDT] 00000020 SystemOut     
O using the median returned by the call to OUT_PARAM
[5/18/10 15:12:22:734 EDT] 00000020 SystemOut     
O INOUT_PARAM completed successfully
[5/18/10 15:12:22:734 EDT] 00000020 

SystemOut O Median salary returned from INOUT _PARAM = 76858.2

Acknowledgment

The authors would like to thank Hamid Kalantari and Robert Weisz for reviewing this article.


Download

DescriptionNameSize
Source Code in Project Interchance format.ResourceInjected.zip15 KB

Resources

Learn

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Rational software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational, DevOps
ArticleID=494339
ArticleTitle=Resource injection using Rational Application Developer v7.5
publish-date=06072010