qr code generator with javascript Figure 28-6: The debugger 497 in Java

Generator QR Code 2d barcode in Java Figure 28-6: The debugger 497

Figure 28-6: The debugger 497
QR Code ISO/IEC18004 Generator In Java
Using Barcode drawer for Java Control to generate, create QR Code ISO/IEC18004 image in Java applications.
Decode QR Code 2d Barcode In Java
Using Barcode decoder for Java Control to read, scan read, scan image in Java applications.
In the debugger, you are free to do anything you usually do in the IDE you can inspect any object reachable from the debugger For example, you can inspect the request object uniform resource indicator (URI), as shown in Figure 28-7
Create Barcode In Java
Using Barcode creator for Java Control to generate, create bar code image in Java applications.
Bar Code Reader In Java
Using Barcode recognizer for Java Control to read, scan read, scan image in Java applications.
Figure 28-7: Inspecting the request object URI These debugging abilities can save you hours of work, compared to using the real WebSphere installation for testing and debugging software Not only is the deployment cycle significantly shorter, but the debugging tools make all the difference
QR Code Creation In Visual C#.NET
Using Barcode drawer for .NET Control to generate, create QR Code ISO/IEC18004 image in .NET applications.
Quick Response Code Printer In .NET Framework
Using Barcode generator for ASP.NET Control to generate, create QR Code image in ASP.NET applications.
Debugging JSPs
Drawing QR Code 2d Barcode In Visual Studio .NET
Using Barcode generation for .NET Control to generate, create QR Code JIS X 0510 image in .NET applications.
Generating QR Code In VB.NET
Using Barcode drawer for .NET framework Control to generate, create QR Code ISO/IEC18004 image in .NET applications.
This chapter concludes with the tools available for JSP development and debugging Unlike the servlet development and execution environment, JSP requires some minimal deployment As mentioned, the VisualAge for Java WebSphere Test Environment runs a miniature Web server that has a "document root" just like the actual IBM HTTP server This root is located by default in the directory ide\project_resources\IBM WebSphere Test Environment\hosts\default_host\default_app\web\ under the VisualAge for Java installation The default content of this directory is shown next
GS1 128 Creator In Java
Using Barcode drawer for Java Control to generate, create GTIN - 128 image in Java applications.
Make UPC A In Java
Using Barcode drawer for Java Control to generate, create UPC Symbol image in Java applications.
To run JSPs from within VisualAge for Java, you first need to place them in this location For example, you can place the "Hello World" JSP from 4 in the aforementioned directory as hellojsp and access it from the Web browser, as shown in Figure 28-8 Note that the URL uses the same hostname and port as before, and the path is relative to the web directory
Linear Printer In Java
Using Barcode maker for Java Control to generate, create 1D Barcode image in Java applications.
European Article Number 13 Creator In Java
Using Barcode printer for Java Control to generate, create EAN 13 image in Java applications.
Figure 28-8: Running hellojsp from WebSphere Test Environment If you need to debug JSPs (which is likely), you must enable the JSP execution monitoring, under the JSP Monitor Options in the Test Environment Control Center window, as shown in Figure 28-9
Create 2 Of 5 Industrial In Java
Using Barcode drawer for Java Control to generate, create 2/5 Industrial image in Java applications.
Print Code 39 In .NET
Using Barcode encoder for VS .NET Control to generate, create Code 39 image in .NET applications.
Figure 28-9: JSP Monitor Options After you enable JSP monitoring, when you invoke a JSP (by clicking the refresh button on the browser window, for example), VisualAge for Java automatically starts the JSP Execution Monitor window with your JSP, as shown in Figure 28-10 The JSP Execution Monitor is a special debugging environment for JSP Recall that JSP are translated into servlets
Data Matrix Creation In None
Using Barcode creator for Online Control to generate, create ECC200 image in Online applications.
Encoding EAN13 In Java
Using Barcode creator for BIRT Control to generate, create EAN-13 image in BIRT reports applications.
Figure 28-10: The JSP Execution Monitor The JSP Execution Monitor shows four subwindows: The list of JSPs launched by the browser JSP source Servlet Java source Generated HTML The JSP Monitor allows you to step through the Java code and see the HTML content generated dynamically It does not provide all the functionality of the VisualAge for Java debugger but is still useful for debugging JSP To get the JSP running, you must click the Step, Run, or Fast-Forward buttons on the JSP monitor toolbar You can control the JSP Monitor settings via the JSP Execution Monitor Options You can enable or disable JSP monitoring and syntax error retrieval, as well as set the port used for JSP monitoring (Note that this is for internal communication within VisualAge for Java and is not related to the port 8080 used for the HTTP connection from your browser) Summary IBM is considered one of the premier vendors in the space for Java, Java application servers, and e-business The strength of the integration between VisualAge for Java (which has the best support for multiple-person development teams using the Enterprise Edition) and the WebSphere application server, in the form of the WebSphere Test Environment, is of utmost importance to the WebSphere application developer If you plan to use the WebSphere Application Server for deploying your applications, we strongly recommend that you use VisualAge for development and make use of the tools described in this chapter This chapter concludes the discussion of servlets and JSPs On to Enterprise JavaBeans!
USS Code 39 Generator In Objective-C
Using Barcode generator for iPad Control to generate, create Code39 image in iPad applications.
Printing Code 39 Full ASCII In None
Using Barcode generation for Software Control to generate, create Code39 image in Software applications.
Part VI: Developing EJB List 29: Session Beans 30: Entity Beans 31: EJB Transactions and Security 32: Message-Driven Beans 33: IBM EJB Extensions 34: Using EJB in a Multitiered Application
Bar Code Recognizer In Java
Using Barcode scanner for Java Control to read, scan read, scan image in Java applications.
Painting Bar Code In Java
Using Barcode encoder for Android Control to generate, create bar code image in Android applications.
29: Session Beans Overview This chapter begins an in-depth discussion of Enterprise JavaBeans (EJB), a serverside component architecture that enables and simplifies the process of building enterprise-level distributed applications in Java As mentioned in 11, EJBs are categorized into two groups: session beans and entity beans The major distinguishing feature between these two groups is the notion of persistence Session beans represent server-side components that implement business logic but are not persistent, while entity beans are used when the beans' state needs to be persisted beyond a single user's session In 5, you saw a simple state-less "Hello World" session bean 11 elaborated on EJB, the EJB architecture, roles, and framework It described session beans and covered their lifecycles This chapter looks at some examples of session EJBs Through these examples, you will explore how session beans are built and how they are deployed in a WebSphere Application Server The discussion here includes state-less as well as state-ful session beans and covers all aspects of EJBs, including building them, assembling them, and deploying them PageFetch: A State-less Session Bean A state-less session bean does not maintain a conversational state in other words, when invoked, a state-less bean does not maintain any context that is used for subsequent calls One consequence of this is that EJB containers can pool and reuse state-less sessions For example, they can use the same instance for different invocations by different clients This is possible because instances of a state-less session bean are expected to be identical Note that although the bean does not maintain a conversational state, this does not necessarily imply that it does not have any member variable Such variables are, however, of limited use because the client must not rely on their existence (that is, the client must not assume that consecutive method invocations actually use the same bean instance) If a state-less session bean does have state (that is, it contains member variables), these member variables should be declared as final If they're not declared as final, you can run into race condition scenarios if two or more clients of the bean simultaneously access the state of the state-less session bean The state-less session bean example in this section is the PageFetch bean Recall from 11 that one of the motivations for using session EJB is to promote application partitioning Our bean does just that This bean acts on the behalf of the client and retrieves a Web page It then compresses the Web page content and returns it to the client This kind of bean can be useful for retrieving "busy" Web pages, assuming that the EJB server in which the bean is deployed is located in the vicinity of the Web server holding the content (for example, both are on the same LAN) PageFetch Remote Interface The first step in developing a new enterprise bean is defining the remote interface, which defines the contract with the user of the bean In our case, the bean provides one "business" method called getPage This method takes as parameter a Hyptertext Transfer Protocol (HTTP) uniform resource locator (URL), retrieves the page, and returns the page in compressed form The interface is shown here: import javaxejb*; import javarmi*; import javaio*; 502
public interface PageFetch extends EJBObject { byte[] getPage(String url) throws RemoteException, IOException; } The remote interface extends the EJBObject interface that is part of the javaxejb package The class implementing this interface is generated by the EJB container Each method defined in the remote interface must throw the RemoteException exception to deal with cases in which some communication or other problem prevents the method from being invoked This requirement stems from the fact that an EJB method is called using Java Remote Method Invocation (RMI) In addition, each of the parameters and returned values for the method must either be Java primitive types or must implement the Serializable interface Our getPage method also throws an IOException When it accesses the Web page designated by the parameter url, some network failure might occur The reasons for such a failure could range from the URL being malformed to the server or network being down Such an occurrence is indicated by throwing the exception PageFetch Home Interface The next step is to define the home interface for our EJB The home interface is used to create and destroy EJB instances The EJB home interface extends the EJBHome interface defined in the javaxejb package import javaxejb*; import javarmi*; import javaio*; public interface PageFetchHome extends EJBHome { PageFetch create() throws RemoteException, CreateException; } The create method returns the remote interface just defined and does not require any parameters In general, the create method for a home interface can take whatever parameters are required for constructing the bean object In the case of state-less beans, there are usually no such parameters The create method can throw either a RemoteException (due to RMI problems) or CreateException, which indicates that while no problems have been encountered with the communication, the server is still unable to create the bean instance (for example, due to memory limitations) PageFetch Bean Implementation After defining these two interfaces, we can turn to the implementation of our bean The first thing to note is that the bean implements the javaxejbSessionBean interface It does not implement the PageFetch interface (our remote interface) because that interface is implemented by a stub class generated by the EJB container Our bean implementation can still implement other interfaces or extend a class To be able to describe a state -ful bean in the next section, we need to separate the implementation of the bean into two parts First, we define the class PageBean, which 503
implements the SessionBean interface This class has two auxiliary methods that allow loading a Web page and compressing a string: import javaxejb*; import javarmi*; import javai o*; import javautil*; import javanet*; import javautilzip*; public class PageBean implements SessionBean { // Implementation of "business" method public byte[] getPage(String url) throws IOException { // Get the page content StringBuffer buf = loadPage(url); // Compress the page return pack(buf); } // EJB methods public void ejbCreate() { } public void ejbRemove() { } public void ejbActivate() { } public void ejbPassivate() { } public void setSessionContext(SessionContext context) { 504 }
// Given a URL, access the page and return it in a string buffer protected StringBuffer loadPage(String urlString) throws IOException { URL finalUrl = new URL(urlString); StringBuffer stringBuffer = new StringBuffer(); URLConnection urlconnection = finalUrlopenConnection(); urlconnectionsetDoInput(true); urlconnectionsetRequestProperty("User-Agent", "Mozilla/40(compatible; MSIE 55; Windows 98)"); InputStreamReader reader = new InputStreamReader (urlconnectiongetInputStream()); int i = urlconnectiongetContentLength(); int j; char[] inbuf = new char[4096]; for (; (j = readerread(inbuf)) != -1; ) { stringBufferappend(inbuf, 0, j); int k = stringBufferlength(); if (i <= 0) { continue; } if (i <= k) { break; } } return stringBuffer; } /* * Compress the byte stream before sending it It is worth doing * a bit of extra work because the bytes are normally sent over * a slow wireless line */ protected byte[] pack(StringBuffer stringBuffer) throws IOException { String pageStr = stringBuffertoString(); ByteArrayOutputStream s = new ByteArrayOutputStream(); ByteArrayOutputStream st2 = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(s); outwriteBytes(pageStr); 505
outflush(); byte[] full = stoByteArray(); int fullsz = ssize(); Deflater def = new Deflater(); defsetStrategy(DeflaterDEFAULT_STRATEGY); defsetLevel(DeflaterBEST_COMPRESSION); defsetInput(full); DeflaterOutputStream os = new DeflaterOutputStream(st2, def); int len = fullsz; int st = 0; int jump = 1024; byte[] buf = new byte[1024]; while (st < len) { if (len - st < 1024) jump = len - st; Systemarraycopy(full, st, buf, 0, jump); oswrite(buf, 0, jump); st += 1024; } osclose(); return st2toByteArray(); } } The implementation of the EJB methods is empty, mainly because our bean is stateless, so there is not a whole lot to do when it is created, removed, activated, or passivated We implement two protected auxiliary methods that are to be used by subclasses of the class These auxiliary methods account for most of this class The loadPage method loads a Web page whose URL is given and returns a StringBuffer holding the content This method establishes a URL connection and reads the page over this connection The pack method uses the javautilzip package to compress a StringBuffer The next class is the actual implementation of our session bean It extends PageBean and implements our business method getPage By implementing this method, as well as the required methods of the SessionBean interface, our PageFetchBean complies with what the EJB container expects from the bean implementation Note that this method must be declared public and must match the signature defined for it in the remote interface The only allowed difference in terms of the signature is that the bean implementation method need not throw a RemoteException It may want to do so if its own logic requires performing RMI, in which case the method's signatures will be identical However, that is not the case here import javaxejb*; import javarmi*; 506
public class PageFetchBean extends PageBean { // Implementation of "business" method public byte[] getPage(String url) throws IOException { // Get the page content StringBuffer buf = loadPage(url); // Compress the page return pack(buf); } } As noted earlier, the bean's superclass implements two protected auxiliary methods that are used by the single method defined in this class This is allowed because the bean class is an ordinary Java class However, some restrictions stem from the EJB model: The bean cannot start new threads or use the synchronized keyword The bean must not be abstract Static variables can be used only if they are declared final (that is, all static variables are actually constant) These restrictions are not enforced by the compiler, the assembly tools, or the EJB container The developer has the freedom to make mistakes; as in most cases, EJB applications still require careful design PageFetch Bean Assembly and Deployment Bean assembly and deployment is performed using the Application Assembly Tool (AAT) and the Administrative Console, respectively When adding the new bean (as part of a new EJB module), we use the AAT to set the bean parameters You can use the General tab in the New Session Bean dialog box, shown in Figure 29-1, to indicate the EJB name, display name, and description These three are used to assist in the task of deploying the beans Remember that the person deploying the EJB module can be someone other than the application assembler (possibly even someone from a different organization) Other parameters are the remote interface, home interface, and bean class Finally, you can select whether the bean is state-less or state-ful; in our case, it is state -less We also set the transaction attributes for the bean Transaction attributes are discussed in 31 It is worthwhile to note that the AAT is not able to determine automatically whether the bean is state-ful or state-less because being state -less does not necessarily mean that there are no member variables
Figure 29-1: New Session Bean General tab You can use the icons tab (not shown) to associate an icon with the bean This icon will be shown at assembly and deployment time The IBM Extensions tab shown in Figure 29-2 is used to define some WebSphere-specific attributes, such as timeout, caching, and local transactions These are discussed in detail in 33
Figure 29-2: New Session Bean IBM Extensions tab The Bindings tab, shown in Figure 29-3 is used to determine the Java Naming Directory Interface (JNDI) name of the bean This name is important because it is the key by which client-side code can access the bean
Figure 29-3: New Session Bean Bindings tab Deploying this bean to the WebSphere Application Server is straightforward once you've packaged it in an EJB module (repeating the procedure described in 5) The next section presents a small JavaServer Pages (JSP) page that uses the PageFetch bean, so it makes sense to package the EJB and JSP together in one Enterprise Archive (EAR) file An EAR file holds zero or more Web Archive (WAR) files as well as zero or more EJB modules Creating an EAR File To create a new EAR file, choose File | New | Application Then, in the lefthand pane of the Application Assembly Tool, you can import EJB modules into the EAR file by rightclicking the EJB Modules icon and selecting Import Later on, you can also import Web modules (by right-clicking the Web Modules icon and selecting Import) After adding both an EJB module and a WAR module, the AAT should look like the one shown in Figure 29-4
Figure 29-4: AAT with an enterprise application containing a PageFetch EJB Notice that the Web module contains a single JSP It is described in the next section, "PageFetch in Action" The AAT generates an XML-based deployment descriptor The descriptor for our bean is as follows: < xml version="10" encoding="UTF-8" > <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc//DTD Enterprise JavaBeans 11//EN" "http://javasuncom/j2ee/dtds/ejb-jar_1_1dtd"> <ejb-jar id="ejb-jar_ID"> <description>page fetcher</description> <display-name>page</display-name> <enterprise-beans> <session id="Session_1"> <description>Page Fetch1</description> <display-name>PageFetch1</display-name> <ejb-name>PageFetch1</ejb -name> <home>PageFetchHome</home> <remote>PageFetch</remote> <ejb-class>PageFetchBean</ejb-class> <session-type>Stateless</session-type> 511
<transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor id="AssemblyDescriptor_1"> </assembly-descriptor> </ejb-jar> In this XML file, you can clearly see the bean attributes we selected in the AAT: the bean description, display name, remote and home interface, bean implementation class, state-less session type, and transaction type PageFetch in Action To demonstrate our PageFetch bean, we will implement a simple JSP in which a specific page is accessed and the data is decompressed and shown to the user: <%@page import="javaxejb*" %> <%@page import="javaxnaming*" %> <%@page import="javautil*" %> <%@page import="javarmi*" %> <%@page import="javautilzip*" %> <% String str = null; byte[] ret = null; byte[] full = null; try { Properties env = SystemgetProperties(); envput(javaxnamingContextINITIAL_CONTEXT_FACTORY, "comibmwebspherenamingWsnInitialContextFactory"); envput(javaxnamingContextPROVIDER_URL, "iiop://localhost"); InitialContext ic = new InitialContext(env); PageFetchHome home = (PageFetchHome) javaxrmiPortableRemoteObjectnarrow( iclookup("PageFetcher"), PageFetchHomeclass); PageFetch bean = homecreate(); ret = beangetPage("http://wwwviryanetcom"); Inflater inf = new Inflater(); infsetInput(ret); full = new byte[2000000]; len = infinflate(full); str = new String(full, 0, len); } catch (Exception ex) { %> 512
Error <%= ex %> <% } %> <%= str %> The implementation of this JSP is quite straightforward, and the output here is the page as it looks after the content is decompressed and returned from the bean We've chosen to have the JSP access a single constant URL, which is, of course, not practical but it is sufficient for demonstrating the use of our EJB
DiffPageFetch: A State-ful Session Bean Next we turn to state -ful session beans A state-ful session bean holds a conversational state that spans multiple method invocations This implies that the bean has some member variables holding the state, and that the container must typically keep a separate instance for each client because the bean instances are no longer interchangeable For state -less beans, the container can use the same instance for all clients, but for state-ful beans, this management is mandatory What the container typically does is resort to passivating beans placing them in persistent storage and using the same instance for different clients Our example of a state-ful session bean will be similar to the state-less example earlier in the chapter Suppose we are again interested in accessing a Web page, except we expect it to change marginally from one access to another The bean must be able to send back to the client just the changes, thus reducing the amount of network traffic To do that, the bean must maintain a state that is the recent copy of the page itself The only way to implement this functionality with a state-less bean is to send the bean the previous page content as a method parameter at each invocation This is obviously wasteful in network traffic, however, and it defies the purpose of calculating differences and compressing the data The state of a state-ful session bean is determined by the values of its nontransient member variables These variables must be primitive Java types or they must implement the Serializable interface so that the container can place them in external memory State-ful session beans, however, save design work and make for a simpler program State-less session beans produce systems that perform better and are inherently scalable State -less session beans are managed within a pool and are reused by multiple clients They create an environment well suited for enterprise applications in which scalability and performance are the most important factors Stateful session beans, on the other hand, do not support high volumes and are therefore seldom used for production applications DiffPageFetch Remote Interface As with the PageFetch bean, our first step is defining the remote interface Our bean provides two business methods: This first is called getPage, and it retrieves the page and returns it in compressed form This method is used for a full refresh of the page or for obtaining the initial copy of the page Note that the method does not take any parameters An instance of this bean corresponds to a single URL, so the URL is passed to the bean at construction time The second method is getDiff, which returns the difference in the page from the most previous invocation of either getPage or getDiff import javaxejb*; 513
import javarmi*; import javaio*; public interface DiffPageFetch extends EJBObject { byte[] getPage() throws RemoteException, IOException; byte[] getDiff() throws RemoteException, IOException; } One thing you should note about state-ful session beans is that the data stored in them is not really persistent, in the sense that it can withstand a server failure This stands in stark contrast to entity beans, which are guaranteed to be fully persistent using an external data store such as a database You should, therefore, not use state-ful session beans if the state is of any long-term applicative importance For example, if the bean holds some data relating to a financial transaction, you might not want to risk losing your data In our case, a loss will not be too critical, because if the bean state is lost, we can just call getPage again to reload the Web page DiffPageFetch Home Interface Now let's turn to the home interface, which defines the create method In our case, the create method takes one parameter the page URL, which is used for subsequent invocations of getPage and getDiff import javaxejb*; import javarmi*; import javaio*; public interface DiffPageFetchHome extends EJBHome { PageFetch create(String url) throws RemoteException, CreateException; } DiffPageFetch Bean Implementation Our class still implements the javaxejbSessionBean interface because this bean, too, is a session bean We implement the SessionBean interface indirectly by extending the class PageBean This bean has two member variables that hold its state One variable holds the HTTP URL that the bean retrieves, and the other holds the most recent copy of the page retrieved For the sake of completeness, we implement all the methods of the SessionBean interface Note that while the ejbActivate and ejbPassivate methods still remain empty (as we are not holding any resources that need to be freed), the ejbCreate method now takes a parameter that is the URL and stores it in the respective member variable The ejbRemove method clears this variable import javaxejb*; import javarmi*; public class PageFetchBean extends PageBean 514
{ // Conversational State StringBuffer content; String url; // Implementation of "business" method public byte[] getPage() throws IOException { StringBuffer buf = loadPage(url); content = buf; return pack(buf); } public byte[] getDiff() throws IOException { if (content == null) return null; StringBuffer buf = loadPage(url); StringBuffer diff = doDiff(conte nt, buf); content = buf; return pack(diff); } // EJB methods public void ejbCreate(String theUrl) { url = theUrl; content = null; } public void ejbRemove() { content = null; } public void ejbActivate() { } public void ejbPassivate() 515
{ } public void setSessionContext(SessionContext context) { } // Auxiliary Method protected String doDiff(String orig, String next) { int ind1 = 0; int origLen = origlength(); int nextLen = nextlength(); String diff = ""; while (origcharAt(ind1) == nextcharAt(ind1) && ind1 < nextLen && ind1 < origLen) ind1++; if (ind1 == origLen) { if (ind1 == nextLen) return diff; return "start " + ind1 + " end 0%%" + nextsubString(origLen); } int ind2 = 0; while (origcharAt(origLen - ind2 - 1) == nextcharAt(nextLen ind2 - 1) && ind2 < (origLen - ind1) && ind2 < (nextLen - ind1)) ind2++; return "start" + ind1 + " end " + ind2 + "%%" + nextSubString(ind1, nextLen-ind2); } } This bean has two business methods The first is the getPage method, which loads the page and behaves pretty much like the getPage method of the PageFetch bean The difference is that it doesn't take a parameter and instead uses its state variable to determine the target URL The second method is getDiff This method loads the current version of the page and compares it to the old version, sending the differences back to the client For the 516
sake of simplicity, we implement a crude method of calculating the difference We look for the longest common prefix and longest common suffix of the two versions of the page and consider changed whatever is in the middle This is, of course, not generally useful, but it is useful for pages in which only one field changes (such as a status) In any case, this difference calculation method satisfies the bare minimum requirement, making sure that if no changes occur, the difference is empty Note that the getDiff method returns null in case it is called without calling the getPage method first Application assembly and deployment for this bean are quite similar, except that the bean should be designated as state-ful on the General tab of the New Session Beans dialog box Client-side code can make use of this bean by invoking the getPage method and then repeatedly invoking the getDiff method to find out whether any updates have been made to the page After receiving the method's returned value, client-side code needs to uncompress it and do some simple parsing of the prefix and suffix lengths
Understanding the Session Bean Lifecycle 11 discussed the session bean lifecycle This section inspects the session bean lifecycle using the "Hello World" bean from 5, adding debug prints in the various EJB methods Later, we'll look at a state-ful variant of this bean to highlight the differences between the lifecycles of state -less and state-ful session beans State-less Debug Hello World Bean The remote interface for our state-less bean is as follows: import javaxejb*; import javarmi*; public interface HelloDbg extends EJBObject { String getTextMessage() throws RemoteException; } The home interface is shown here: import javaxejb*; import javarmi*; public interface HelloDbgHome extends EJBHome { HelloDbg create() throws RemoteException, CreateException; } These two interfaces are similar to those of the state-less session bean described in 5 The bean implementation is also similar, except printouts have been added: import javaxejb*; import javarmi*; public class HelloDbgBean implements SessionBean 517
{ // Implementation of "business" method public String getTextMessage() { return "Hello World"; } // EJB methods public void ejbCreate() { Systemoutpri ntln("ejbCreate"); } public void ejbRemove() { Systemoutprintln("ejbRemove"); } public void ejbActivate() { Systemoutprintln("ejbActivate"); } public void ejbPassivate() { Systemoutprintln("ejbPassivate"); } public void setSessionContext(SessionContext context) { Systemoutprintln("setSessionContext"); } } We use the following simple client program to invoke this bean, adding an infinite loop to the end so that the program will not exit This way, we can guarantee that resources are not freed (at least not until timeout intervals elapse)
import javaxejb*; import javarmi*; 518
import javautil*; import javaxnaming*; public class HelloClient { public static void main(String args[]) { try { Properties env = SystemgetProperties(); envput(javaxnamingContextINITIAL_CONTEXT_FACTORY, "comibmwebspherenamingWsnInitialContextFactory"); envput(javaxnamingContextPROVIDER_URL, "iiop://localhost"); InitialContext ic = new InitialContext(env); HelloDbgHome home = (HelloDbgHome) javaxrmiPortableRemoteObjectna rrow( iclookup("HelloDbgHome"), HelloDbgHomeclass); HelloDbg bean = homecreate(); Systemoutprintln(beangetTextMessage()); for (;;); } catch (Exception ex) { Systemoutprintln("HelloClient Runtime Error:"); exprintStackTrace(); } } } After you deploy this bean and run the client program, go to the WebSphere log files located in the logs directory under your WebSphere installation root If everything goes smoothly (and the client-side program prints out the "Hello World" message), the WebSphere stdout log should show something similar to this:
Now repeatedly invoke the same program using different windows This creates many concurrent clients that do not die Look at the log file again and notice that it hasn't changed This implies that WebSphere is implementing instance pooling Because the bean is state-less, the same instance can serve any number of clients State-ful Debug Hello World Bean Now we'll take the previous bean and augment it in the following way: we pass it a message string at construction time, and this string is returned when invoking the getMessageText method 519
The remote interface for this bean is shown here: import javaxejb*; import javarmi*; public interface HelloDbg2 extends EJBObject { String getTextMessage() throws RemoteException; } The home interface is as follows: import javaxejb*; import javarmi*; public interface HelloDbgHome2 extends EJBHome { HelloDbg2 create(String m) throws RemoteException, CreateException; } The bean implementation prints out messages in a unique way: import javaxejb*; import javarmi*; public class HelloDbgBean2 implements SessionBean { public String msg; // Implementation of "business" method public String getTextMessage() { return msg; } // EJB methods public void ejbCreate(String m) { msg = m; Systemoutprintln("ejbCreate" + msg); } public void ejbRemove() { Systemoutprintln("ejbRemove 2"); } 520
public void ejbActivate() { Systemoutprintln("ejbActivate 2"); } public void ejbPassivate() { Systemoutprintln("ejbPassivate 2"); } public void setSessionContext(SessionContext context) { Systemoutprintln("setSessionContext 2"); } } The client code for testing this bean is shown next It takes the string used to initialize the bean from the command -line arguments import javaxejb*; import javarmi*; import javautil*; import javaxnaming*; public class HelloClient2 { public static void main(String args[]) { try { Properties env = SystemgetProperties(); envput(ContextINITIAL_CONTEXT_FACTORY, "comibmwebspherenamingWsnInitialContextFactory"); "); envput(javaxnamingContextPROVIDER_URL, "iiop://localhost"); InitialContext ic = new InitialContext(env); HelloDbgHome2 home = (HelloDbgHome2) javaxrmiPortableRemoteObjectnarrow( iclookup("HelloDbgHome2"), HelloDbgHome2class); HelloDbg2 bean = homecreate(args[0]); Systemoutprintln(beangetTextMessage()); for (;;); } catch (Exception ex) { Systemoutprintln("HelloClient Runtime Error:"); 521
exprintStackTrace(); } } } After compiling all the code and deploying the bean, we are ready for repeating the test running several clients and checking the logs We run the client-side program three times with the parameters Test, Another Test, and Yet Another Test The results in the log are shown in the following illustration Notice that the outp ut of the previous execution is still shown in the log, but you can distinguish the new output by the number 2 that follows the setSessionContext invocations and the message string following the ejbCreate invocations As you can see in the log, each client gets its own bean instance, and the container cannot share the same instance among all three beans
Summary
This chapter provided further details on session beans, which are important constructs used to implement server-side code that is either an extension of a client (state-ful beans) or reusable pool-managed components used by multiple clients (state-less beans) In both cases, the client communicates with the bean over RMI, and the EJB container manages access to the bean The chapter presented examples for both state-less and state -ful session beans and described the differences in terms of their lifecycles and how WebSphere manages them Classes and methods built when implementing session beans were discussed, as well as the assembly process and the deployment descriptor Session beans are often used for coding server-side processes Session beans do not normally represent business objects, because they are linked to sessions (hence, their name) and not to persistent data 30 deals with entity beans, which are usually used for implementing persistent business objects
30: Entity Beans Overview 29 discussed Enterprise JavaBeans (EJB) session beans In the original EJB specification, the other half of the EJB realm deals with entity beans Entity beans differ from session beans in that they are persistent objects Persistent objects are stored in external storage such as a disk or a database This chapter will discuss what entity beans are and how they are built, assembled, and deployed It focuses on the persistence of data encapsulated within entity beans Entity beans and session beans are compared to help you ensure that you choose the right bean type for your future projects, and a few examples of how to use entity beans are discussed
Copyright © OnBarcode.com . All rights reserved.