July 3rd, 2009
Chapter 17: Using Advanced EJB Techniques address = info.address; emailAddress = info.email; country = info.country; phoneNumber = info.phoneNumber; } And that leaves us with the getCustomerInfo() method. This method is required to return an instance of CustomerValues so you need an instance to return! Either create it locally in the method, or use a global instance for the class. The global instance is the preferred option. Why? Won’t different callers end up overwriting the data that a previous caller requested? No. Remember that remote EJBs always pass data by value. That means that each time a method returns data, the caller ends up with a copy of the data you returned. Thus you can change information as much as you want, and each client will have his or her own individual copy. The final method implementation of your bean is: private CustomerValues customerInfo = new CustomerValues(); public CustomerValues getCustomerInfo() throws EJBException { customerInfo.customerId = customerId; customerInfo.name = userName; customerInfo.address = address; customerInfo.email = emailAddress; customerInfo.country = country; customerInfo.phoneNumber = phoneNumber; return customerInfo; } As you can see, there is not that much work required to convert a standard bean design to a high-performance version using value objects. So, if you know that you are going to have beans that are heavily used by your application and performance is a major consideration, value objects are a worthwhile change. Designing for local beans Looking at the opposite situation wherein the client and bean are held in the same VM the other approach applies. This time, instead of trying to corral all the data into a single reply, each piece of data is requested through a separate method. The disadvantages for the remote beans are the advantages in this situation: You need only to access data that you need rather than having to access all of it. In addition, you have the greatest chance of accessing the most up to date information (the bean may have changed its data between method calls if another client is also working with the same bean). For local beans, you want the methods that you provide to return primitive data whenever possible. This ensures the fastest possible communications and removes the overhead of copying data or allocating new class instances to return data. Earlier in the chapter, we mentioned that one of the restrictions on local beans is that they must pass a reference to the data to the client. Traditional code works the same way. For example, passing an array enables the receiver to change the contents of the array directly. In the context of remote beans, that array would be made as a copy of the original and passed to the client code. Any changes made in that array would be kept on the client and not reflected back at the server. With local beans, the opposite applies unless the local bean implementation takes explicit steps to make a copy of the data before returning it. 386
For reliable and cheap web hosting services please check tomcat web hosting website.
Posted in java | No Comments »
July 3rd, 2009
Chapter 17: Using Advanced EJB Techniques Now you need to provide variables that represent each of the fields. The simplest implementation is to just use a public variable per method that you had in your previous bean instance (this will horrify the OO-purist who would insist on having setter and getter methods!). This is how the class would now look with the addition of the public variables: public class CustomerValues implements Serializable { public int customerID; public String name; public String address; public String email; public String country; public String phoneNumber; public CustomerValues() { } } For your next step, you need to modify the bean’s remote interface to take advantage of this new class. Two options exist replace all the methods with a set/get method pair that just takes the CustomerValues class, or add it as an additional methods. Which choice you make is personal preference. For the purposes of this exercise, all the methods will be replaced by a single pair of set/get methods using the value object. Having made this decision, you can rewrite the remote interface to look like this: public interface Customer extends EJBObject { public CustomerValues getCustomerInfo() throws RemoteException; public void setCustomerInfo(CustomerValues) throws RemoteException; } Next you need to update the bean implementation class (you don’t need top do anything with the home interface) to reflect the changes in the remote interface. Due to the way you constructed the example in the previous chapter, the change in the implementation is quite simple. Start by deleting all of the methods that correspond to the old business methods and replace them with the stubs of the two new methods. public class CustomerEntityBean implements EntityBean { … public CustomerValues getCustomerInfo() throws EJBException { } public void setCustomerInfo(CustomerValues info) throws EJBException { } } Two methods to fill in, what do you do? Well, so long as you can copy the values from the values class to the internal cached variables, it really doesn’t matter what you do. So, let’s look at the setCustomerInfo method first: public void setCustomerInfo(CustomerValues info) throws EJBException { customerId = info.customerId; userName = info.name; 385
For high quality jboss hosting services please check jboss web hosting website.
Posted in java | No Comments »
July 2nd, 2009
Chapter 17: Using Advanced EJB Techniques If the goal is to reduce network traffic as much as possible, you want to get your money’s worth each time you do make a request. If you are returning only one piece of information, you might as well return as much as possible. The design implications are quite clear: Don’t use a lot of methods that only return one value, and do use a few methods that return a lot of information in one hit. In EJB terminology, the class that returns all the data as a single item is called a Value Object. Note Remember that for any method that returns a class rather than a primitive type, the returned class must be serializable. If the class is not serializable, a RemoteException will be thrown. Implementing value objects in remote beans Let’s take our customer bean example as the basis for illustrating how to change an EJB to use value objects. In the previous chapter, you saw a bean declaration that looks like this: public interface Customer extends EJBObject { public int getCustomerID() throws RemoteException; public void setCustomerID(int id) throws RemoteException; public String getName() throws RemoteException; public void setName(String name) throws RemoteException; public String getAddress() throws RemoteException; public void setAddress(String addr) throws RemoteException; public String getEmail() throws RemoteException; public void setEmail(String addr) throws RemoteException; public String getCountry() throws RemoteException; public void setCountry(String code) throws RemoteException; public String getPhoneNumber() throws RemoteException; public void setPhoneNumber(String ph) throws RemoteException; } Notice how there are a lot of methods that all return one value. In the “Beans in the wild” section of the previous chapter, you saw how to integrate an EJB with a JSP or servlet. With what you now know about performance penalties, think about how slow that JSP will be to process and then display the contents of the Web page. Each one of those lines where you wrote data out to the page, either through a bean or custom tag, required a request across a network. That means your JSP using that model is going to be a real dog. The now obvious solution to this problem is to change the bean so that it now uses a single value object to fetch the values that your JSP needs. The role of the value object is to provide a very simple container for all those values that you would have previously fetched individually. Looking through the method calls above, that looks like you will need to deal with strings and ints. Creating a value object class starts with the normal class declaration. Because value objects are returned as parameters in a remote call, they need to satisfy the same rules as any other class that you may use they must be serializable. That makes the outline of your value object class look something like this: public class CustomerValues implements Serializable { public CustomerValues() { } } Note Remember that serializable objects require an explicit public, no-argument constructor. 384
For high quality java hosting services please check tomcat web hosting website.
Posted in java | No Comments »
July 2nd, 2009
Chapter 17: Using Advanced EJB Techniques An example application to introduce local interfaces LocalProduct The next step is to provide the names of the classes that have the home and remote interfaces. Of course, you don’t have a remote interface this time, but a local interface. To describe these new capabilities, you replace the home and remote elements with local-home and local elements, respectively: LocalProductHome Customer After this point in the descriptor, the file looks the same. To complete the description, you will need to provide the following elements: LocalProductEntityBean
Bean
ProductID True Now the descriptor is complete, and you can roll the EAR file as before. Method-data granularity As with any non-trivial application, performance considerations are always important in the design process. When it comes to enterprise beans, you use a set of design considerations similar to that of any other remote-object technology, such as RMI or CORBA. For the purpose of these considerations, we make the very fundamental assumption that the client will be on a separate machine from the server. Each time you ask for data, the system has to ensure that you get the latest copy and must therefore require extra network traffic. The result is that a good designer will alter the way he or she makes data available to the client. Designing for remote beans When you are designing the code surrounding remote beans, the network is your primary concern. By placing a network between the user of the data and the source of the data, you create a lot of extra overhead: Requests must be sent and received, data must be written to and from the underlying stream, error detection/correction handling and many other tasks. As a result, the response time between asking for and receiving a piece of data is very long (potentially in the order of seconds for a heavily loaded system). As a programmer you will be very aware of performance issues in any application. It’s typically the number-one complaint we programmers have to deal with. If it takes a second or so every time a request is made to a bean, then reducing the number of time-consuming requests as much as possible certainly becomes a goal. What does this mean from a design perspective? 383
For high quality website hosting services please check java web hosting website.
Posted in java | No Comments »
July 1st, 2009
Chapter 17: Using Advanced EJB Techniques Note the lack of RemoteException that the remote version of the bean had to throw in the previous chapter. The remote product EJB is an entity bean that requires declarations of a number of finder methods. You will still need to write the finder methods for the local version, too: public LocalProduct findByPrimaryKey(ProductID id) throws FinderException; public List findByCategory(String cat, String name) throws FinderException; public List findAllInCategory(String cat) throws FinderException; Primary-key information is required for all entity beans. As you might have noticed in the preceding snippet, the code reuses as the primary-key class the ProductID class from the remote version. As the primary-key class is not dependent on any form of the EJB interfaces, you are free to use it wherever you like (even using the same class for different bean types). In this case, reusing the class gives you an advantage, because the local and remote beans represent the same data. Once you have completed the local interfaces, the rest of the writing process is the same as for remote beans. Local bean-implementation classes are still required to implement EntityBean or SessionBean interfaces as appropriate. This requirement does not change between local and remote versions. Using local beans The process of gaining access to a local bean is no different from the process of gaining a reference to a remote bean. The use of home and remote interfaces remains the same, and you still use JNDI to find the initial reference to the home interface. Of course, the most important difference between using local beans and using remote beans is that you can’t use a local bean in an environment such as a servlet or JSP. You can only use local beans in the same context (EJB container) as another bean. Apart from that consideration, all the code looks the same. To complete the picture of using local beans, this is what the code looks like in an environment such as another bean: InitialContext ctx = new InitialContext(); Object ref = ctx.lookup(”ejb/LocalProduct”); LocalProductHome home = (LocalProductHome)PortableRemoteObject.narrow(ref, LocalProductHome.class); ProductID id = new ProductID(some_id); LocalProduct product = home.findByPrimaryKey(id); Deploying local beans Deploying a local bean is the same as deploying any other bean. The various classes and the deployment descriptor must be wrapped into a JAR file and deployed to an appropriate server. Normally the vendor’s tools will take care of the complete process for you. Fill in the appropriate fields of the deployment wizard, and everything is taken care of. If you wish to roll your own, the only difference between remote beans and their local brethren is the element names used in the deployment descriptor. A deployment descriptor for a local bean starts with the same headers as a normal bean: 382
For reliable and cheap web hosting services please check tomcat web hosting website.
Posted in java | No Comments »
July 1st, 2009
Chapter 17: Using Advanced EJB Techniques Figure 17-1: A UML depiction of the relationships among local interfaces, remote interfaces, and the bean implementation From the client perspective, there are no new interfaces to deal with. Now that the bean is local to the client, no method calls that you make will need to catch a RemoteException. Maintaining the status quo is the new AccessLocalException, which indicates that the client is not allowed to use this method because the method is not a local call (for example, because a remote client such as a JSP tried to access the bean). All the other exceptions remain the same, meaning that you will still need to deal with them from their respective method calls. Writing local beans You implement local beans using the same process you use for remote beans. First create the bean interface, then write the home interface, and finally the bean implementation itself. For illustrative purposes, we shall convert the product beans of the previous chapter. Starting with the bean interface, you need to write an interface that extends the EJBLocalObject interface. public interface LocalProduct extends EJBLocalObject Note To date, no naming conventions for local interfaces have been suggested, so in this blog we will start all local objects with the prefix Local to distinguish them from the remote versions. As with all bean interfaces you will need to provide a number of methods that allow access to the data. Unlike with the remote equivalent, because the bean is local, these methods are not required to throw any exceptions. So, taking the lead from the remote Product EJB, you add methods to the interface as follows: public int getProductID(); public void setProductID(int id); public String getName(); public void setName(String name); Moving along, the home interface requires you to extend the EJBLocalHome interface as follows: public interface LocalProductHome extends EJBLocalHome As with the remote home interfaces, you need to declare a number of create() methods, each of which throws a CreateException: public LocalProduct create() throws CreateException; public LocalProduct create(int id) throws CreateException; 381
For high quality website hosting services please check cheap web hosting website.
Posted in java | No Comments »
June 30th, 2009
Chapter 17: Using Advanced EJB Techniques Requirements of local beans Programming local beans requires applying a few restrictions over and above those required by ordinary EJBs. These extra requirements are the result of the fact that local beans are a purely server-side construct that is, an EJB client such as a JSP or servlet will never see these beans. Local beans must exist in the same JVM as the beans that use them. This restricts their usage and deployment capabilities to whatever the user bean needs. All data is live between the local bean and the bean using it (pass-by-reference). That is, the user ends up with a live copy of the local bean, and both should assume that any data passed back and forth will be live rather than a copy. For example, an array of values from the local bean to the user bean will be a single piece of data, so the user should not write new values into the array for fear of corrupting the state of the local bean. Any bean may be a local bean. Session and entity beans are valid local clients. It is possible for a bean implementation class to have both local and remote definitions, but it is not encouraged. As any sort of bean can be a local bean, you can add a lot of flexibility to your application. That is, local beans are not a new type of bean, just an extended (or restricted, depending on your viewpoint) set of capabilities layered over the existing bean types. The choice between local beans and remote beans is highly dependent on your application. If you look at the example beans in the previous chapter, you will see that nothing really lends itself to the use of a remote bean. For example, the mailer bean must be available to every client so that the clients can send e-mail. The same goes for customer and order information, because these beans are accessed by the Web component of the application. With more analysis and a bigger set of data, our example application could make use of local beans for example, in keeping more detailed product information, like various models of the same product. Tip Sometimes it is worth having both local and remote beans for the same information. For example, if the example application had a new super-bean that performed order processing, it would be worth having a local bean that represented customer and product information in addition to the remote versions that the Web components are using. So don’t think that if you have a remote bean you can’t use a local bean for the same information and vice versa. Interfaces for local beans With each new capability comes a new set of interfaces to implement. For local beans, two new interfaces exist: the home interface (EJBLocalHome) and the bean object (EJBLocalObject). Even though you must implement these interfaces as you do the remote beans, you have a lot less work to do. Local interfaces still perform and require the same tasks as remote interfaces. You can’t take shortcuts just because your bean is now local. Accessing beans still means going through a home interface as well as taking the usual steps, such as calling create methods. If you are still confused about the various relationships, have a look at Figure 17-1, which illustrates the details using UML. 380
For reliable and cheap web hosting services please check cheap web hosting website.
Posted in java | No Comments »
June 30th, 2009
Chapter 17: Using Advanced EJB Techniques Overview EJBs provide a huge range of capabilities to the end user. In the previous chapter, we introduced you to the basics of writing the most common forms of EJBs. Those techniques are useful in many situations and form the core of any EJB-based application. However, there are many more useful techniques yet to be introduced, and as we alluded to in the previous chapter, there are more types of EJBs to cover. The techniques covered in this chapter are aimed at the true enterprise-level system a system wherein you have a central system providing hundreds of services with many different client-application types. As the first step in moving on to larger systems, we show you how to extend for better performance the basic classes that you already have from the previous chapter. Basic entity and session beans can only provide you with so much, and the EJB specification team realized this. The J2EE v1.3 specification includes the new EJB 2.0 standard, which provides for a huge increase in the number of and, more importantly, the interaction between, beans and databases. Along with this new specification come a lot of new languages and concepts, so hold on, we have a lot to cover! Extending Enterprise Beans Within the basic bean structures that we introduced in the previous chapter, you have a lot of room to explore different strategies in the enterprise application. Most of the new techniques we introduce in this section revolve around getting more out of your existing application. While you can take these approaches and bolt them into the basic design, it will be more beneficial for you to revisit the complete architecture as a result of having learned to use these new tools. Local beans for better performance At the top of the list of EJB users’ wish lists has been the ability to allow beans to be more efficient in communication. Prior to the EJB 2.0 specification, a bean was a bean. They all acted the same. It did not matter whether the bean client was used on the same machine as the bean server or on another one halfway around the world: All the underlying connections took the same approach of using the network to access the bean and its methods, even if they did exist on the same server and even in the same JVM. Many large-scale system designs took the EJB philosophy and applied it to everything not only was the outside world presented with an EJB interface, but internally the design used beans that were never seen in the outside world. The effect was a severe performance penalty for beans that referenced other beans residing on the same machine. In order to fix this problem, the new specification introduces the concept of local beans. These are beans that are never seen outside of the server context, which allows the server to make a number of performance optimizations (for example, making direct method calls rather than using RMI-IIOP). Note Local beans still maintain the concept of client and server usage. For local beans, the only permitted client is another bean residing on the same machine. Beans on other machines cannot be clients of the local bean. 379
For reliable and cheap web hosting services please check tomcat web hosting website.
Posted in java | No Comments »
June 29th, 2009
Chapter 16: Introducing Enterprise JavaBeans out.write(cust.getAddress()); out.write(”
“); out.write(”Country: “); out.write(cust.getCountry()); out.write(”
“); out.write(”Email: “); out.write(cust.getEmail()); out.write(”
“); out.write(”Phone: “); out.write(cust.getPhoneNumber()); out.write(”
“); } catch(Exception e) { out.write(”There was an error processing the customer”); out.write(e.getMessage()); } return SKIP_BODY; } That’s all you need to do to integrate EJBs with custom tags in JSPs. As you can see from the two different examples, there is really not that much difference in difficulty between the approaches. Which you choose is more a matter of personal and/or company preferences. Summary During this chapter, you received an extensive introduction to the core of the J2EE specification Enterprise JavaBeans. You could reasonably argue that the rest of the specifications in J2EE are there to support the requirements for EJBs. As you can see, EJBs are a huge topic, and so far we have barely scratched the surface of what you can do with them (stay tuned for more in the next chapter!). However, what we have covered so far is enough to get you up and running on most simple and medium-complexity projects. We gave you: An introduction to the concepts and terminology of EJBs. Instructions for writing basic session and entity beans. Instructions for integrating EJBs within other J2EE systems, such as servlets and JSPs. 378
For high quality java hosting services please check tomcat web hosting website.
Posted in java | No Comments »
June 29th, 2009
Chapter 16: Introducing Enterprise JavaBeans public void release() { } } From this outline, you can see most of the standard features relating to custom tags. There’s the constructor, the doStartTag() method (both of which require some code) and the methods for processing the customerID attribute. Of interest here is how you process the attribute information. Notice that the code has elected to take the value from the JSP as a String and then process it internally. You may provide alternative classes, such as Integer in the TLD rather than the default String. You are still missing the important part: interacting with the EJB. You should remember from the other examples the basic process that is needed fetch the home interface and then access the bean information. As usual, Java gives you plenty of options, but this is the one we recommend. Use the constructor to load the home interface of the Customer EJB. You would use the constructor rather than fetching the home interface in the doStartTag() method. The reason for this is for efficiency. The home interface is a common item, and you don’t need to be fetching it every single time. So place that code in the constructor: public CustomerTag() { try { Context initial = new InitialContext(); Object objref = initial.lookup(”ejb/Customer”); home = (CustomerHome)PortableRemoteObject.narrow( objref, CustomerHome.class); } catch(Exception e) { // Just print the error out System.err.println(”Error finding home interface” + e); } } If you allocate items in the constructor, you should naturally follow it up with an implementation of the release() method so that you can free them. public void release() { home = null; } That leaves the doStartTag() method for you to fill in. You should probably be able to guess exactly what needs to be done now. In this method, you fetch the EJB corresponding to the provided customer ID and then write out some formatted text to the output like this: public int doStartTag() { JspWriter out = pageContext.getOut(); try { CustomerID id = new CustomerID(customerId); Customer cust = home.findByPrimaryKey(id); out.write(”Customer ID: “); out.write(customerId); out.write(”
“); out.write(”Name: “); out.write(cust.getName()); out.write(”
“); out.write(”Address: “); 377
For high quality java hosting services please check java web hosting website.
Posted in java | No Comments »
June 28th, 2009
Chapter 16: Introducing Enterprise JavaBeans