Enterprise JavaBeans Dan Harkey Client/Server Computing Program Director San Jose State University dharkey@email.sjsu.edu www.corbajava.engr.sjsu.edu Session EJBs Implement business logic that runs on an EJB server Are not shared between clients--logical extension of a single client Do not maintain persistent state Two types Stateless--no client specific state is maintained between client method calls Stateful--can maintain conversational state Copyright 2001-2002, Dan Harkey. All rights reserved. Page 1-2
Session EJB Component Contract Serializable (from io) EJBContext EnterpriseBean SessionBean ejbactivate() ejbpassivate() ejbremove() setsessioncontext() YourSessionBean SessionSynchronization afterbegin() aftercompletion() beforecompletion() Optional getcallerprincipal() : Principal getejbhome() : EJBHome getrollbackonly() : boolean getusertransaction() : UserTransaction iscallerinrole(arg0 : String) : boolean setrollbackonly() : void SessionContext getejbobject() ejbcreate() businessmethod() Session EJB Client/Server Contract Remote (from rmi) EJBMetaData EJBObject getejbhome() gethandle() getprimarykey() isidentical() remove() YourRemoteInterface businessmethod() EJBHome getejbmetadata() gethomehandle() remove() YourHomeInterface create() getejbhome() gethomeinterfaceclass() getprimarykeyclass() getremoteinterfaceclass() issession() Handle getejbobject() Serializable (from io) HomeHandle getejbhome() Copyright 2001-2002, Dan Harkey. All rights reserved. Page 3-4
EJB Development Process The Count Stateless EJB Copyright 2001-2002, Dan Harkey. All rights reserved. Page 5-6
Count Stateless Session EJB EJBHome SessionBean CountClient (from statelesssession) sum main() CountHome (from statelesssession) create() EJBObject Count (from statelesssession) CountEJB (from statelesssession) CountEJB() ejbcreate() ejbactivate() ejbpassivate() ejbremove() setsessioncontext() increment() increment() Stateless Session EJB State Diagram Copyright 2001-2002, Dan Harkey. All rights reserved. Page 7-8
Count Stateless Session Interaction Diagram : CountClient JNDI : InitialContext EJB Home : CountHome EJB Object : Count EJB : CountEJB 1: new() 2: lookup(jndihomename) 3: new() 4: create() 5: new() 6: new() 7: setsessioncontext(sessioncontext) 8: ejbcreate( ) 9: increment(sum) 10: increment(sum) Home Interface for Stateless Session EJBs Extends the EJBHome interface. It can also extend other interfaces but must follow the RMI-over-IIOP rules for interface definition Declares one method named create which has no parameters. The create method returns a reference to a remote interface for the bean and throws CreateException and RemoteException Copyright 2001-2002, Dan Harkey. All rights reserved. Page 9-10
Rules for Writing RMI-IIOP Interfaces The interface must extend, either directly or indirectly, the interface java.rmi.remote. This happens automatically for enterprise beans as the EnterpriseBean interface extends java.rmi.remote Each method declaration must satisfy the requirements of a remote method declaration. These requirements are: A remote object declared as a parameter or return value must be declared as a remote interface, not the implementation class of that interface Rules for Writing RMI-IIOP Interfaces (continued) Each method must throw RemoteException Method parameters or return types must be a Java object that is serializable. This includes Java primitive types, remote Java objects, and non-remote Java objects that implement the java.io.serializable interface. A remote interface may also extend another non-remote interfaces, as long as all of the methods (if any) of the interface being extended satisfies the requirements of a remote method declaration. Copyright 2001-2002, Dan Harkey. All rights reserved. Page 11-12
Count Stateless Session EJB: Home Interface // CountHome.java package count.statelesssession; import javax.ejb.ejbhome; import java.rmi.remoteexception; import javax.ejb.createexception; public interface CountHome extends EJBHome { public Count create() throws RemoteException, CreateException; } Remote Interface for Stateless Session EJBs Extends the EJBObject interface. It can also extend other interfaces but again, it must follow the RMI-over-IIOP rules for interface definition. Declares the business methods the enterprise bean will support. These methods must have valid RMI-over-IIOP return types and arguments and must declare RemoteException in addition to any other exceptions thrown by the matching method in the bean class. Copyright 2001-2002, Dan Harkey. All rights reserved. Page 13-14
Count Stateless Session EJB: Remote Interface // Count.java package count.statelesssession; import javax.ejb.ejbobject; import java.rmi.remoteexception; public interface Count extends EJBObject { public int increment(int sum) throws RemoteException; } Class for Stateless Session EJBs May extend other classes or interfaces but bean class or one of it s parent classes must implement the SessionBean interface. The class must be public and must not be abstract or final. It must provide a default, no-argument constructor and it must not have a finalize method. Copyright 2001-2002, Dan Harkey. All rights reserved. Page 15-16
Class for Stateless Session EJBs (continued) The bean class or one of it s parent classes must implement the ejbcreate method (note that ejbcreate returns a void) and any business methods declared in the remote interface. The bean class can implement helper and private methods that are not exposed to clients of the enterprise bean. Count Stateless Session EJB Class // CountBean.java package count.statelesssession; import javax.ejb.*; import java.rmi.remoteexception; public class CountEJB implements SessionBean { // no arg contructor public CountEJB() {} } public void ejbcreate() {} public void ejbactivate() {} public void ejbpassivate() {} public void ejbremove() {} public void setsessioncontext(sessioncontext ctx ) {} public int increment(int sum) { return ++sum; } Copyright 2001-2002, Dan Harkey. All rights reserved. Page 17-18
Count Stateless Session EJB: EJB Deployment Descriptor <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'> <ejb-jar> <description>no description</description> <display-name>ejb1</display-name> <enterprise-beans> <session> <description>no description</description> <display-name>countstateless</display-name> <ejb-name>countstateless</ejb-name> <home>count.statelesssession.counthome</home> <remote>count.statelesssession.count</remote> <ejb-class>count.statelesssession.countejb</ejb-class> <session-type>stateless</session-type> <transaction-type>bean</transaction-type> </session> </enterprise-beans> </ejb-jar> Count Stateless Session EJB: Application Deployment Descriptor <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'> <application> <display-name>countstateless</display-name> <description>application description</description> <module> <ejb>ejb-jar27688.jar</ejb> </module> </application> Copyright 2001-2002, Dan Harkey. All rights reserved. Page 19-20
Count Stateless Session EJB: J2EE RI Specific Deployment Descriptor <?xml version="1.0" encoding="utf-8"?> <j2ee-ri-specific-information> <server-name></server-name> <rolemapping /> <enterprise-beans> <ejb> <ejb-name>countstateless</ejb-name> <jndi-name>statelesssessioncounthome</jndi-name> </ejb> </enterprise-beans> </j2ee-ri-specific-information> Steps Peformed by an EJB Client Look up the enterprise bean s home using JNDI Create an instance of the bean Call business methods on the bean Remove the bean when it is no longer needed Copyright 2001-2002, Dan Harkey. All rights reserved. Page 21-22
Steps Performed to Look Up an EJB's Home Interface Using JNDI Creating an instance of the JNDI InitialContext object Call the lookup method of the InitialContext object to find the bean s home. A string name is passed to the lookup method to identify the bean s home The object that is discovered using the lookup method is cast to the correct type using the narrow method of the PortableRemote object Classes used by a JNDI Client Context (from naming) InitialContext (from naming) InitialContext() addtoenvironment() bind() close() composename() createsubcontext() destroysubcontext() getenvironment() getnameinnamespace() getnameparser() list() listbindings() lookup() lookuplink() rebind() removefromenvironment() rename() unbind() Copyright 2001-2002, Dan Harkey. All rights reserved. Page 23-24
Count Stateless Session EJB: Client (1 of 3) // CountClient.java package count.statelesssession; import count.statelesssession.count; // Count EJB Remote import count.statelesssession.counthome; // Count EJB Home import java.rmi.*; import java.util.*; import java.io.*; import javax.rmi.*; import javax.naming.*; import javax.ejb.*; public class CountClient { public static void main ( String args[] ) { int sum; // current sum CountHome counthome; Count Stateless Session EJB: Client (2 of 3) try { // Get the initial JNDI context System.out.println("Getting initial context"); InitialContext context = new InitialContext(); // Find the home interface and narrow to CountHome Object object = context.lookup("statelesssessioncounthome"); counthome = (CountHome)PortableRemoteObject.narrow(object, CountHome.class); // Create EJB System.out.println("Creating EJB"); Count count = counthome.create(); // Set sum to initial value of 0 System.out.println("Setting sum to 0"); sum = 0; Copyright 2001-2002, Dan Harkey. All rights reserved. Page 25-26
Count Stateless Session EJB: Client (3 of 3) // Calculate Start time long starttime = System.currentTimeMillis(); // Increment 1000 times System.out.println("Incrementing"); for (int i = 0 ; i < 1000 ; i++ ) { sum = count.increment(sum); } // Calculate stop time; print out statistics long stoptime = System.currentTimeMillis(); System.out.println("Avg Ping = " + ((stoptime - starttime)/1000f) + " msecs"); System.out.println("Sum = " + sum); } catch(exception e) { System.err.println("Exception"); System.err.println(e); } } Copyright 2001-2002, Dan Harkey. All rights reserved. Page 27-28