Presentation is loading. Please wait.

Presentation is loading. Please wait.

Design of Distributed Software Chapter 3: Middleware Services Overview of 10 important middleware services and examples in CORBA, RMI, JEE, Web Services.

Similar presentations


Presentation on theme: "Design of Distributed Software Chapter 3: Middleware Services Overview of 10 important middleware services and examples in CORBA, RMI, JEE, Web Services."— Presentation transcript:

1 Design of Distributed Software Chapter 3: Middleware Services Overview of 10 important middleware services and examples in CORBA, RMI, JEE, Web Services and.NET (During the lesson, it will be indicated which parts are highly important and which are not important for the exam)

2 Design of Distributed Software2 Overview Naming Service Event and Notification Service Messaging Service Persistence Service Transaction Service Activation Service Loadbalancing Service Session Tracking Security Service Dynamic Invocation Service

3 Design of Distributed Software 3.1 Naming Service

4 Design of Distributed Software4 Naming Service Definition Binding Service Bind Object References to a textual name Operations: bind / rebind : registration by server lookup / resolve : by client 1. Naming Service

5 Design of Distributed Software5 Java RMI : Registry RMI registry must run on every server computer in the distributed system. maps names to remote object references. a name is represented as a string with format: //computerName:port/objectName class java.rmi.Naming public void bind(String name, Remote obj)  gives an exception when the name is already bound public void unbind(String name, Remote obj) public void rebind(String name, Remote obj)  when the name is already bound, the object reference is overwritten public Remote lookup(String name) public String[ ] list()  returns all names bound in the Registry 1. Naming Service

6 Design of Distributed Software6 JNDI Java Naming and Directory Interface Distributed version of RMI registry applications based on Java technology can store and retrieve named Java objects of any type JNDI provides methods for performing standard directory operations,  associating attributes with objects  searching for objects using their attributes  etc. http://java.sun.com/products/jndi/reference/ codesamples/index.html http://java.sun.com/products/jndi/tutorial/ 1. Naming Service

7 Design of Distributed Software7 CORBA Naming Service Registration of Object References Names are structured in a hierarchy cfr directories in file system files and directories can be assigned a “Kind” id client server a b Naming service 1 2 3 1. Naming Service

8 Design of Distributed Software8 CORBA server Java class with Main method Creates and initializes the ORB Creates an instance of Servant class Registers it to the ORB (through the connect method) Gets a reference for the Naming Service Registers the server to the Naming Service Waits for incoming client requests 1. Naming Service

9 Design of Distributed Software9 CORBA Naming Service NamingService implements an interface called NamingContext rebind for servers to register the remote object references of CORBA objects by name (e.g. rebind (path, Object)) resolve for clients to look them up by name.(e.g. Object = resolve(path) ) The names are structured in a hierarchy, a path is an array of NameComponent (a struct with a name in it) the path starts from an initial context provided by CORBA Naming Service is available in all CORBA implementations 1. Naming Service

10 Design of Distributed Software10 Example ShapeListServer import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class ShapeListServer { public static void main(String args[]) { try{ java.util.Properties props = System.getProperties(); ORB orb = ORB.init(args, props); ShapeListServant shapeRef = new ShapeListServant(orb); orb.connect(shapeRef); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); NameComponent nc = new NameComponent("ShapeList", ""); NameComponent path[] = {nc}; ncRef.rebind(path, shapeRef); orb.run(); } catch (Exception e) {... } } 1. Naming Service

11 Design of Distributed Software11 Example ShapeListClient import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; public class ShapeListClient{ public static void main(String args[]) { try{ java.util.Properties props = System.getProperties(); ORB orb = ORB.init(args, props); org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService"); NamingContext ncRef = NamingContextHelper.narrow(objRef); NameComponent nc = new NameComponent("ShapeList", ""); NameComponent path [] = { nc }; ShapeList shapeListRef = ShapeListHelper.narrow(ncRef.resolve(path)); Shape[] sList = shapeListRef.allShapes(); GraphicalObject g = sList[0].getAllState(); } catch(org.omg.CORBA.SystemException e) {...} } 1. Naming Service

12 Design of Distributed Software12 Advanced Example (1) NameComponent[] contextName= new NameComponent[1]; contextName[0] = new org.omg.CosNaming.NameComponent(); contextName[0].id = "CORBA_test"; contextName[0].kind = “ODS_course"; // Note on kind: The kind field is used to indicate the type // of the object. This is to avoid conventions such as that used // by files (name.type -- e.g. test.ps = postscript etc.) org.omg.CosNaming.NamingContext testContext; try { // Bind the context to root, and assign testContext to it: testContext = rootContext.bind_new_context(contextName); } catch(org.omg.CosNaming.NamingContextPackage.AlreadyBound ex) { // If the context already exists, this exception will be raised. // In this case, just resolve the name and assign testContext // to the object returned: org.omg.CORBA.Object tmpobj; tmpobj = rootContext.resolve(contextName); testContext = NamingContextHelper.narrow(tmpobj); if (testContext == null) { System.err.println("Failed to narrow naming context."); return false;} } 1. Naming Service

13 Design of Distributed Software13 Advanced Example (2) // Bind the object (obj) to testContext, naming it Echo: org.omg.CosNaming.NameComponent[] objectName=new org.omg.CosNaming.NameComponent[1]; objectName[0] = new org.omg.CosNaming.NameComponent(); objectName[0].id = "Echo"; objectName[0].kind = "Object"; // Bind obj with name Echo to the testContext: try { testContext.bind(objectName,obj); } catch(org.omg.CosNaming.NamingContextPackage.AlreadyBound ex) { testContext.rebind(objectName,obj); } // Note: Using rebind() will overwrite any Object previously bound // to /CORBA_test.ATLANTIS_tests with obj. // Alternatively, bind() can be used, which will raise a // CosNaming::NamingContext::AlreadyBound exception if the name // supplied is already bound to an object. 1. Naming Service

14 Design of Distributed Software14 Running server and client with NS Start orbd : UNIX command shell : $ orbd -ORBInitialPort 1050 -ORBInitialHost nameserverhost & MS-DOS system prompt : start orbd -ORBInitialPort 1050 -ORBInitialHost nameserverhost Start the Echo server : UNIX command shell : $ java echoServer -ORBInitialPort 1050 -ORBInitialHost nameserverhost & MS-DOS system prompt : start java echoServer -ORBInitialPort 1050 -ORBInitialHost nameserverhost Result: echoServer ready and waiting... Run the client application : $ java echoClient -ORBInitialPort 1050 -ORBInitialHost localhost ResuIt: I said, “Hello!“. The Object said, “Hello!" 1050 = port on which Naming Service listens 1. Naming Service

15 Design of Distributed Software15 CORBA Trading Service Trading Service: Comparable to Naming Service Allows objects to be located by attribute : directory service Database: service types and attributes -> remote object references Clients specify :  Constraints on the values of attributes  Preferences for the order in which to receive matching offers 1. Naming Service

16 Design of Distributed Software16 Other Name Services Web Services URIs are used to locate the web services DNS (Domain Name Service).Net No distributed directory, but a local directory on each participating machine Based on Web Services 1. Naming Service

17 Design of Distributed Software 3.2 Event and Notification Service

18 Design of Distributed Software18 Events and Notifications data Method 1 Method 2 Method 3 A Client Event or Notification Method Call 2. Event/Notification Service

19 Design of Distributed Software19 Publish - Subscribe paradigm Object that generates events : publishes the type of events it will make available Objects that want to receive notifications: subscribe to the types that are of interest (or: register) Event types : refer to different operations of object generating events Objects that represent events = notifications Asynchronous communication between publishers and the subscribers 2. Event/Notification Service

20 Design of Distributed Software20 Event type Each event has attributes: Name or identifier of generating object Operation Parameters Time Sequence Number Subscribing = specify event types criterion about attribute values 2. Event/Notification Service

21 Design of Distributed Software21 Architecture for distributed event notification observer Event service observer subscriber object of interest 3. object of interest 1. 2. notification Notification : object that contains information about event Observer : decouple the object of interest from its subscribers (forwarding, filtering, patterns of events, notification mailbox) 2. Event/Notification Service

22 Design of Distributed Software22 CORBA Event Service Defines interfaces for: Suppliers Consumers Push (by supplier to consumer) PushConsumer interface {push (...);} Consumer register their object references Pull (by consumer from supplier) PullSupplier interface { pull (...); } Suppliers register their object references 2. Event/Notification Service

23 Design of Distributed Software23 Event Service (2) Event Channels Allow multiple suppliers to communicate with multiple consumers Buffer between suppliers and consumers EventChannel interface implemented by objects in event server Chains of event channels 2. Event/Notification Service

24 Design of Distributed Software24 Notification Service Extends Event Service with filters Notifications have datatype ( any ) Event Consumers may use filters  Specify events they are interested in  Proxies forward notifications to consumers according to constraints specified in filters Event Suppliers can discover the events the consumer are interested in Event Consumers can discover a set of event types (subscribe to new event) Configure properties of Event Channel  Reliability, priority of events, required ordering, policy for discarding stored events Event type repository 2. Event/Notification Service

25 Design of Distributed Software25 Eventing in other technologies Java RMI / JEE write callbacks Java Message Service Web Services WS Eventing : W3C draft defines a protocol for eventing http://www.w3.org/Submission/WS-Eventing/.Net Framework support comparable to JEE 2. Event/Notification Service

26 Design of Distributed Software Intermezzo : EJB : Enterprise Java Beans I1. Architecture I2. Types of EJBs I3. Stateless Session Beans I4. Stateful Session Beans

27 Design of Distributed Software27 Introduction EJB components have the remote capabilities of RMI or CORBA objects are JavaBeans components :  allow introspection of properties  JavaBeans “design patterns” for component layout (properties, accessors, modifiers, events,...) architecture provides non-functional features  component life cycle management,  transaction processing,  security handling,  persistence  remotability  timer  state management  resource pooling  messaging I1. Architecture

28 Design of Distributed Software28 Introduction EJB-container EJB container hosted on application server java beans interactions mediated by container interactions : - with other beans locally (same container) remotely (different container) - with other JEE components (servlets, jsp,...) - with client - with other resources (e.g. database) I1. Architecture

29 Design of Distributed Software29 Architecture browser webserver Application Server applet Database system Web container EJB container WebserverClient Servlet JSP EJB Web container services component life cycle management handle communication with webserver HTTP servlet session tracking EJB container services component life cycle management transaction service security handling resource pooling JEE client I1. Architecture

30 Design of Distributed Software30 Server side architecture Servlet JSP EJB Java EE container Web containerEJB container Persistence provider External Resource Entity business logic persistent application data [POJO] persistent application data [RDBMS] I1. Architecture

31 Design of Distributed Software31 Benefits (1) simplify the development of large, distributed applications. the EJB container provides system-level services to enterprise beans, the bean developer can concentrate on solving business problems. the EJB container--not the bean developer--is responsible for system-level services such as transaction management and security authorization. I1. Architecture

32 Design of Distributed Software32 Benefits (2) the client developer can focus on the presentation of the client because the beans--and not the clients--contain the application's business logic, the clients are thinner (important for clients that run on small devices) enterprise beans are portable/reusable components the application assembler can build new applications from existing beans. these applications can run on any compliant J2EE server. I1. Architecture

33 Design of Distributed Software33 EJB Views EJBs have two possible views: The local view  Used by local clients (only EJBs in the same container) The remote view  Used by remote clients (not limited to EJBs; can include Servlets, etc.)  Can also be used by clients in the same container A bean can implement both local and remote views I1. Architecture EJB local remote EJB

34 Design of Distributed Software34 The Local View New since EJB 2.0 spec Parameters are passed by reference The client and the EJB must reside in the same container The client itself must be an EJB Much faster than remote view No network latency No marshalling/unmarshalling No need to worry about remote exceptions I1. Architecture

35 Design of Distributed Software35 The Local View (cont.) 1. Client looks up a bean object - using Java Naming and Directory Interface (JNDI) - using Dependency Injection (DI) 2. Client finds EJB 3. Client uses EJB business methods from the local interface I1. Architecture client (EJB) InitialContext JNDI service EJBLocalObject Bean Instance EJB container

36 Design of Distributed Software36 The Remote View Based on Java RMI Uses remote interface, stub, and tie (skeleton) Works with RMI/IIOP (“RMI over IIOP”) Vendor-specific protocols are also possible Parameters are passed by value All parameter and return-value types must be serializable Provides location independence and flexibility API design consideration (method granularity) : One method that does several related tasks is more effective than several smaller methods I1. Architecture

37 Design of Distributed Software37 The Remote View (cont.) Same 3 steps as before, but taken over the network: I1. Architecture client (EJB) InitialContext JNDI service client container remote stub EJBObject Bean Instance EJB container remote tie

38 Design of Distributed Software Intermezzo EJB : Enterprise Java Beans I1. Architecture I2. Types of EJBs I3. Stateless Session Beans I4. Stateful Session Beans

39 Design of Distributed Software39 Types of EJBs I2. Types of EJBs EJBs Session BeansEntitiesMessage Beans - session related object - always associated to one single client at most - types stateful : “conversational state” stateless - “real life” object - mostly associated to “row in database” - persistent - NEW since EJB3.0 [replace (very) complex EntityBeans] - NOT managed by EJB container - asynchronous message handling - new since J2EE 1.3 synchronousasynchronous

40 Design of Distributed Software40 Session EJBs A session bean instance is: A non-persistent object Implements some business logic (“procedural component”) Runs on the server Not shared among multiple clients I2. Types of EJBs

41 Design of Distributed Software41 Stateful Session EJBs A stateful session bean maintains a state values of its instance variables also called : conversational state The state is relevant only for a single client cannot be seen by other clients The state is not persistent does not survive a server shutdown when the client removes the bean or terminates, the session ends and the state disappears Canonical example: ShoppingCart I2. Types of EJBs

42 Design of Distributed Software42 Stateless Session EJBs Conceptually, the same as stateful session EJBs No state http-style request – reply interaction Can have fields, but they are not unique to any client Basically, it’s an optimization trick: Since the container knows the bean has no state, it can: Use a single bean instance (While each client thinks it has its own copy) Destroy/re-instantiate on the fly Redirect requests to different instances (load balancing) Example: CurrencyConversionBean I2. Types of EJBs

43 Design of Distributed Software43 Entities Object-oriented view of entities stored in persistent storage Normally, each entity represents a row in a relational DB table Persistence code generated through ORM-tool (Object-Relational Mapping, e.g. Hibernate, TopLink) A single instance (on the server) can be accessed by multiple clients Unlike stateful session EJBs Each instance must be uniquely identifiable by means of a primary key. I2. Types of EJBs

44 Design of Distributed Software44 Message Driven Beans (MDBs) process messages asynchronously messages originate from JMS (Java Messaging Service)-compliant system message can be sent by any source other EJB other JEE component (e.g. web component) any other (legacy) component indirectly accessed by clients no interface, use message instead similar to stateless session bean all beans are equivalent (pooling !) – no client specific state no conversational state maintained can handle requests from multiple clients I2. Types of EJBs JMS queue MDB Client

45 Design of Distributed Software45 Bean packaging Bean contents deployment descriptor (XML) [deploytool] enterprise bean class (bytecode) [programmer] interfaces [IDE] local/remote helper classes (utilities/exceptions/...) [programmer] I2. Types of EJBs EJB JAR-file JEE-application EJB JAR-file WAR-file EAR-file deployable units to application server

46 Design of Distributed Software46 Deployment descriptor I2. Types of EJBs -essentially contains meta-data of application/component - cumbersome to construct/maintain - alternative : Annotations BUT : deployment descriptor can still override annotations POJO JEE component

47 Design of Distributed Software47 Naming Conventions I2. Types of EJBs syntaxexample bean name BeanExampleBean bean class BeanExampleBean remote [component] interface RemoteExampleRemote local [component] interface LocalExampleLocal

48 Design of Distributed Software Intermezzo EJB : Enterprise Java Beans I1. Architecture I2. Types of EJBs I3. Stateless Session Beans I4. Stateful Session Beans

49 Design of Distributed Software49 Session Bean services I3. Stateless SB Thread safe and performant concurrency (techniques : pooling, session management, passivation – activation) Remoting Exposure as Web Service Transaction Management Security Management Timer services (scheduling)

50 Design of Distributed Software50 Session Bean in EJB2.0 I3. Stateless SB implements the SessionBean + BeanInterface interface is public is NOT abstract or final at least one ejbCreate method implements required business methods (component i’face) does NOT have a finalize method public class MyBean implements javax.ejb.SessionBean,BeanInterface { private javax.ejb.SessionContext context; public void setSessionContext(javax.ejb.SessionContext aContext) { context = aContext; }// called when created public void ejbActivate() { }// called when activated public void ejbPassivate() {}// called when passivated public void ejbRemove() {}// called when removed from server public void ejbCreate() { }// called when created // business methods }

51 Design of Distributed Software51 Session Bean in EJB3.0 I3. Stateless SB @Stateful public class MyBean implements BeanInterface { @Resource SessionContext context; @PostContruct //...// called when created @PostActivate //...// called when activated @PrePassivate //...// called when passivated @PreDestroy //...// called when removed from server // remote business method // local business method } SIMPLE Plain Old Java Object WITH annotations...

52 Design of Distributed Software52 Session Bean in EJB3.0 Programming Rules I3. Stateless SB - Bean MUST implement at least one business interface - methods must NOT start with “ ejb ” - business methods are public, NOT final, NOT static - @Remote : arguments and return value MUST implement Serializable - Class MUST be concrete, NOT final - MUST have no-arg constructor (can be default no-arg constructor) - can subclass other Session Bean, or POJO BUT : mind “inheritance of annotations” - @Stateless, @Stateful -> NOT inherited - lifecycle call back method annotations -> inherited

53 Design of Distributed Software53 Session Context During creation, the EJB instance is handed a Session Context object An instance of javax.ejb.SessionContext Typically set using DI @Resource SessionContext context; The context object contains: Security-related information  getCallerPrinciple, isCallerInRole Transaction-related information and methods  getUserTransaction, get/setRollbackOnly EJB Object-related information  getEJBObject, getEJBLocalObject  The former must be returned instead of this, whenever required I3. Session EJBs

54 Design of Distributed Software54 Stateless Session Bean usage I3. Stateless SB Client 1 Client 2 Client 3 Bean Pool Instance 1 Instance 2 Client 4 EJB container

55 Design of Distributed Software55 Session Bean interfaces I3. Stateless SB SB1 SB2 EJB container Local interface ( @Local ) Remote interface ( @Remote ) Web Service interface ( @WebService ) Stateless Session Beans ONLY !

56 Design of Distributed Software56 Session Bean interfaces I3. Stateless SB Interface can ONLY be annotated with 1 SB interface type NOT allowed : @WebService @Remote public interface MyInterface { public int f(int i); } Allowed : public interface MyInterface { public int f(int i); } @Remote public MyRemoteInterface extends MyInterface {} @WebService public MyWSInterface extends MyInterface {}

57 Design of Distributed Software57 Example : a random bean I3. Stateless SB business methods random() : give a random int number between 0 and 10 random(int n) : idem between 0 and n package random; import javax.ejb.Remote; @Remote public interface RandomRemote { public int random(); public int random(int n); } RandomRemote.java

58 Design of Distributed Software58 Coding the RandomBean Coding the RandomBean I3. Stateless SB package random; import javax.ejb.Stateless; @Stateless public class RandomBean implements random.RandomRemote { public RandomBean() { } public int random() { return random(10); } public int random(int n) { return (int)(Math.random()*n); } RandomBean.java

59 Design of Distributed Software59 Using Java 5 I3. Session Beans Using NetBeans 1.create JEE application File->New Project ->Enterprise -> Enterprise Application ->Next Project Name : RandomApp -> Finish 3 projects are created : - enterprise application project[RandomApp] - ejb-project[RandomApp-ejb] - web-project[RandomApp-war] 2. create the bean EJBModule -> New -> SessionBean EJB name : Random package : random -> stateless -> remote -> Finish 2 source files are created RandomBean.java, RandomRemote.java 3. add business methods RandomBean [right click in source code] -> EJB Methods -> Add Business Method 4. deploy the application/bean RandomApp -> Run

60 Design of Distributed Software60 Example : a random bean I3. Stateless SB package random; import javax.ejb.Remote; @Remote public interface RandomRemote { int random(); int random(int parameter); } RandomRemote.java IDE-generated RandomBean.java as before IDE-generated (except for business methods)

61 Design of Distributed Software61 EJB-clients I3. Stateless SB different types of clients -container clients (JEE components) -> support ! - app client (client side component) - other EJB (same container or not) - web component (JSP/Servlet) (other container) -[non-container clients (standalone)] Steps : 1. Client gets reference to EJB (JNDI or not) 2. Invocation of business methods on session bean 3. Client calls remove-method (stateful session beans only)

62 Design of Distributed Software62 Client 1 : Application Client I3. Stateless SB contains all info on EJB to allow client code to run in separate JVM links to JEE server to resolve JNDI references Two jar-files JAR 1 : client deployment descriptor client code class files generic : runs with all Application Servers JAR 2 : stubs class files to communicate with Application Server specific to Application Server generated by deploytool

63 Design of Distributed Software63 Client 1 : Application Client I3. Stateless SB 1.use dependency injection to resolve EJB-reference @EJB MyEJB ejbREF; 2.invoke business methods ejbREF.method1(par1); ejbREF.method2(); //... typical client code sequence Application client in same enterprise application

64 Design of Distributed Software64 Coding the AppClient Coding the AppClient I2. Session Beans package randomappclient; import javax.ejb.EJB; import random.*; public class Main { @EJB public static RandomRemote r; public static void main(String[] args) { System.out.println("Starting appclient..."); System.out.println(r.random(10000)); } } Main.java INJECTION ONLY DONE FOR - statics - in class Main

65 Design of Distributed Software65 Using Java 5/6 I2. Session Beans Using NetBeans 1.create JEE application File->New Project ->Enterprise -> Enterprise ApplicationClient ->Next Project Name : RandomAppClient -> Finish 2.code the client - create reference to bean remote interface - invoke business methods on bean 3.Copy necessary packages to source code Resolve imports (Alt-Shft-F) 4.Add appclient project to JEE application project (RandomApp) RandomApp -> Add JavaEE module -> RandomAppClient 5.Deploy the JEE application RandomApp -> Run Project 6. Deploy and run the client project RandomAppClient -> Run Project

66 Design of Distributed Software66 Client 2 : Standalone Application Client I3. Stateless SB 1.Retrieve InitialContext Context ctx = new InitialContext(); 2.Perform explicit JNDI lookup (MyRemote) ejbRef=(MyRemote)ctx.lookup(“ ”) 3.Invoke business methods on bean ejbREF.method1(par1); ejbREF.method2(); //... typical client code sequence Application client separately from enterprise application USE mappedName (global JNDI names !)

67 Design of Distributed Software67 Using Java 5/6 I2. Session Beans Using NetBeans 1.create JEE application File->New Project ->Enterprise -> Enterprise ApplicationClient ->Next Project Name : RandomAppJNDIClient -> Finish 2.code the client - retrieve initial context - create reference to bean remote interface using JNDI lookup - invoke business methods on bean 3.Add libraries (EJB JAR-files to the project) RandomAppClient -> Properties -> Libraries -> [Navigate to EJB- JAR] -> Add Jar Files Resolve imports (Alt-Shft-F) 4.Deploy the JEE application RandomApp -> Run Project 5. Deploy and run the client project RandomAppClient -> Run Project

68 Design of Distributed Software68 Example : Random Bean I3. Stateless SB @Stateless(mappedName=" Random ") public class RandomBean implements random.RandomRemote { public RandomBean() { } public int random() { return random(10); } public int random(int n) { return (int)(Math.random()*n); } package randomappclientjndi; import javax.ejb.EJB; import javax.naming.*; import random.RandomRemote; public class Main { public Main() {} public static void main(String[] args) throws Exception { System.out.println("Starting appclient..."); Context ctx = new InitialContext(); RandomRemote r=(RandomRemote)ctx.lookup(" Random "); for(int i=0;i<10;i++) System.out.println(r.random(10000)); } Application client Random Bean

69 Design of Distributed Software69 Running the client I3. Stateless SB - from IDE - using appclient tool -> JAR file for distribution -> start appclient $AppServerInstall\bin\appclient –client

70 Design of Distributed Software70 Client 3 : Web Client I3. Stateless SB Create jsp or servlet -> WebModule -> New -> JSP or Servlet Compile web resource Add to war (IDE or deploytool) Deploy application Set context root for web application (default index.jsp) Browse to indicated URL (e.g. http://localhost:8080/RandomApp-war/ )

71 Design of Distributed Software71 Client 3 : Web Client I3. Stateless SB JSP client <%@ page import="random.*, javax.ejb.*, java.math.*, javax.naming.*, java.rmi.RemoteException" %> <%! private RandomRemote bean = null; public void jspInit() { try { InitialContext ic = new InitialContext(); bean=(RandomRemote)ic.lookup(RandomRemote.class.getName()); } catch (Exception ex) { System.out.println("Exception caught : "+ ex.getMessage()); } public void jspDestroy() { bean = null; } %> index.jsp or “ Random ”

72 Design of Distributed Software72 Client 3 : Web Client I3. Stateless SB Random Values Random Values Enter upperbound: <% String upper = request.getParameter("upper"); if ( upper != null ) { int n = Integer.parseInt(upper); %> Random value smaller than : <% } %> index.jsp

73 Design of Distributed Software73 Client 3 : Web Client I3. Stateless SB Servlet client private random.RandomRemote lookupRandomBean () { @EJB private RandomRemote randomBean; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println(" "); out.println(" Servlet RandomServlet "); out.println(" "); out.println("A random value < 100 : "+randomBean.random(100)); out.println(" "); out.close(); } // Servlet methods } automatically generated DI for EJB lookup (right-click in Servlet body-> Enterprise Resources -> Call Enterprise Bean-> Select the bean to look up) RandomServlet.java

74 Design of Distributed Software74 JEE standard example Currency Converter I3. Stateless SB package converter; import java.math.BigDecimal; import javax.ejb.Stateless; @Stateless public class CurrencyConverterBean implements CurrencyConverterRemote { BigDecimal yenRate = new BigDecimal("121.6000"); BigDecimal euroRate = new BigDecimal("0.0077"); public CurrencyConverterBean() { } public BigDecimal dollarToYen(BigDecimal dollars) { BigDecimal result = dollars.multiply(yenRate); return result.setScale(2, BigDecimal.ROUND_UP); } public BigDecimal yenToEuro(BigDecimal yens) { BigDecimal result = yens.multiply(euroRate); return result.setScale(2, BigDecimal.ROUND_UP); } } CurrencyConverterBean.java

75 Design of Distributed Software75 Currency Converter : remote interface package converter; import java.math.BigDecimal; import javax.ejb.Remote; @Remote public interface CurrencyConverterRemote { BigDecimal dollarToYen(BigDecimal dollars); BigDecimal yenToEuro(BigDecimal yens); } I3. Stateless SB CurrencyConverterRemote.java

76 Design of Distributed Software76 Application Client package currencyconverterclient; import converter.CurrencyConverterRemote; import java.math.BigDecimal; import javax.ejb.EJB; public class Main { @EJB private static CurrencyConverterRemote currencyConverterBean; public Main() { } public static void main(String[] args) { BigDecimal param = new BigDecimal("100.00"); BigDecimal amount=currencyConverterBean.dollarToYen(param); System.out.println(amount); amount = currencyConverterBean.yenToEuro(param); System.out.println(amount); } } I3. Stateless SB Main.java

77 Design of Distributed Software EJB : Enterprise Java Beans I I1. Architecture I2. Types of EJBs I3. Stateless Session Beans I4. Stateful Session Beans

78 Design of Distributed Software78 Stateful Session Bean usage I4. Stateful SB Client 1 Client 2 Client 3 Instance 1 Client 4 EJB container Instance 2 Instance 3 Instance 4 State 1 State 2 State 3 State 4 typical usage : multi-step workflows

79 Design of Distributed Software79 Stateless Session Bean : Life Cycle I4. Stateful SB Does Not Exist Ready 0. newInstance() 1. Dependency Injection 2. @PostConstruct 1.@Remove /Timeout 2.@PreDestroy Passive @PrePassivate @PostActivate Timeout business method invocation @Remove : called by client to indicate removal

80 Design of Distributed Software80 Activation and Passivation During the bean’s lifecycle, the container may decide to passivate it (LRU-algorithm) Normally done to free up memory and other resources Bean is notified immediately before passivation by lifecycle method @PrePassivate In this method, the bean should: Release any heavy-duty resources it might be holding  Open files, database connections, etc. Nullify fields that should not be serialized (cache, etc.) Copy state into Serializable variables If the bean is referenced by client while passivated, the container activates it. Bean is notified by @PostActivate immediately after de- serialization Its chance to restore all field values, resources, etc. I4. Stateful SB

81 Design of Distributed Software81 Stateful Session Beans Programming Rules I4. Stateful SB Additional Rules - @Stateful (instead of @Stateless ) identical (except for name) als @Stateless - instance variables must be primitive/ Serializable - @Remove for “friendliness” - provide additional methods (wrt stateless beans) : @PostActivate @PrePassivate

82 Design of Distributed Software82 Simple Example : a random bean business methods random() : give a random int number between 0 and 10 random(int n) : idem between 0 and n getSum() : get sum of all values produced in this session getUser() : get user of this session setUser() : set user of this session I4. Stateful SB

83 Design of Distributed Software83 Random State Bean : remote interface package randomstate; import javax.ejb.Remote; import javax.ejb.Remove; @Remote public interface RandomStateRemote { int random(int n); int random(); void setUser(String name); String getUser(); int getSum(); @Remove void remove(); } RandomStateRemote.java I4. Stateful SB

84 Design of Distributed Software84 Random State Bean : Bean Class package randomstate; import javax.ejb.Remove; import javax.ejb.Stateful; @Stateful public class RandomStateBean implements RandomStateRemote { private String userName; private int sum=0; public RandomStateBean() {} public int random(int n) { int r=(int)(n*Math.random()); sum+=r; return r; } public int random() {return random(10);} public void setUser(String name) {userName=name;} public String getUser() {return userName;} public int getSum() {return sum;} @Remove public void remove() {userName=null;sum=0;} } RandomStateBean.java I4. Stateful SB session related state variables friendly removal

85 Design of Distributed Software85 Random State Bean : multisession client package twosessionclient; import javax.ejb.EJB; import randomstate.RandomStateRemote; public class Main { @EJB private static RandomStateRemote george; @EJB private static RandomStateRemote john; public Main() {} public static void main(String[] args) { george.setUser("George"); john.setUser("John"); for(int i=0;i<5;i++) System.out.println("1:"+george.random(10)+"\t2:"+john.random(100)); System.out.println(george.getUser()+" : "+george.getSum()); System.out.println(john.getUser()+" : "+john.getSum()); george.remove(); john.remove(); } Main.java I4. Stateful SB 1:52:8 1:02:25 1:62:43 1:32:34 1:12:1 George:15 John:111 sample run

86 Design of Distributed Software86 J2EE canonical example : CartBean package cart; import java.util.ArrayList; import javax.ejb.Remove; import javax.ejb.Stateful; @Stateful public class CartBean implements CartRemote { private String customerName; private String customerId; private ArrayList contents=new ArrayList (); public CartBean() {} public void initUser(String person) throws CreateException { initUser(person,"0"); } public void initUser(String person, String id) throws CreateException { if(person==null) throw new CreateException("Null person not allowed."); else customerName=person; customerId=id; } I4. Stateful SB CartBean.java

87 Design of Distributed Software87 J2EE canonical example : CartBean public void addBook(Book b) { contents.add(b); } public void removeBook(Book b) throws BookException { if(contents.contains(b)) contents.remove(b); else throw new BookException("Book not in shopping cart !"); } public ArrayList getContents() { return contents; } @Remove public void remove() { contents=null; customerName=null; customerId=null; } I4. Stateful SB CartBean.java

88 Design of Distributed Software88 Cart Bean : Remote Interface package cart; import javax.ejb.Remote; import javax.ejb.Remove; @Remote public interface CartRemote { void initUser(String person) throws CreateException; void initUser(String person, String id) throws CreateException; void addBook(Book b); void removeBook(Book b) throws BookException; java.util.ArrayList getContents(); @Remove void remove(); } I4. Stateful SB CartRemote.java

89 Design of Distributed Software89 Cart Bean : Utility Classes package cart; import java.io.Serializable; public class Book implements Serializable { private String title; private String author; public Book(String t,String a) { title=t;author=a; } public String toString() { return " "; } public boolean equals(Object o) { if(o instanceof Book) { Book a=(Book)o; return (((a.author).equals(author))&&((a.title).equals(title))); } else return false; } I4. Stateful SB Book.java MUST be Serializable !

90 Design of Distributed Software90 Cart Bean : Utility Classes package cart; import java.rmi.RemoteException; public class BookException extends RemoteException{ public BookException(String message) { super(message); } } I4. Stateful SB BookException.java MUST be RemoteException ! package cart; import java.rmi.RemoteException; public class CreateException extends RemoteException{ public CreateException(String message) { super(message); } CreatekException.java

91 Design of Distributed Software91 CartBean Client package shoppingcartclient; import cart.*; import java.util.ArrayList; import javax.ejb.EJB; public class Main { @EJB private static CartRemote shoppingCart; public Main() {} public static void main(String[] args) { try { shoppingCart.initUser("MyFavouriteUser"); } catch(Exception e) {System.err.print(e);} shoppingCart.addBook(new Book("The Martian Chronicles","Jane Austin")); shoppingCart.addBook(new Book("2001 A Space Odyssey","George Lewanski")); shoppingCart.addBook(new Book("The Left Hand of Darkness","Unknown")); ArrayList bookList = new ArrayList (); bookList = shoppingCart.getContents(); System.out.println(bookList); try { shoppingCart.removeBook(new Book("Alice in Wonderland","Lewis Carrol")); shoppingCart.remove(); } catch(Exception e) {System.out.println(e);} } I4. Stateful SB Main.java

92 Design of Distributed Software 3. Messaging Service 1. Messaging concepts 2. Message Driven Beans

93 Design of Distributed Software93 Messaging architecture 3.1 Messaging concepts supports communication between components/subsystems loosely coupled (no interface to conform to) asynchronous -> can be used to couple “fast” and “slow” subsystems JMS also supports synchronous communication (with timeout) message sender = producer send message Message Oriented Middleware [MoM] = reliable man-in-the-middle acknowledge store retrieve message receiver = consumer send message “deliver” acknowledge

94 Design of Distributed Software94 Messaging models 3.1 Messaging concepts point-to-point (PTP) publish-subscribe (Topic) producer Queue consumer receiver delivered to 1 online consumer with correct destination ID producer Topic consumer delivered to all consumers subscribed to the topic consumer

95 Design of Distributed Software95 JMS-basics 3.1 Messaging concepts “Java Messaging Service” = messaging API supported by JEE - resembles JDBC API JMS message message headers message properties message body common set of (key,value) pairs - JMSTimestamp - JMSCorrelationID - JMSReplyTo - JMSMessageID application defined (key,value) pairs [ String, Object, primitive no char ] message payload -ObjectMessage -BytesMessage -MapMessage -StreamMessage -TextMessage

96 Design of Distributed Software96 JMS programming model 3.1 Messaging concepts Connection Factory Connection long-lived logical relation client-provider expensive to create resource hungry Session short-lived logical relation inexpensive to create cheap ! Destination creates message creates ProducerConsumer Destination

97 Design of Distributed Software97 JMS message delivery model 3.1 Messaging concepts Designed for reliable message communication : Use of acknowledgements DeliveryMode can be specified to indicate message persistence Priority levels can be specified Support for transactions (default : auto-commit)

98 Design of Distributed Software 3. Messaging Service 1. Messaging concepts 2. Message Driven Beans

99 Design of Distributed Software99 Message Driven Beans 3.2 MDBs client producer 1 MDBean Pool Instance 1 Instance 2 EJB container client producer 2 client producer 3 Services offered - safe multithreading and pooling - simplified coding (wrt native JMS) message destination Instance 3 Instance 4

100 Design of Distributed Software100 Message Driven Beans Programming Rules 3.2 MDBs Class - must implement message listener interface (can be declared by annotation) - concrete (not absract), non-final - POJO, not subclass of MDB - public Methods -MUST have no-arg constructor - no finalizer (use @PreDestroy ) - MUST have message listener methods ( public, NOT static, NOT final ) - NO runtime exceptions (terminates MDB)

101 Design of Distributed Software101 @MessageDriven : Listener @MessageDriven( name=“MyBean”, messageListenerInterface=“javax.jms.MessageListener”) public class MyBeanMDB {... } OR @MessageDriven(name=“MyBean”) public class MyBeanMDB implements MessageListener {... } OR use deployment descriptor 3.2 MDBs

102 Design of Distributed Software102 @MessageDriven : ActivationConfigs allows for system-specific configuration public @interface ActgivationConfigProperty { String propertyName(); String propertyValue(); } typical usage @MessageDriven( name=“MyBean”, activationConfig= { @ActivationConfigProperty(propertyName=“destinationType”, propertyValue=“javax.jms.Queue”), @ActivationConfigProperty(propertyName=“connectionFactoryJndiName”, propertyValue=“jms/QueueConnectionFactory”), @ActivationConfigProperty(propertyName=“destinationName”, propertyValue=“jms/MyQueue”; } ) Bean listens to Queue find Factory to connect to Queue find Queue to listen to 3.2 MDBs

103 Design of Distributed Software103 @MessageDriven : ActivationConfigs acknowledgeMode How should the session acknowledge ? AUTO_ACKNOWLEDGE -> rigorous acknowledgement of each message (default) DUPS_OK_ACKNOWLEDGE -> lazy acknowledgement (once in case of duplicate messages) subscriptionDurability (for Topics ) How to handle offline consumers ? NonDurable -> offline consumers do not get the message (default) Durable -> offline consumers get the message as soon as they get connected 3.2 MDBs

104 Design of Distributed Software104 @MessageDriven : ActivationConfigs messageSelector consumer side filtering of messages operands literals ( String s, numeric values, boolean s,...) Identifiers -> message property name or header field operators comparison =, >, >=, Null comparison : IS NULL, IS NOT NULL true/false comparison : IS [NOT] TRUE, IS [NOT] FALSE logical : NOT, AND, OR 3.2 MDBs

105 Design of Distributed Software105 MDB lifecycle Does Not Exist Ready 0. newInstance() 1. Dependency Injection 2. @PostConstruct @PreDestroy onMessage @PostConstruct -> setup session with Queue/Topic @PreDestroy -> Release session 3.2 MDBs

106 Design of Distributed Software106 Example: Processing ShipRequests NetBeans 1.Create EnterpriseProject with Application Client [JMessageProject] 2.Create Message Driven Bean Right click on JMessageProject-ejb node -> New -> Message Driven Bean EJB-name : ShipRequestMDB package : ejb Destination Type : Queue -> Finish 3. Program onMessage() -method 3.2 MDBs

107 Design of Distributed Software107 Example: Processing ShipRequests package ejb; import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.Message; import javax.jms.MessageListener; @MessageDriven(mappedName = "jms/ShipRequestMDB", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class ShipRequestMDB implements MessageListener { /** Creates a new instance of ShipRequestMDB */ public ShipRequestMDB() { } public void onMessage(Message message) { } } ShipRequestMDB.java IDE-generated JNDI mapped name listens to JMS messages 3.2 MDBs

108 Design of Distributed Software108 Example: Processing ShipRequests package ejb; import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.*; import util.ShipRequest; @MessageDriven(mappedName = "jms/ShipRequestMDB", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class ShipRequestMDB implements MessageListener { /** Creates a new instance of ShipRequestMDB */ public ShipRequestMDB() { } public void onMessage(Message message) { try { ObjectMessage oMessage=(ObjectMessage)message; ShipRequest sRequest=(ShipRequest)oMessage.getObject(); processShipRequest(sRequest); } catch(JMSException e) { System.err.println(e); e.printStackTrace(System.err); } private void processShipRequest(ShipRequest s) { System.out.println(s); } ShipRequestMDB.java with onMessage... 3.2 MDBs

109 Design of Distributed Software109 Example: Utility Class package util; import java.io.Serializable; public class ShipRequest implements Serializable { protected String item; protected String dest; /** Creates a new instance of ShipRequest */ public ShipRequest(String i,String d) { item=i; dest=d; } public String toString() { return "Send item : to destination : "+dest+"."; } ShipRequest.java must be serializable 3.2 MDBs

110 Design of Distributed Software110 Example : Sending messages [from appclient] NetBeans 1.Open Application Client project [JMessageProject-app-client] 2.Connect to Message Driven Bean Right click in main() -method -> Enterprise Resources -> send JMS message Project : JMessageProject-ejb Destination: S hipRequestMDB Select : Generate Inline Lookup Code 3. Copy util -package (!) 4. Code application logic 3.2 MDBs

111 Design of Distributed Software111 Example : Sending messages [from appclient] package jmessageproject; import javax.annotation.Resource; import javax.jms.*; import javax.naming.NamingException; public class Main { @Resource(mappedName = "jms/ShipRequestMDBFactory") private static ConnectionFactory shipRequestMDBFactory; @Resource(mappedName = "jms/ShipRequestMDB") private static Queue shipRequestMDB; public Main() { } public static void main(String[] args) { // TODO code application logic here } private Message createJMSMessageForShipRequestMDB(Session session, Object messageData) throws JMSException { // TODO create and populate message to send // javax.jms.TextMessage tm = session.createTextMessage(); // tm.setText(messageData.toString()); // return tm; } //... } Main.java IDE-generated inject resources : administrated JMS objects Convenience template method 3.2 MDBs

112 Design of Distributed Software112 Example : Sending messages [from appclient] private void sendJMSMessageToShipRequestMDB(Object messageData) throws NamingException, JMSException { Connection connection = null; Session session = null; try { connection = shipRequestMDBFactory.createConnection(); session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(shipRequestMDB); messageProducer.send(createJMSMessageForShipRequestMDB(session, messageData)); } finally { if (session != null) { session.close(); } if (connection != null) { connection.close(); } } Main.java IDE-generated Convenience template method 3.2 MDBs

113 Design of Distributed Software113 Example : Sending messages [from appclient] package jmessageproject; import javax.annotation.Resource; import javax.jms.* import javax.naming.NamingException; import util.ShipRequest; public class Main { @Resource(mappedName = "jms/ShipRequestMDBFactory") private static ConnectionFactory shipRequestMDBFactory; @Resource(mappedName = "jms/ShipRequestMDB") private static Queue shipRequestMDB; public Main() {} public static void main(String[] args) throws Exception { ShipRequest r=new ShipRequest("Book ","Sunset Boulevard"); try { sendJMSMessageToShipRequestMDB(r); }catch(NamingException ne) { System.err.println(ne); }catch(JMSException je) { System.err.println(je); } //... } Main.java Modified... 3.2 MDBs

114 Design of Distributed Software114 Example : Sending messages [from appclient] private static Message createJMSMessageForShipRequestMDB(Session session, ShipRequest mData ) throws JMSException { ObjectMessage oMessage=session.createObjectMessage(mData); return oMessage; } private static void sendJMSMessageToShipRequestMDB( ShipRequest mData ) throws NamingException, JMSException { Connection connection = null; Session session = null; try { connection = shipRequestMDBFactory.createConnection(); session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(shipRequestMDB); messageProducer.send(createJMSMessageForShipRequestMDB(session, mData )); } finally { if (session != null) { session.close(); } if (connection != null) { connection.close(); } } Main.java Modified... 3.2 MDBs

115 Design of Distributed Software115 Sending back info to the client How to send JMS message from bean -> client ? -> ConnectionFactory and Destination to be configured by admin -> deployment descriptor contains info for container to set up -> resources can be injected by container appclient container ONLY injects: - into Main –class - private static attributes Set up administrated resources for reply (MDB -> appclient) ShipReplyConnectionFactory ShipReplyQueue 3.2 MDBs

116 Design of Distributed Software116 Configuring administrated objects NetBeans 1.Select resource type File -> New File... Select ejb-project node Categories -> Sun Resources File Types -> JMS Resource -> Next 2. Configure JMS resource JNDIname : jms/ description : Free text Select JMS-resource type -> Next Enter properties (if needed) Name : JNDIname, without prefix -> Finish [JMessageProject-ejb] [jms/ShipReplyConnectionFactory] [jms/ShipReplyQueue] [jms.ConnectionFactory] [jms.Queue] [] [ShipReplyQueue] 3.2 MDBs

117 Design of Distributed Software117 MDB code with reply package ejb; import javax.annotation.Resource; import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.*; import javax.naming.NamingException; import util.ShipRequest; @MessageDriven(mappedName = "jms/ShipRequestMDB", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class ShipRequestMDB implements MessageListener { @Resource(mappedName="jms/ShipReplyConnectionFactory") private ConnectionFactory shipReplyCF; @Resource(mappedName="jms/ShipReplyQueue") private Destination shipReplyQueue; public ShipRequestMDB() {} ShipRequestMDB.java 3.2 MDBs

118 Design of Distributed Software118 MDB code with reply public void onMessage(Message message) { try { ObjectMessage oMessage=(ObjectMessage)message; ShipRequest sRequest=(ShipRequest)oMessage.getObject(); processShipRequest(sRequest); } catch(JMSException e) { System.err.println(e); e.printStackTrace(System.err); } private void processShipRequest(ShipRequest s) { System.out.println("----------------------------->"+s); try { sendJMSMessageToShipReplyQueue(s); }catch(Exception e) { System.err.println(e); } ShipRequestMDB.java 3.2 MDBs

119 Design of Distributed Software119 MDB code with reply private Message createJMSMessageForShipRequestMDB(Session session,ShipRequest mData) throws JMSException { ObjectMessage oMessage=session.createObjectMessage(mData); return oMessage; } private void sendJMSMessageToShipReplyQueue (ShipRequest mData) throws NamingException, JMSException { Connection connection=null; Session session=null; try { connection = shipReplyCF.createConnection(); session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer( shipReplyQueue ); messageProducer.send(createJMSMessageForShipRequestMDB(session, mData)); } finally { if (session != null) { session.close(); } if (connection != null) { connection.close(); } ShipRequestMDB.java 3.2 MDBs

120 Design of Distributed Software120 Client code with reply package jmessageproject; import javax.annotation.Resource; import javax.jms.*; import javax.naming.NamingException; import util.ShipRequest; public class Main { @Resource(mappedName = "jms/ShipRequestMDBFactory") private static ConnectionFactory shipRequestMDBFactory; @Resource(mappedName = "jms/ShipRequestMDB") private static Queue shipRequestMDB; @Resource(mappedName="jms/ShipReplyConnectionFactory") private static ConnectionFactory shipReplyCF; @Resource(mappedName="jms/ShipReplyQueue") private static Queue shipReplyQueue; private static ReplyListener r=null; Main.java Sending Listener Receiving 3.2 MDBs

121 Design of Distributed Software121 Client code with reply public Main() {} public static ConnectionFactory getFactory() {return shipReplyCF;} public static Queue getQueue() {return shipReplyQueue;} public static void main(String[] args) throws Exception { r=new ReplyListener(); try { r.init(); } catch(Exception e) { System.err.println(e); } ShipRequest r=new ShipRequest("Book ","Sunset Boulevard"); try { sendJMSMessageToShipRequestMDB(r); }catch(NamingException ne) { System.err.println(ne); }catch(JMSException je) { System.err.println(je); } Main.java Awkward, but needed... 3.2 MDBs

122 Design of Distributed Software122 Client code with reply private static Message createJMSMessageForShipRequestMDB(Session session, ShipRequest mData) throws JMSException { ObjectMessage oMessage=session.createObjectMessage(mData); return oMessage; } private static void sendJMSMessageToShipRequestMDB(ShipRequest mData) throws NamingException, JMSException { Connection connection=null; Session session=null; try { connection = shipRequestMDBFactory.createConnection(); session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(shipRequestMDB); messageProducer.send(createJMSMessageForShipRequestMDB(session, mData)); } finally { if (session != null) { session.close(); } if (connection != null) { connection.close(); } Main.java 3.2 MDBs

123 Design of Distributed Software123 Client code with reply class ReplyListener implements MessageListener { Connection connection=null; Session session=null; public void init() throws Exception { try { ConnectionFactory shipReplyCF=Main.getFactory(); Queue shipReplyQueue=Main.getQueue(); connection = shipReplyCF.createConnection(); session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); Message Consumer messageConsumer = session.create Consumer (shipReplyQueue); messageConsumer.setMessageListener(this); connection.start(); } public void onMessage (Message m) { System.out.println("Received !!!!"); // code to close session/connection : if(message.equals(stop)) { //... } } Main.java Find admin resources register listener start listening 3.2 MDBs

124 Design of Distributed Software 3.4 Persistence Service 1.Java 5 Entities 2.(Java 1.4 Entity Beans) 3.EJB Design Patterns

125 Design of Distributed Software125 JEE Architecture browser webserver Application Server applet Database system Web container EJB container WebserverClient Servlet JSP EJB 4.1 Entities JEE client Focus of this section: - Persistence - Design Patterns

126 Design of Distributed Software126 Introduction Entity = persistent object persistent state realised through persistent fields/properties object/relational annotations used to map to relational data in data store Entity class = any Java class but annotated with @Entity public/protected no-arg constructor not final class, no persistent final fields, no final methods if passed by value, must implement Serializable persistent instance variables NOT public Field is persistent, unless annotated @Transient Primary key annotated with - simple primary key @Id - composite primary key @EmbeddedId, @IdClass 4.1 Entities

127 Design of Distributed Software127 Primary Key Primary Key class must be public properties public public default constructor must implements hashCode() and equals() must be Serializable composite primary key : related to - multiple fields/properties of the entity class - embeddable class Same names of fields/properties as in entity class 4.1 Entities

128 Design of Distributed Software128 Managing Entities EntityManager - find entities - query entities - life cycle funtions on entities (create, remove, persist) PersistentContext associated to data store associated to its own EntityManager Container Managed :  changes in PersistentContext automatically propagated by container  EntityManager obtained by @PersistenceContext annotation (through injection) @PersistenceContext EntityManager theManager; 4.1 Entities

129 Design of Distributed Software129 Building Java 5 Applications with Entities Entity objects = simple Java classes no longer need to be placed in an EJB module no longer need to be packaged in an EAR file (both cfr Java 1.4 Entity Beans) entity classes can be created directly inside a web application Two options: Option 1 : Start with Entity code Generate DB tables, columns and DB sync code based on attributes of entities Option 2 : Start with DB structure (tables, columns) Generate Entity code and DB sync code See next slides 4.1 Entities

130 Design of Distributed Software130 Building Java 5 Applications with Entities Option 1: Start with Entity code Example Netbeans 5.5 IDE Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category and click Next. Name the project, set the server to the Sun Java System Application Server, set the Java EE Version to Java EE 5, and click Next. Select the JavaServer Faces checkbox and click Finish. Next Steps: Creating a Persistence Unit Creating the Entity Classes Creating a Web Interface Running the Project 4.1 Entities

131 Design of Distributed Software131 Creating a Persistence Unit Persistence unit tells the container: which entity classes are to be managed by the entity manager, the datasource used by those entities. Created by defining its properties in persistence.xml table generation strategy Netbeans 5.5 : mostly created using the New Persistence Unit wizard. 4.1 Entities

132 Design of Distributed Software132 Creating a Persistence Unit Right-click the web application node in the Projects window and choose New > File/Folder From the Persistence category, select Persistence Unit and click Next. Choose Persistence Provider E.g. TopLink (Netbeans default). Provides the libraries for Java Persistence and the entity manager Other: Hibernate, etc. Choose Data Source E.g. jdbc/sample (Netbeans default). Used to connect to the database Specify table generation strategy (default: create) 4.1 Entities

133 Design of Distributed Software133 Creating the Entity Classes Cfr http://www.netbeans.org/kb/55/persistence.html Animal class: -name -kind -weight -pavilion Pavilion class: -name -address -Collection 1:n ManyToOne OneToMany 4.1 Entities

134 Design of Distributed Software134 Creating the Entity Classes package entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class Animal implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name="animalName") private String name; private String kind; private String weight; @ManyToOne private Pavilion pavilion; /** Creates a new instance of Animal */ public Animal() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String toString() { return "entity.Animal[id=" + getId() + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getKind() { return kind; } public void setKind(String kind) { this.kind = kind; } public String getWeight() { return weight; } public void setWeight(String weight) { this.weight = weight; } public Pavilion getPavilion() { return pavilion; } public void setPavilion(Pavilion pavilion) { this.pavilion = pavilion; } } Animal.java 4.1 Entities

135 Design of Distributed Software135 Creating the Entity Classes package entity; import java.io.Serializable; import java.util.Collection; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; @Entity public class Pavilion implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name="pavilionName") private String name; private String address; @OneToMany(mappedBy="pavilion") private Collection animals; public Pavilion() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } Pavilion.java public String toString() { return "entity.Pavilion[id=" + getId() + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Collection getAnimals() { return animals; } public void setAnimals(Collection animals) { this.animals = animals; } } 4.1 Entities

136 Design of Distributed Software136 Creating a Web Interface 4.1 Entities

137 Design of Distributed Software137 Creating a Web Interface Choose File > New. Select JSF Pages from Entity Class from the Persistence category and click Next. In the New JSF Pages from Entity Class wizard, click Add All to select our two entity classes and click Next. Specify the package for the generated classes and click Finish. Running the project: Start the Java DB database by choosing Tools > Java DB Database > Start Java DB Server. Right-click the project node and choose Run Project. 4.1 Entities

138 Design of Distributed Software138 Building Java 5 Applications with Entities Option 2: Start from DB structure Start the Java DB database by choosing Tools > Java DB Database > Start Java DB Server. Choose New File (Ctrl-N) to open the New File wizard. Select Entity Classes from Database from the Persistence category and click Next. In the Entity Classes from Database wizard, select the data source for the database : a list of available tables appears in the Available Tables pane. Select the right table from the Available Tables and click Add. When you click Add, any tables related to the selected table are also added. Click Next. The selected table and any related tables are displayed. If you want to modify the name of the class that will be generated, you can type the name in the Class Name field. 4.1 Entities

139 Design of Distributed Software139 Building Java 5 Applications with Entities Option 2: URL: http://www.netbeans.org/kb/55/customer- book.html (“Comparing Java EE 5 Platform and J2EE 1.4 Platform”)http://www.netbeans.org/kb/55/customer- book.html Shows Use of EntityManager when using entities 4.1 Entities

140 Design of Distributed Software140 Using Entities In the Source Editor, right-click in the java-file and choose Persistence > Use Entity Manager to inject the PersistenceContext in the class. The IDE adds the following annotation that specifies the persistence unit. The annotation is added above the class declaration. @PersistenceContext(name = "persistence/LogicalName", unitName = “NamePU") The IDE also adds the following annotation injecting a resource for managing transaction boundaries: @Resource private UserTransaction utx; The IDE generates default code, to be adapted by programmers 4.1 Entities

141 Design of Distributed Software141 Using Entities public Customer findByID(Integer customerNr) { Customer customer = null; try { Context ctx = (Context) new InitialContext().lookup("java:comp/env"); EntityManager em = (EntityManager) ctx.lookup("persistence/LogicalName"); utx.begin(); customer = em.find(Customer.class, customerNr); utx.commit(); } catch(Exception e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught", e); throw new RuntimeException(e); } return customer; } Partially generated by IDE, adapted by programmer 4.1 Entities

142 Design of Distributed Software142 Example Object Relational Mapping (ORM) package ods.ejb; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; @NamedQueries( { @NamedQuery ( name="findAccountByUsername", query="SELECT acc FROM Account acc WHERE acc.username = :username" ) }) @Entity public class Account implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //The username of this account. @Column(unique = true, nullable = false) private String username; //The password of this account. @Column(nullable = false) private String password; //Indicates if the user (attached to this account) is an //administrator. @Column(nullable = false) private boolean isAdmin; public Account() { } public Account(String username, String password, boolean isAdmin){ this.username = username; this.password = password; this.isAdmin = isAdmin; } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } … } 4.1 Entities

143 Design of Distributed Software143 Example Façade Session package ods.ejb; import java.util.List; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; @Stateless public class AccountFacade implements AccountFacadeLocal { @PersistenceContext private EntityManager em; public AccountFacade() { } public boolean isValidAccount(String username, String password){ Account account = findByUsername(username); boolean valid = false; If(account != null) if(account.getPassword().equals(password)) valid = true; return valid; } public Account addAccount(String username, String password, boolean isAdmin) throws IllegalArgumentException{ Account existing = findByUsername(username); if(existing != null) throw new IllegalArgumentException("username allready exists"); else{ Account account = new Account(username, password, isAdmin); create(account); return account; } public Account findByUsername(String username){ try { Account account = (Account) em.createNamedQuery("findAccountByUsername").setParameter("username", username).getSingleResult(); return account; } catch (NoResultException e) { } return null; } public void create(Account account) { em.persist(account); } public void edit(Account account) { em.merge(account); } public void destroy(Account account) { em.remove(em.merge(account)); } public Account find(Object pk) { return (Account) em.find(Account.class, pk); } public List findAll() { return em.createQuery("select object(o) from Account as o").getResultList(); } } 4.1 Entities

144 Design of Distributed Software144 Entity Lifecycle Management @PrePersist Marks a method in the entity class as a pre-persist callback (executed before an entity is persisted). @PostPersist Marks a method in the entity class as a postpersist callback (executed after an entity is persisted). @PreUpdate Marks a method in the entity class as a preupdate callback (executed before entity data is updated in the database). @PostUpdate Marks a method in the entity class as a postupdate callback (executed after entity data is updated in the database). @PreRemove Marks a method in the entity class as a preremove callback (executed before an entity is removed from the database). @PostRemove Marks a method in the entity class as a postremove callback (executed after an entity is removed from the database). @PostLoad Marks a method in the entity class as a postload callback (executed before an entity is loaded from the database). 4.1 Entities

145 Design of Distributed Software 3.4 Persistence Service 1.Java 5 Entities 2.(Java 1.4 Entity Beans) 3.EJB Design Patterns

146 Design of Distributed Software146 Introduction Entity Beans represents business object in permanent storage = “row in a database table” persistent storage mechanism in AS : relational database typically  bean class associated to table  bean instances associated to row in table characteristics  persistent  allow shared access  can be found using primary key  participate in relations with other beans 4.2. Java 1.4 Entity Beans

147 Design of Distributed Software147 Shared Access Multiple clients access same bean Requirements safe access (locks) client isolation Implemented using Transaction Service Transaction attributes specified when deploying the bean Transaction boundaries added by container 4.2. Java 1.4 Entity Beans

148 Design of Distributed Software148 Persistence Bean survives - application shutdown - server crashes/restarts/... Two persistency flavours - Bean Managed Persistence : - code (SQL) for DB access (load/store/updates) written by programmer - not necessarily portable to other DB - Container Managed Persistence - code automatically generated and called - more portable approach 4.2. Java 1.4 Entity Beans

149 Design of Distributed Software149 Entity Beans : Life Cycle Does Not Exist Ready newInstance setEntityContext business method ejbLoad ejbStore Pooled ejbActivate ejbPassivate unsetEntityContext 1.create 2.ejbCreate 3.ejbPostCreate 1.remove 2.ejbRemove no specific identity all pooled instances are equal 4.2. Java 1.4 Entity Beans

150 Design of Distributed Software150 Components of an Entity EJBs Three parts: Component interface (local and/or remote) Home interface (local and/or remote) The bean class  Implements javax.ejb.EntityBean And a Primary Key class Can be an existing class  String, Integer, Date, etc. Can be a new class (e.g., for composite keys)  Must properly override hashCode and equals  Must be serializable  Naming convention: X Key 4.2. Java 1.4 Entity Beans

151 Design of Distributed Software151 Home Interface Life Cycle methods As with Session Beans, each ejbCreate method is reflected in the Home interface In addition, for every ejbCreate method there’s a corresponding ejbPostCreate method  PostCreate is invoked after the bean has an EJB object, and is represented in the persistent data storage  Allows you to pass references to the bean to other EJBs –e.g., relationships Other lifecycle methods include ejbActivate, ejbPassivate,, and ejbRemove Home methods to be executed on all instances Finder methods : ejbFindXXX DB Synchronization methods : ejbLoad, ejbStore 4.2. Java 1.4 Entity Beans

152 Design of Distributed Software 3.4.2 EJB: Java 1.4 Entity Beans 1.Bean Managed Persistence 2.Container Managed Persistence

153 Design of Distributed Software153 BMP : Activation... getting an identity pooled -> ready : bean MUST be associated with business object done through assigning primary key in ejbCreate AND ejbActivate : set primary key value Bean creation process 4.2.1 BMP EJB

154 Design of Distributed Software154 Managing Storage Assuming each bean represents a row in a relational table: The ejbCreate methods should add a row to the database The ejbRemove method should remove the row represented by the bean instance ejbLoad should assume nothing about the instance variables mapped to table fields, and reload their values from the database  You can find the primary key by invoking getPrimaryKey on the EntityContext reference ejbStore should update the table row to reflect the current bean state 4.2.1 BMP EJB

155 Design of Distributed Software155 Managing Storage Conceptually, ejbLoad is called before every business method So the method is sure to work with up-to-date values from the database Likewise, ejbStore is called after every business method Storing any changes made to the instance variables As a result, beans can survive container crashes Serious performance hit Common practice: maintain a ‘dirty’ flag Note that according to the spec, the container may invoke ejbLoad and ejbStore arbitrarily, and does not have to call them before/after every business method invocation 4.2.1 BMP EJB

156 Design of Distributed Software156 Activation and Passivation Bean instances are managed in a pool The same bean instance, after created, can be used for different table rows at different times Saves instantiation costs When a bean is returned to the pool (detached from a given row), it is passivated When a bean is re-attached to a row, it is activated Persistent data should not be stored/reloaded during activation/passivation Use ejbPassivate/ejbActivate to release/reacquire other resources 4.2.1 BMP EJB

157 Design of Distributed Software157 Storage and Activation 4.2.1 BMP EJB

158 Design of Distributed Software158 Finder Methods Given the home interface, a client can create new entity EJBs using the various create methods Remember that each create method in the home interface has a corresponding ejbCreate and ejbPostCreate method in the bean class But what if the client wants to locate existing beans? The home interface also includes finder methods. Named findXXX Must return either java.util.Collection, or the component interface type Throws FinderException (and RemoteException for remote homes) Always defined: findByPrimaryKey(keytype) 4.2.1 BMP EJB

159 Design of Distributed Software159 Finder Methods For each findXXX method in the home interface, a corresponding ejbFindXXX method must be implemented in the bean class ejbFindByPrimaryKey is required Finder methods can find a single record This includes ejbFindByPrimaryKey Value returned must be the primary key of the found record  which is the parameter in ejbFindByPrimaryKey’s case Throw FinderException if no record was found Finder methods can find a set of records Signature must define java.util.Collection as return type Return a collection of primary keys Return an empty collection if no records were found 4.2.1 BMP EJB

160 Design of Distributed Software160 Removing a Row The last lifecycle method, ejbRemove, must include code to remove the row corresponding to the current bean instance from the persistent data store Can throw javax.ejb.RemoveException if removal failed. 4.2.1 BMP EJB

161 Design of Distributed Software161 SQL mapping ejbCreateINSERT ejbRemoveDELETE ejbLoadSELECT ejbStoreUPDATE ejbFindXXXSELECT 4.2.1 BMP EJB

162 Design of Distributed Software162 BMP design: different steps 1. Database set up 2. Create bean template 3. Database lookup 4. Class attributes and get/set 5. Life cycle methods ejbCreate, ejbPostCreate, ejbRemove ejbLoad, ejbStore ejbActivate, ejbPassivate finder methods 6. Business methods 7. Home methods 8.Client code 4.2.1 BMP EJB

163 Design of Distributed Software 3.4.2 EJB Java 1.4 : Entity Beans 1.Bean Managed Persistence 2.Container Managed Persistence

164 Design of Distributed Software164 Letting the Container Do the Work Entity beans, as defined so far, must include a lot of SQL statements if they use a database as their data source SELECT for ejbLoad and finder methods INSERT for create methods UPDATE for ejbStore DELETE for ejbRemove The work is repetitive, tedious, and error-prone Why not automate it? Enter CMP: Container Managed Persistence for Entity EJBs 4.2.2 CMP EJB

165 Design of Distributed Software165 CMP Entity Beans CMP EJBs work just like BMP EJBs Same lifecycle However, the mapping between persistent bean attributes and table columns is defined in a declarative manner. tell the container which attribute corresponds to which column the container generates deployment code that handles loading, finding, deleting, etc. In the EJB 1.x spec, persistent attributes are simply class variables. Starting with EJB 2.0, persistent attributes are not reflected as class variables Only defined by getter/setter methods Allows the container to manage a ‘dirty’ flag automatically, thus saving needless updates 4.2.2 CMP EJB

166 Design of Distributed Software166 CMP Beans part of bean deployment descriptor (declarative) describes bean persistent state and relationships referenced by queries written in EJB QL supply one EJB query for each finder method Persistent Fields Abstract Schema persistent bean state automatically synchronized at runtime no coding of persistent fields, just declare them in the AS identified my get/set methods 4.2.2 CMP EJB

167 Design of Distributed Software167 Bean class CMPBMP Class definitionabstractnot abstract DB callshandled by containernot handled by container Persistent statevirtual stateinstance variables Access methods for state and relationships requirednone required findByPrimaryKey by containerto be coded findXXX provide EJB queryto be coded select methodshandled by containernone return ejbCreate noneprimary key object 4.2.2 CMP EJB

168 Design of Distributed Software168 Lifecycle Methods in CMP Entity Beans Each CMP entity bean must include the same lifecycle methods as BMP beans However, some of the semantics are slightly different: ejbLoad is called immediately after the data is loaded  Allows you to calculate values for any class variables that depend on field values  Should not attempt to load the data by itself ejbStore is called immediately before the data is stored  Does not store the data by itself ejbRemove is called immediately before the row is removed  Does not actually remove the row by itself All are normally empty. 4.2.2 CMP EJB

169 Design of Distributed Software169 Access Methods For each persistent attribute A in the bean, there must be a get A and/or a set A method The getters and setters are defined in the bean class as abstract methods Their actual implementation is included in a subclass generated by the container. Implication: the bean class itself is abstract. 4.2.2 CMP EJB

170 Design of Distributed Software170 Finder Methods in CMP Entity Beans Finder methods are defined normally in the home interface However, no corresponding ejbFindXXX methods are defined in the bean class Each finder method is associated (in the deployment descriptor) with an EJB QL query The query should return one row (at most) if the finder is defined to return a single bean The query should return zero or more rows if the finder is defined to return a collection EJB QL is a modified subset of SQL 4.2.2 CMP EJB

171 Design of Distributed Software171 Select Methods Similar to finder methods can return local/remote interface queries the DB EJB QL query associated with every select method not implemented in the bean class Different from finder methods can return persistent state of related bean not exposed to client -> only invoked by other beans methods defined in the entity bean class 4.2.2 CMP EJB

172 Design of Distributed Software172 CMP design: different steps 1. Database set up -> idem as BMP 2. Create bean template 3. Database lookup 4. Class attributes : get/set 5. Life cycle methods 1. ejbCreate, ejbPostCreate, ejbRemove 2. ejbLoad, ejbStore 3. ejbActivate, ejbPassivate 4. finder methods 6. Business methods -> idem as BMP 7. Home methods-> idem as BMP 8. Facade Session Bean 9. Client code-> idem as BMP (actually calls SB !) 4.2.2 CMP EJB

173 Design of Distributed Software 3.4 Persistence Service 1.Java 5 Entities 2.(Java 1.4 Entity Beans) 3.EJB Design Patterns

174 Design of Distributed Software174 Entity Bean 1 Entity Bean 1 Entity Bean 1 EJB Design Patterns Facade Controller Entity Bean 1 Entity Bean 2 Entity Bean 3 Entity Bean 3 Entity Bean 3 Entity Bean 3 Entity Bean 2 Client proxy Facade pattern session bean presents API to clients Proxy pattern abstracts the server to the client Command pattern reduce the complexity in the communication decouple client - server 4.3 Design Patterns

175 Design of Distributed Software175 The Session Facade Pattern Used for minimizing Client/entity bean coupling Risk of client using unapproved business methods  Or using approved business methods in unapproved ways Network delays Points of change if high-level business operations are modified The idea: create a Session EJB that provides high- level business methods Client should only work with the session bean(s) Entity EJBs provide (possibly only) a local interface  Session EJB accesses entity EJBs locally 4.3 Design Patterns

176 Design of Distributed Software176 The Session Facade Pattern Client Application Server No Facade 4.3 Design Patterns

177 Design of Distributed Software177 The Session Facade Pattern Client Application Server With Facade 4.3 Design Patterns

178 Design of Distributed Software178 Session Facade Example Client code without the facade: Find Account home Find accounts a1, a2 by primary keys k1, k2 a1.setBalance(a1.getBalance() - amount); a2.setBalance(a2.getBalance() + amount); Client code with the facade: Find TransferBean home, create TransferBean t1 t1.transfer(k1, k2, amount); 4.3 Design Patterns

179 Design of Distributed Software179 Resulting Benefits Faster operation 1 JNDI lookup, 1 remote object lookup and 1 remote business method vs. 1 JNDI lookup, 2 remote object lookups and 4 remote business methods in the old code Easier maintenance If we have two different clients (servlet, application) and we wish to change the transfer semantics (e.g., add logging), there's only one place to change Easier transaction management can be started at the facade Increased security Client can't invoke Account.setBalance directly, since Account has no remote component interface 4.3 Design Patterns

180 Design of Distributed Software180 Proxy Pattern Class at client side Abstracts home interface location to the client Performance benefit : cache home objects Also called “EJBHomeFactory pattern” Application Server ClientNoProxy EJBHome ClientProxy 4.3 Design Patterns

181 Design of Distributed Software181 Proxy Pattern Advantages Proxy can contain JNDI name – Bean class mapping Can serve as cache for EJBHome objects Allows cleaner coding style 4.3 Design Patterns

182 Design of Distributed Software182 Command Pattern Command pattern = Class, transmitted from one object to another Client constructs commands, facade forwards them to right controller Example code public interface BasicCommandInterface{ public String getCommandTarget(); public String getCommandInstruction(); public HashMap getCommandData(); public void setCommandData(String key,Object value); public void setCommandTarget(String aTarget); public void setCommandInstruction(String anInstruction); public execute(); public void getCommandData(HashMap aData); } Applications can be modified dynamically Facade doesn’t need to provide all interface methods 4.3 Design Patterns

183 Design of Distributed Software183 Command Pattern Client Command Processor (stateless SB) Command Routing (could be proxy) Commands decoupling client – server single network transaction Controller (stateful SB) 4.3 Design Patterns

184 Design of Distributed Software184 Other Recommended Practices Avoid calling EJB methods directly from JSP The need to catch remote exceptions would complicate the JSP code Avoid hard-coding JNDI properties Store configuration hashtable values in a file Avoid hard-coding JNDI resource names Avoid fine grain data transfers 4.3 Design Patterns


Download ppt "Design of Distributed Software Chapter 3: Middleware Services Overview of 10 important middleware services and examples in CORBA, RMI, JEE, Web Services."

Similar presentations


Ads by Google