C H A P T E R 6 |
Scenario: J2EE Application Client and J2EE Application |
FIGURE 6-1 shows another J2EE application. Like the applications in the other scenarios, this one has significant business logic in an EJB module. But, where the earlier examples used web module front ends, this one uses a front end provided by a J2EE client application.
In other scenarios (see Chapter 4 and Chapter 5), a web module front end and an EJB module with substantial business logic are assembled into a J2EE application, and the application is deployed as a unit. End users use web browsers to access the web pages defined in the web modules.
A J2EE application client also provides a user interface, but it is programmed, deployed, and executed differently than a web module. An application client is a separate Java program with its own main method. The application client is deployed separately from the server-side J2EE application. In most cases it is deployed to an end user's machine. Since it is a separate program with its own main method, an end user can start and stop the application client separately from the server-side J2EE application.
The application client runs in a J2EE client container, which means that even though the application client is deployed and executed separately from the server-side J2EE application, it can use Java RMI to invoke the business methods of the server-side application. And, when it does, it can participate in J2EE container-managed transactions and container-managed security.
This scenario looks at a J2EE application that includes the type of interaction shown in FIGURE 6-1. This application shows you how an application client is used and how it participates in J2EE transactions and security. It is also an example of the kinds of application design problems you can solve with an application client.
In most of the previous scenarios, the application has been an online shopping catalog, and the end users have been online shoppers who access the online catalog through web module front ends.
The online catalog application, however, has other end users besides the shoppers. Items in the online catalog change frequently. Items are added, removed, put on sale, and so on. These tasks aren't performed by the shoppers, but by an application administrator who is an employee of the online vendor.
The work performed by the administrator is more complicated than what the online shoppers do. For example, adding a new item to the catalog requires setting up a product record that is keyed by SKU, setting up the mixture of image and text that appears in the online catalog, and setting up the keywords that online shoppers use to search for products.
Shoppers typically interact rapidly with the application, requesting new pages from the catalog, requesting more detailed information on a particular item, and so on. The application administrator interacts differently with the application, typically spending long periods of time working on a catalog entry before saving it. Only when saving a catalog entry does the application client need the services of the server-side application. So, the application administrator could make use of business logic that executes independently of the server-slide logic.
After considering the work that is performed by the application administrator, you decide that an application client with its own business logic is a more appropriate tool for administering the online catalog than a web interface provided by a web module. The main interactions that will take place when this application runs are:
1. The server side of the application, which performs the actual database inserts, updates, and deletes, is a J2EE application with session and entity enterprise beans. It accesses the same databases that the online shoppers do. This application is typically managed by system administration and is up and running before the application administrator starts the application client.
2. The application administrator starts the application client to perform some catalog management tasks. The application client runs in its own process, on the administrator's machine. Since it was deployed as a J2EE application client, it runs in a J2EE client container. The application administrator logs in and establishes a security identity.
3. The application administrator works with text and images to build a new catalog entry. When the administrator completes a new catalog entry and clicks a Save button, the application client uses JNDI lookup to obtain a remote reference to the session bean in the server-side application, and uses Java RMI to invoke the business method that inserts the new entry into the online catalog database. This may lead to several inserts in different tables.
There are other programming issues in this application, such as programming the interactions between the session and entity enterprise beans. These are covered in other scenarios that focus on those issues.
TABLE 6-1 summarizes the programming required to create the J2EE application and application client illustrated in FIGURE 6-1.
The sections that follow use a simple example to demonstrate each of these programming tasks.
In this scenario, the application client uses Java RMI to communicate with an enterprise bean in the server-side application. The instructions that follow show you how to write a very simple program that fits this scenario.
The instructions are divided into two main parts. The first explains how to write the Java code for the client program. The second explains how to transform that program into an application client that can be deployed to a J2EE application server.
What distinguishes an application client from other stand-alone Java programs is its use of J2EE services, such as EJB references, to interact with other J2EE applications running in other containers. CODE EXAMPLE 6-1 shows a simple way to implement the JNDI lookup code in a Swing program.
Like other types of J2EE references, the EJB references in this application client consist of the lookup code and corresponding declared references. The next section, which transforms the program into a J2EE application client, explains how to set up the reference declarations. The significant feature in this section is the lookup code.
Notice that the lookup code is similar to the lookup code used when web modules invoke business methods of enterprise beans. The code that is needed for the J2EE interactions has been commented and highlighted.
Your real-world application client will be more complex than this, so you may want to test it at this point, before you deploy it to a J2EE application server. You can run your program by executing its main method, either from the IDE or from the command line. But, since it won't be running in a J2EE client container yet, your JNDI lookup calls and remote method invocations will fail. To test execute, you need to comment the JNDI calls, and replace the remote invocations with code that returns dummy values that will allow you to test your program's logic. You can still test your windowing code and business logic.
In this simple example, the JNDI lookup was added to the JFrame's constructor. The create method that returned an instance of the enterprise bean and the remote invocation of sayHello were added to the button's action performed method. This is a simple way of adding J2EE code to a small program. A later section will consider other strategies for adding J2EE code to a client program. The next step in the scenario is transforming your Swing program into a J2EE application client.
You have written a Java program that provides the functionality you need in an application client. The procedures that follow explain how to use the Sun ONE Studio 4 IDE to turn it into a J2EE application client.
To create a client application node and associate it with your client program:
1. Right-click on the folder or package in which you want to create you application client. Choose New J2EE
Application Client.
This creates an application client node in the explorer.
2. Right-click the application client node. Choose Set Main Class. Use the browser to select your client class. Click OK.
What you see in the IDE is a new sub node of the application client node for your Java client program. FIGURE 6-2 shows an application node named HelloAppClient. The helloClient program (shown in CODE EXAMPLE 6-1) was designated as the main class for this application client node, and the IDE created a sub node named helloClient. The application client node represents the deployable form of the Java client program. You can use its properties to request specific J2EE services from the client container. In this case, the HelloAppClient node represents the deployable form of the helloClient program.
After creating an application client and associating a program with it, you need to configure the application client. In this case, you wrote a Java client program that invokes an enterprise bean business method, so you need to set up declared references on the application client node that match the JNDI lookup in the program code.
To set up an EJB Reference for an application client:
1. Right-click the application client node. Choose Properties. Click on the References tab to bring it to the front. Locate the EJB References Property, click on it, and click the ellipsis (...) button that appears. This opens the enterprise bean reference property editor. Click Add to open the Add EJB Reference dialog.
FIGURE 6-3 shows the dialog. The values in the fields are correct for the program in CODE EXAMPLE 6-1.
2. Click on the tab for the J2EE application server you are using to bring it to the front.
The fields that appear on this tab depend on the application server. FIGURE 6-4 shows the tab for the J2EE Reference Implementation, which has a field for JNDI Name. You use this field to identify the enterprise bean your application client will be interacting with. You need to identify the enterprise bean by the JNDI name that was specified when the enterprise bean was deployed. In this example the server-side enterprise bean was deployed with the name Hello.
If you are using a different J2EE application server, click the Help button to access online help for the fields on the tab.
3. Click OK to close the Add EJB Reference dialog, and OK again to close the property editor.
In addition to an enterprise bean reference, your application needs a copy of the stub files that support the remote method invocation on the enterprise bean you identified in the reference. These files are server-specific, and they are generated by the application server's deployment tool when the server-side application is deployed. They are normally found in a JAR file generated when the server-side application is deployed.
Some application servers (including WebLogic) are able to download the stub files to the your application client when you execute it. If you are using one of these servers, you don't need to do anything with the stub files. You can proceed directly from setting up the enterprise bean references to executing your application.
Other application servers require you to supply a copy of the stub JAR file before you execute your application client. The J2EE Reference Implementation is one of these servers, and this section contains procedures for telling the Reference Implementation where to find stub JAR. When you deploy the application client to the RI, a copy of the stub JAR will be included in the deployment.
If you are developing both the server-side application and the application client, you probably have a copy of the server-side application mounted in the Explorer along side your application client. If this is the case, you can simply identify the server-side application as the application client's target application, and the IDE will find the client JAR file for you. FIGURE 6-5 shows HelloAppClient in the same fileystem as the server-side application, which is represented by the HelloApplication node.
To set the Target Application property:
1. Right-click on the application client. Choose Properties. Locate the Target Application property, click on it and click on the ellipsis (...) button.
2. Use the browser to locate the server-side application's node in you IDE. Select it and click OK.
FIGURE 6-6 shows the HelloAppClient's property sheet after it has been configured to use the HelloApplication as its target application.
If you are developing your client for a server-side application that has already been deployed on another machine, and you don't have the server-side application on your development machine, you can use a different property to provide the application client with the path to the necessary client JAR. You may need to obtain a copy of the client JAR file from the developer of the server-side application, or from the system administrator who manages the server-side application.
If the server-side application was developed with Sun ONE Studio 4, you (or the server-side developer or system administrator) can use the IDE to create the necessary stub JAR file.
To create a client JAR file for a server-side application that is mounted in the IDE:
Right-click on the J2EE application node. Choose Export Client Support. This opens the Specify location for client jar dialog. Use it to specify a directory in which to place the client JAR.
If the client JAR can't be created this way, because the server-side application can't be mounted in the Sun ONE Studio 4 IDE, the server-side developer (or system administrator) will have to obtain a copy of the client JAR generated by the application server.
Once you have a copy of the client JAR, mount it in your file system, and use the client JAR property to identify it to your application client.
To specify a client JAR for you application client:
Right-click on the application client node. Choose Properties. Click on the tab for the application server you are using to bring it to the front. Locate the property that identifies the client JAR path, click on it and click on the ellipsis (...) button.
Figure FIGURE 6-7 shows the J2EE RI tab for the HelloAppClient node. This tab provides a property named Stub Jar File, which you can use to identify the stub JAR file.
For other application servers that require you to identify a client JAR file, the process should be similar. First, you obtain a copy of the client JAR file. Then, on the server-specific property tab, locate the property you use to identify the path to the stub JAR file. Remember that some application servers, including WebLogic, automatically download the client JAR to your application client when you execute it.
To execute your application client:
1. Make sure that you have chosen an application server for your application client. Right-click the client application node and choose Properties. On the property sheet, locate the Application Server property.
The initial value for this property is Default Application Server. If you execute with this value for the property, your application client will be executed by the application server instance that was selected as the default server instance. (To see the default server, switch to the Explorer Window's Runtime tab, locate the Server Registry node and its Default Servers subnode.)
You can also specify a server instance with this property. Click the Application Server property, then click the ellipsis (...) button. This opens the property editor.
2. Right-click the application client node and choose Execute.
This command runs your application client inside a client container provided by the application server you specified in Step 1.
3. Some application servers (including the J2EE Reference Implementation) will open a login screen at this point. Type in a valid username and password.
FIGURE 6-8 shows the J2EE RI login screen with the default J2EE RI username and password (j2ee/j2ee).
4. After you log in successfully, the application server will open execute your client program's main method.
If you prefer to deploy your application client and run it from the command line, you can create a client JAR file. Executing a client JAR file requires the application server's tool for running clients.
1. Right-click the application client node and choose Export Client Jar. Use the dialog to specify the application server and the location of the client jar file.
2. You can move the client JAR file to another machine, if the application server has been installed on that machine.
3. Run the client with the tool provided by the application server. (For the J2EE Reference Implementation, the tool is named runclient.)
In this scenario, the application client communicates with a server-side J2EE application. The server-side application in FIGURE 6-1 consists of a single EJB module, but this is not required. The server-side application could include several EJB modules; it could even include a web module that provided different end-user functionality than the application client does. (Assembling a web module and an EJB module into a single J2EE application is covered in other scenarios.)
No special programming is required to make the server-side application accessible to an application client. When you program an application client, however, you need some information about the server-side application.
Transactions are generally part of the server-side J2EE application, and defining transaction boundaries is part of programming the server-side application. The server-side container will start a transaction when the application client invokes a transactional business method, and commit the transaction when all of the business logic inside the transaction boundary completes successfully.
This scenario explains how to program one type of interaction between an application client and a server-side J2EE application. It shows an application client that uses Java RMI to requests services from a server-side J2EE application. It also show the J2EE code inside the swing class that has the main() method.
The example (CODE EXAMPLE 6-1) showed the J2EE code inside the swing class that provided the interface for the application. Putting all of the code in this class made it easier for you to see everything that is required in a client application, but you may want to program your real-world application clients differently.
One approach, that allows you to isolate your J2EE code from your user interface and business logic, is to put your J2EE code into a helper class. FIGURE 6-9 shows a client application that uses a helper class.
Assume that this application client provides the functionality described in the scenario (The Interactions in This Application), helping an application administrator set up a new entry for an online catalog. In this version of the client, however, when the end-user clicks the Save button, the windowing class does not perform the JNDI lookup and remote invocation itself. Instead, it passes the new catalog entry to the helper class. The Save button's actionPerformed method would now include code something like this:
... myHelperClass helper = new myHelperClass(); helper.saveNewEntry(newCatalogEntry); .... |
The helper class's saveNewEntry method performs the JNDI lookup and invokes the necessary server-side methods. You set the enterprise bean references up in the same way, on the application client node.
This approach makes it easier to test you Java client program. You can simply replace the helper class with another Java class that returns dummy values.
Note that application clients are not limited to Java RMI interactions with one enterprise bean in the server-side application. They can invoke the business methods of multiple enterprise beans. To do this, your client needs to import the home and remote interfaces of all the enterprise beans, and you need to add JNDI lookup code for all of the enterprise beans. You also need to add references for all the enterprise beans to the application client node.
An application client can also use Java messaging to communicate with a server-side application. To do this, you need to know the JNDI names that were assigned to the queue and queue connection factory when the server-side application was deployed. Instead of enterprise bean references, your application client needs a resource environment reference for the queue (see The Reference Declaration for the Queue) and a resource reference for the queue connection factory (see The Reference Declaration for the QueueConnectionFactory), Your application code needs JNDI lookups for these two references (see The JNDI Lookup Code).
Copyright © 2002, Sun Microsystems, Inc. All rights reserved.