Enterprise Java EJB Session Beans v 131013 EJB
Enterprise Java EJB: Session Beans v 131013 EJB: Session Beans 1
Needs and Java. SE/EE Implementation Options v 131013 EJB: Session Beans Enterprise Java 2
Goals Enterprise Java • Be able to deploy business logic to the EJB tier – hosted by the container • • • resource management threading security transactions remote interfaces async capabilities – accessed by other local business logic and local web tier – accessed by remote clients v 131013 EJB: Session Beans 3
Objectives Enterprise Java • Rationale • Stateless Session Bean – Stateless – Stateful – Singleton • Enterprise Archives (EARs) • Example Session Bean • Interface Design Issues – Lazy Load – Pure POJOs – DTO Classes v 131013 EJB: Session Beans 4
Overview Enterprise Java • Entity Beans – model business data in system • Session Beans – model interactions between other beans – Taskflow • Enterprise Archive (EAR) – Deployment artifact with a specific structure containing • • v 131013 EJB component(s) WAR component(s) Utility jar(s) … EJB: Session Beans 5
Associated Design Patterns Enterprise Java • Session Façade (covered in Business Logic) • Remote Façade • Data Transfer Objects v 131013 EJB: Session Beans 6
Remote Facade Enterprise Java • Forces – core service layer (business logic and its business objects) contains fine grain methods and objects – a significant number of fine-grain remote calls will not work • Solution – add a Remote Facade • a course-grain facade over a service layer • contains no business logic; it calls it • translates course-grain methods and objects into fine-grain method calls and objects to/from service layer • bulk accessors wrap fine-grain access methods – service layer does not have a remote interface • fine grain business objects used might not be Serializable v 131013 EJB: Session Beans 7
Remote Facade Encapsulates Local Objects Enterprise Java v 131013 EJB: Session Beans 8
Remote Facade Encapsulates Local Logic Enterprise Java v 131013 EJB: Session Beans 9
DTO Pattern Enterprise Java • Context – Business Objects represent too much information or behavior to transfer to remote client • Problem – – Client may get information they don't need Client may get information they can't handle Client may get information they are not authorized to use Client may get too much information/behavior to be useful (e. g. , entire database serialized to client) • Forces – Some clients are local and can share object references with business logic – Handling specifics of remote clients outside of core scope of business logic v 131013 EJB: Session Beans 10
DTO/Remote Facade Solution Enterprise Java • Layer a Remote Facade over Business Logic • Remote Facade constructs Data Transfer Objects (DTOs) from Business Objects that are appropriate for remote client view • Remote Facade uses DTOs to construct or locate Business Objects to communicate with Business Logic v 131013 EJB: Session Beans 11
DTO Pattern Roles Enterprise Java • Data Transfer Object – represent a subset of the state of the application at a point in time – not dependent on Business Objects or server-side technologies • doing so would require sending Business Objects to client • XML and Web services provide the “ultimate isolation” in DTO implementation • Remote Facade – uses Business Logic to perform core business logic – layered on to of Business Logic to translate between Business Objects and DTOs • Business Logic – continues to perform core duties as described in DAO v 131013 Pattern EJB: Session Beans 12
DTO Pattern Consequences • • Enterprise Java Clients only get what they need Clients only get what they understand Clients only get what they are authorized to use Remote and Local interfaces to services are different – makes it harder to provide location transparency • Lightweight Business Objects can be used as DTOs – Remote Facade must make sure they are “pruned” of excess related items before transferring to client – Remote Facade must make sure they are “cleaned” of DAO persistence classes before transferring to client v 131013 EJB: Session Beans 13
Use Cases and Session Beans Enterprise Java • Session Bean per Use Case too fine grain – Create. Account. EJB – Deposit. EJB – Withdraw. EJB – Transfer. EJB • Group cohesive Use Cases into a larger-grain Session Bean – Teller. EJB • create. Account(), deposit(), withdraw(), transfer() v 131013 EJB: Session Beans 14
Use of Session versus Entity Beans Enterprise Java • Session Beans – implementation of a task – interaction between other beans – direct database access • bulk operations – examples • Tax. District. calc. Tax(double cost) • Teller. transfer(long from. Account, long to. Account, double amount) • Registrar. list. Students(String course) v 131013 EJB: Session Beans 15
Enterprise Java Use of Session versus Entity Beans (cont. ) • Entity Beans – represent shared data in the database – provide a type-safe, complete view of shared information – interacts with data generally at the individual object/row level – examples • Account, Student • Account. set. Owner(String tax. Id), Account. get. Owner() • Account. withdraw(double amount), Account. deposit(double amount) v 131013 EJB: Session Beans 16
Stateless Session Bean Enterprise Java • maintains no conversational state – each method is ignorant of what went before it and what will happen after it • maintains implementation state – sharable between separate client invocations • a set of procedures or batch commands that take in a set of parameters and return a result v 131013 EJB: Session Beans 17
Stateful Session Bean Enterprise Java • maintains conversational state – object can cache values between calls • ex. iterator – idle timeout period or client command ends lifetime • maintains implementation state – not sharable between separate clients/objects • all resources are allocated to perform the work of one Stateful Session bean instance. That instance is tied to the state of the client • able to react to transaction states – ex. Publish error message on transaction rollback v 131013 EJB: Session Beans 18
Singleton Session Bean Enterprise Java • Stateful session bean with only one instance shared across all clients • Good for tracking transient state in-memory v 131013 EJB: Session Beans 19
Stateless/Stateful/Singleton Enterprise Java • Stateless – can contain cached implementations • • JDBC Data. Sources JMS Publishers cached EAI state all non-visible to calling client • Stateful – may contain all of the above and add client conversational state • Singleton – May contain all of the above except client conversation state would be shared across clients • e. g. , get. Next. Task() v 131013 EJB: Session Beans 20
Stateless/Stateful/Singleton Enterprise Java • Stateless – Cheapest to implement, deploy, scale • Stateful – should only be used within the scope of a single Http. Request – should not be used at Http. Session Scope • multiple threads would access same instance • Singleton – Newest bean type – More overhead than stateless because of concurrency management – Extremely efficient when managing in-memory state v 131013 EJB: Session Beans 21
Stateless Session Bean Lifecycle v 131013 EJB: Session Beans Enterprise Java 22
Stateful Session Bean Lifecycle v 131013 EJB: Session Beans Enterprise Java 23
Singleton Session Bean Lifecycle v 131013 EJB: Session Beans Enterprise Java 24
Java. EE EARs Enterprise Java • Used for compound deployments – Multiple EJBs – Multiple WARs – EJB + WAR • Optional with new Java. EE 6 “flexible deployment” and the first and last case above – WAR • EJB(s) v 131013 EJB: Session Beans 25
Class Loaders Enterprise Java Parent Class Loader Child Class Loader • Arranged in a parent/child relationship • Requests for a class are first delegated to the parent class loader • May access classes/resources loaded by local and parent class loader • Do not have access to classes/resources loaded by sibling class loaders v 131013 EJB: Session Beans 26
Separate EJB/WAR Deployment Enterprise Java Application Server Class Loader EJB App Class Loader Web App Class Loader • Classes loaded by EJB Application Class Loader not seen by Web Application • Shared implementations must be placed in both applications – WEB-INF/lib – causes difficulty when passing object between applications that have loaded the same class v 131013 EJB: Session Beans 27
J 2 EE Enterprise Application Deployment Enterprise Java Application Server Class Loader EAR Class Loader EJB interfaces and dependent classes identified by EJB manifests loaded by EAR’s classloader EJB App Class Loader Web App 2 Class Loader Web App 1 Class Loader v 131013 EAR Class Loader All EJBs are loaded by a single class loader • may also include web dependent classes identified through manifest entries to promote singleton loading of classes across web applications Servlets/JSPs and lib. jars loaded by isolated classloaders EJB: Session Beans 28
Enterprise Java Enterprise Application Archive (EAR) EAR • WAR WAR EJB EJB • Utility Classes Client App • • Resource Adapter • WAR(s) – directory or archive EJB(s) – directory or archive Client JAR(s) – client applications Utility Classes(s) – directory or archive – supplies external source utility classes – referenced through MANIFESTs Resource Adapters(s) – custom resource drivers META-INF/application. xml v 131013 EJB: Session Beans 29
Directory and Archive Forms Enterprise Java • Exploded Directory Form – ability to modify static files (html/jsp) without redeploying – separate server serves up content in exploded form – simpler build environment • consistent with build environment of free versions of IDEs (Forte, JBuilder, etc. ) • Archive File Format – easy form of distribution v 131013 EJB: Session Beans 30
Enterprise Java application. xml application icon small-icon display-name description? large-icon web-uri security-role* description? ejb|connector|java|web v 131013 module+ alt-dd role-name context-root EJB: Session Beans 31
Key Element Definitions Enterprise Java • Modules – ejb – EJBs (Ex. EJB 1. jar) – web applications – java - client applications – connector – JCA resource adapters • Web applications – web-uri (ex. webapp 1. war) – context-root • Name of web app’s context • May be empty if only one webapp in the application v 131013 EJB: Session Beans 32
application. xml Example <? xml version="1. 0" encoding="UTF-8"? > <!DOCTYPE application PUBLIC "-//Sun Microsystems, Inc. //DTD J 2 EE Application 1. 3//EN" "http: //java. sun. com/dtd/application_1_3. dtd"> <application> <display-name>ejbsession. Bank. EAR</display-name> <description>Example Session Bean Bank Application</description> <module> <web-uri>ejbsession. Bank. WAR. war</web-uri> <context-root>/ejbsession. Bank. WAR</context-root> </web> </module> <ejb>ejbsession. Bank. EJB-1. 0. 2007. 2 -SNAPSHOT. jar</ejb> </module> v 131013 EJB: Session Beans Enterprise Java 33
Example: Core Implementation Enterprise Java ejbsession. Bank. Impl/target/classes |-- META-INF | `-- orm. xml `-- ejava `-- examples `-- ejbsessionbank |-- bl | |-- Bank. Exception. class | `-- Teller. class |-- blimpl | `-- Teller. Impl. class |-- bo | |-- Account. class | |-- Ledger. class | `-- Owner. class |-- dao | |-- Account. DAO. class | |-- DAOException. class | `-- Owner. DAO. class `-- jpa |-- JPAAccount. DAO. class `-- JPAOwner. DAO. class * Note: we are not including a Java. SE persistence. xml in Impl v 131013 EJB: Session Beans 34
Example Session Bean: Business Interface Enterprise Java package ejava. examples. ejbsessionbank. bl; import java. util. List; import ejava. examples. ejbsessionbank. bo. Account; import ejava. examples. ejbsessionbank. bo. Ledger; public interface Teller { Account create. Account(String acc. Num) throws Bank. Exception; Account get. Account(String acct. Num) throws Bank. Exception; Account close. Account(String acct. Num) throws Bank. Exception; void update. Account(Account account) throws Bank. Exception; List<Account> get. Overdrawn. Accounts(int index, int count) throws Bank. Exception; List<Account> get. Accounts(int index, int count) throws Bank. Exception; Ledger get. Ledger() throws Bank. Exception; } v 131013 EJB: Session Beans 35
Example: EJB Enterprise Java ejbsession. Bank. EJB/target/classes |-- ejava | `-- examples | `-- ejbsessionbank | |-- dto | | `-- Owner. DTO. class | `-- ejb | |-- Stats. class | |-- Stats. EJB. class | |-- Stats. Local. class | |-- Stats. Remote. class | |-- Teller. EJB. class | |-- Teller. Local. class | `-- Teller. Remote. class `-- META-INF |-- ejb-jar. xml `-- persistence. xml * Note: We are providing a Java. EE persistence. xml in the EJB v 131013 EJB: Session Beans 36
Enterprise Java Example Session Bean: Local and Remote Interfaces package ejava. examples. ejbsessionbank. ejb; import ejava. examples. ejbsessionbank. bl. Teller; @javax. ejb. Local public interface Teller. Local extends Teller { } package ejava. examples. ejbsessionbank. ejb; import ejava. examples. ejbsessionbank. bl. Teller; @javax. ejb. Remote public interface Teller. Remote extends Teller { } * Warning – although business interfaces can be used for both local and remote interfaces, this only works for simple data models – more later v 131013 EJB: Session Beans 37
Example Session Bean: Bean Class Enterprise Java package ejava. examples. ejbsessionbank. ejb; import javax. annotation. *; import javax. ejb. *; import javax. persistence. *; . . . @Stateless public class Teller. EJB implements Teller. Local, Teller. Remote { private static final Log log =. . . @Resource protected Session. Context ctx; @Persistence. Context(unit. Name="ejbsessionbank") protected Entity. Manager em; Stateless @Resource(name="dao. Class") protected String dao. Class. Name; protected Teller teller; v 131013 EJB: Session Beans 38
Example Session Bean: Bean Class Enterprise Java @Post. Construct public void init() { log. debug("init(), dao. Class=" + dao. Class. Name); teller = new Teller. Impl(); try { Account. DAO dao = (Account. DAO)Thread. current. Thread() //just a partial example of resolving. get. Context. Class. Loader() //a property supplied. load. Class(dao. Class. Name) //by the container. new. Instance(); ((JPAAccount. DAO)dao). set. Entity. Manager(em); ((Teller. Impl)teller). set. Acct. DAO(dao); Owner. DAO owner. DAO = new JPAOwner. DAO(); ((JPAOwner. DAO)owner. DAO). set. Entity. Manager(em); ((Teller. Impl)teller). set. Owner. DAO(owner. DAO); } catch (Exception ex) { log. fatal("error loading dao class: " + dao. Class. Name, ex); throw new EJBException("error loading dao class: " + dao. Class. Name + ", " + ex); } @Pre. Destroy public void close() {. . . } v 131013 EJB: Session Beans 39
Example Session Bean: Bean Class Enterprise Java public Account create. Account(String account. Number) throws Bank. Exception{ try { return teller. create. Account(account. Number); } catch (Account. DAOException ex) { ctx. set. Rollback. Only(); log. fatal("internal error creating account", ex); throw new Bank. Exception("internal error creating account: "+ ex); } } Log details of exception locally on server-side Provide de-serializable message to client v 131013 EJB: Session Beans 40
Example Session Bean: ejb-jar. xml Enterprise Java <? xml version="1. 0"? > <ejb-jar xmlns="http: //java. sun. com/xml/ns/javaee" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //java. sun. com/xml/ns/javaee/ejb-jar_3_1. xsd" version="3. 1"> <enterprise-beans> <session> <ejb-name>Teller. EJB</ejb-name> <env-entry-name> dao. Class</env-entry-name> <env-entry-type>java. lang. String</env-entry-type> <env-entry-value>ejava. examples. ejbsessionbank. jpa. JPAAccount. DAO </env-entry-value> </env-entry>. . . </session> </enterprise-beans> Watch out for <CR>!!! </ejb-jar> v 131013 EJB: Session Beans 41
Example Session Bean: persistence. xml Enterprise Java <? xml version="1. 0" encoding="UTF-8"? > <persistence xmlns="http: //java. sun. com/xml/ns/persistence" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //java. sun. com/xml/ns/persistence_2_0. xsd" version="2. 0"> <persistence-unit name= "ejbsessionbank"> <provider>org. hibernate. ejb. Hibernate. Persistence</provider> <jta-data-source>java: jboss/datasources/Example. DS</jta-data-source> <jar-file>lib/ejbsession. Bank. Impl-${project. version}. jar</jar-file> <properties> <property name= "hibernate. dialect" value="${hibernate. dialect}"/> </properties> </persistence-unit> </persistence> v 131013 EJB: Session Beans 42
Example Singleton Session Bean: Local and Remote Interfaces Enterprise Java package ejava. examples. ejbsessionbank. ejb; public interface Stats { void open(); void close(); int get. Total(); int get. Delta(); void reset(); } package ejava. examples. ejbsessionbank. ejb; @javax. ejb. Local public interface Stats. Local extends Stats { } package ejava. examples. ejbsessionbank. ejb; @javax. ejb. Remote public interface Stats. Remote extends Stats { } v 131013 EJB: Session Beans 43
Example Singleton Session Bean: Bean Class Setup package ejava. examples. ejbsessionbank. ejb; Enterprise Java @javax. ejb. Singleton @javax. ejb. Startup @javax. ejb. Concurrency. Management( javax. ejb. Concurrency. Management. Type. CONTAINER) @javax. ejb. Access. Timeout(value=3000) public class Stats. EJB implements Stats. Local, Stats. Remote { private static final Log log =. . . private int delta; private int total; (Stateful) @javax. annotation. Post. Construct log. info("*** Stats. EJB ***"); } v 131013 EJB: Session Beans 44
Example Singleton Session Bean: Write/Read Methods @Override @javax. ejb. Lock( javax. ejb. Lock. Type. WRITE) public void open() { this. delta += 1; this. total += 1; } @Override @Lock(Lock. Type. WRITE) public void close() { this. delta -= 1; this. total += 1; } Enterprise Java @Override @Lock(Lock. Type. READ) public int get. Total() { return total; } @Override @Lock(Lock. Type. READ) public int get. Delta() { return delta; } @Override @Lock(Lock. Type. WRITE) public void reset() { delta=0; total=0; } v 131013 EJB: Session Beans 45
Example: RMI Test Enterprise Java ejbsession. Bank. Test/target/test-classes |-- ejava | `-- examples | `-- ejbsessionbank | `-- ejbclient … … | |-- Teller. EJBClient. IT. class | |-- Teller. Remoting. IT. class | |-- Teller. Owner. EJBClient. IT. class | `-- Teller. Owner. Remoting. IT. class |-- jboss-ejb-client. properties |-- jndi. properties `-- log 4 j. xml JUnit Test Types *Test = unit tests run by surefire plugin *IT = integration tests run by failsafe plugin v 131013 EJB: Session Beans 46
• • • Generic naming mechanism Works identical with non-EJB resources Ignorant of EJB details Less Efficient Being deprecated by JBoss in favor of EJB Client Remoting Enterprise Java • JNDI Tree (Internally Accessible) java: global/ejbsession. Bank. EAR/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Local java: app/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Local java: module/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Local java: global/ejbsession. Bank. EAR/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote java: app/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote java: module/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote • JNDI Tree (externally Accessible) java: jboss/exported/ejbsession. Bank. EAR/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote • jndi. properties java. naming. factory. initial=org. jboss. naming. remote. client. Initial. Context. Factory java. naming. factory. url. pkgs= java. naming. provider. url=remote: //127. 0. 0. 1: 4447 java. naming. security. principal=known java. naming. security. credentials=password jboss. naming. client. ejb. context=true • External JNDI Name ejbsession. Bank. EAR/ejbsession. Bank. EJB/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote v 131013 EJB: Session Beans 47
JUnit Integration Test (IT) public class Teller. Remoting. IT { private static final Log log =. . . protected Teller teller; @Before public void set. Up() throws Exception { Initial. Context jndi = new Initial. Context(); teller = (Teller. Remote)jndi. lookup(jndi. Name); } Enterprise Java JNDI Properties being supplied through jndi. properties file -orthrough a Properties object @Test public void test. Create. Account() throws Exception { log. info("*** test. Create. Account ***"); Account account=null; //try with what should be a unique number try { account = teller. create. Account("1234"); log. debug("account created: " + account); } catch (Exception ex) { log. fatal("error creating account: " + ex, ex); fail("error creating account: " + ex); } v 131013 EJB: Session Beans 48
• • • EJB-specific naming mechanism Does not work with non-EJB resources Aware of EJB details More efficient than Remoting Non-standard EJBClient Enterprise Java • jndi. properties java. naming. factory. initial= java. naming. factory. url. pkgs=org. jboss. ejb. client. naming java. naming. provider. url= java. naming. security. principal= java. naming. security. credentials= • jboss-ejb-client. properties #top level property listing the names of the connections. There will be a set #of properties for each name listed here remote. connections=default #here we define the properties for the server we have called "default" remote. connection. default. host=127. 0. 0. 1 remote. connection. default. port=4447 remote. connectionprovider. create. options. org. xnio. Options. SSL_ENABLED=false • External JNDI Name ejb: (ear)/(module)/(distinct. Name)/(ejb. Class)!(remote. Interface)[? stateful] ejb: ejbsession. Bank. EAR/ejbsession. Bank. EJB/””/Teller. EJB!ejava. examples. ejbsessionbank. ejb. Teller. Remote v 131013 EJB: Session Beans 49
Lazy Load Issues Enterprise Java • EJB public List<Owner> get. Owners(int index, int count) { return teller. get. Owners(index, count); • RMI Test List<Owner> owners = teller. get. Owners(0, 100); assert. Equals("unexpected number of owners", 2, owners. size()); for(Owner o : owners) { for (Account a: o. get. Accounts()) { //LINE 87. . . } } • Error org. hibernate. Lazy. Initialization. Exception: failed to lazily initialize a collection of role: ejava. examples. ejbsessionbank. bo. Owner. accounts, no session or session was closed. . . org. hibernate. collection. Abstract. Persistent. Collection. read(Abstract. Persisten t. Collection. java: 86) at org. hibernate. collection. Persistent. Bag. iterator(Persistent. Bag. java: 249) at ejava. examples. ejbsessionbank. ejbclient. Teller. Owner. Remote. Test. test. Lazy( Telle r. Owner. Remote. Test. java: 87 ) v 131013 EJB: Session Beans 50
Lazy Load Correction Enterprise Java • EJB Remote @Remote public interface Teller. Remote extends Teller { List<Owner> get. Owners. Loaded(int index, int count) throws Bank. Exception; } • EJBpublic List<Owner> } get. Owners. Loaded(int index, int count) throws Bank. Exception { List<Owner> owners = get. Owners(index, count); for(Owner owner : owners) { for (Account account : owner. get. Accounts()) { account. get. Balance(); //call a method to get loaded } } return owners; • RMI Test List<Owner> owners = teller. get. Owners. Loaded(0, 100); Alt: relation fetch mode Alt: DAO JPAQL Query public class Owner { @One. To. Many(fetch=EAGER) private List<Account> accounts; v 131013 SELECT o FROM Owner o LEFT JOIN FETCH o. accounts EJB: Session Beans 51
Non-POJO Class Issues Enterprise Java • EJB public List<Owner> get. Owners. Loaded(int index, int count) } throws Bank. Exception { List<Owner> owners = get. Owners(index, count); for(Owner owner : owners) { for (Account account : owner. get. Accounts()) { account. get. Balance(); //call a method to get loaded } } return owners; • RMI Test List<Owner> owners = teller. get. Owners. Loaded(0, 100) ; for(Owner o : owners) { for (Account a: o. get. Accounts()) { log. info("account=" + a); } log. debug("addresses=" + o. get. Accounts(). get. Class(). get. Name() ); assert. True("unexpected collection class", o. get. Accounts(). get. Class(). get. Name(). contains("hibernate")); } • Output -account=id=2, acctnum=111, bal=$0. 0 -addresses=org. hibernate. collection. Persistent. Bag v 131013 EJB: Session Beans 52
Non-POJO Class Correction • EJB Enterprise Java public List<Owner> get. Owners. POJO(int index, int count). . . List<Owner> owners. POJO = new Array. List<Owner>(); for(Owner owner : get. Owners(index, count)) { Owner owner. POJO = new Owner(owner. get. Id()); owner. POJO. set. First. Name(owner. get. First. Name()); owner. POJO. set. Last. Name(owner. get. Last. Name()); owner. POJO. set. Ssn(owner. get. Ssn()); for (Account account : owner. get. Accounts()) { Account account. POJO = new Account(account. get. Id()); account. POJO. set. Account. Number(account. get. Account. Number()); account. POJO. deposit(account. get. Balance()); owner. POJO. get. Accounts(). add(account. POJO); } owners. POJO. add(owner. POJO); } return owners. POJO; } • RMI Test owners = teller. get. Owners. POJO(0, 100); . . . • Output log. debug("addresses=" + o. get. Accounts(). get. Class(). get. Name()); assert. False("unexpected collection class", o. get. Accounts(). get. Class(). get. Name(). contains("hibernate")); -account=id=2, acctnum=111, bal=$0. 0 -addresses=java. util. Array. List v 131013 EJB: Session Beans 53
BO Complexity Class Issues Enterprise Java • Business Object public class Owner implements Serializable { private long id; private String first. Name; private String last. Name; private String ssn; private Collection<Account> accounts = new Array. List<Account>(); . . . v 131013 EJB: Session Beans 54
BO Complexity Correction Enterprise Java • DTO Class public class Owner. DTO implements Serializable {. . . private private static final long serial. Version. UID = 1 L; long id; String first. Name; String last. Name; int accounts; • EJBpublic List<Owner. DTO> } get. Owners. DTO(int index, int count) throws Bank. Exception { List<Owner. DTO> owners. DTO = new Array. List<Owner. DTO>(); for(Owner owner : get. Owners(index, count)) { Owner. DTO owner. DTO = new Owner. DTO(owner. get. Id()); owner. DTO. set. First. Name(owner. get. First. Name()); owner. DTO. set. Last. Name(owner. get. Last. Name()); owner. DTO. set. Accounts(owner. get. Accounts(). size()); owners. DTO. add(owner. DTO); } return owners. DTO; • RMI Test List<Owner. DTO> owners = teller. get. Owners. DTO(0, 100); v 131013 EJB: Session Beans 55
Enterprise Java Building EJBs with Maven v 131013 EJB: Session Beans 56
Parent Project |-|-`-- Enterprise Java ejbsession. Bank. BLImpl ejbsession. Bank. EAR ejbsession. Bank. EJB ejbsession. Bank. Test pom. xml v 131013 EJB: Session Beans 57
Parent Project Enterprise Java <? xml version="1. 0" encoding="UTF-8"? > <project> <parent> <group. Id>ejava</group. Id> <artifact. Id>ejava-root</artifact. Id> <version>3. 0. 2012. 2 -SNAPSHOT</version> <relative. Path/> </parent> <model. Version>4. 0. 0</model. Version> <group. Id>ejavaee. ejb</group. Id> <artifact. Id>ejbsession. Bank</artifact. Id> <packaging>pom</packaging> <name>EJB Session Bean Bank</name> <description> This project is the root project for the core session bean example. </description> <modules> <module>ejbsession. Bank. Impl</module> <module>ejbsession. Bank. EJB</module> <module>ejbsession. Bank. WAR</module> <module>ejbsession. Bank. EAR</module> <module>ejbsession. Bank. Test</module> </modules> </project> v 131013 EJB: Session Beans 58
EJB Project Enterprise Java ejbsession. Bank. EJB/src/ `-- main |-- java | `-- examples | `-- ejbsessionbank | |-- dto | | `-- Owner. DTO. java | `-- ejb | |-- Stats. EJB. java | |-- Stats. Local. java | |-- Stats. Remote. java | |-- Teller. EJB. java | |-- Teller. Local. java | `-- Teller. Remote. java `-- resources `-- META-INF |-- ejb-jar. xml |-- persistence. xml `-- (jboss-ejb 3. xml) v 131013 EJB: Session Beans 59
EJB Project pom. xml: ejb Packaging Enterprise Java <project> <parent> <artifact. Id>ejbsession. Bank</artifact. Id> <group. Id>ejavaee. ejb</group. Id> <version>3. 0. 2012. 2 -SNAPSHOT</version> <relative. Path>. . </relative. Path> </parent> <model. Version>4. 0. 0</model. Version> <artifact. Id>ejbsession. Bank. EJB</artifact. Id> <packaging>ejb</packaging> <name>Session Bank EJB</name> <description> This project provides an example of the core properties of a session bean. </description> <dependencies> </dependencies> <build> </build> <profiles> </project> v 131013 EJB: Session Beans 60
EJB Project: dependencies Enterprise Java <dependencies> <!-- core dependencies --> <dependency> <group. Id>commons-logging</group. Id> <artifact. Id>commons-logging</artifact. Id> <scope>provided</scope> </dependency> <group. Id>javax</group. Id> <artifact. Id>javaee-api</artifact. Id> <scope>provided</scope> </dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. Impl</artifact. Id> <version>${project. version}</version> <scope>provided</scope> </dependency> </dependencies> v 131013 EJB: Session Beans 61
EJB Project: plugins Enterprise Java <build> <!--tell the resource plugin to perform filtering on resources to fill in dialect, etc. --> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resources> <plugins> <!-- tell the EJB plugin we are using EJB 3 and configure client-jar --> <plugin> <group. Id>org. apache. maven. plugins</group. Id> <artifact. Id>maven-ejb-plugin</artifact. Id> <configuration> <generate. Client>true</generate. Client> <client. Excludes> <client. Exclude>**/ejb/*Local. class</client. Exclude> <client. Exclude>**/ejb/*EJB. class</client. Exclude> </client. Excludes> </configuration> </plugins> </build> v 131013 EJB: Session Beans 62
EJB Project: profiles Enterprise Java <profiles> <profile> <!-- H 2 embedded/file-based DB --> <id>h 2 db</id> <properties> <jdbc. driver>org. h 2. Driver</jdbc. driver> <jdbc. url>jdbc: h 2: ${basedir}/target/h 2 db/ejava</jdbc. url> <jdbc. user>sa</jdbc. user> <jdbc. password/> <hibernate. dialect> org. hibernate. dialect. H 2 Dialect </hibernate. dialect> </properties>. . . </profile> </profiles> v 131013 EJB: Session Beans 63
EJB Project: persistence. xml Enterprise Java <? xml version="1. 0" encoding="UTF-8"? > <persistence xmlns="http: //java. sun. com/xml/ns/persistence" xmlns: xsi="http: //www. w 3. org/2001/XMLSchema-instance" xsi: schema. Location="http: //java. sun. com/xml/ns/persistence_2_0. xsd" version="2. 0"> <persistence-unit name=" ejbsessionbank"> <provider>org. hibernate. ejb. Hibernate. Persistence</provider> <jta-data-source >java: jboss/datasources/Example. DS</jta-data-source> <properties> <property name="hibernate. dialect" value="${hibernate. dialect}"/> <property name="hibernate. show_sql" value="false"/> </properties> </persistence-unit> • After filtering <property name="hibernate. dialect" value="org. hibernate. dialect. HSQLDialect "/> v 131013 EJB: Session Beans 64
EAR Project Enterprise Java ejbsession. Bank. EAR/ `-- pom. xml • pom. xml <project> <parent> <artifact. Id>ejbsession. Bank</artifact. Id> <group. Id>ejavaee. ejb</group. Id> <version>3. 0. 2012. 2 -SNAPSHOT</version> <relative. Path>. . </relative. Path> </parent> <model. Version>4. 0. 0</model. Version> <artifact. Id>ejbsession. Bank. EAR</artifact. Id> <packaging>ear</packaging> <name>Session Bank EAR</name> <dependencies> </dependencies> <build> </project> v 131013 EJB: Session Beans 65
EAR Project (cont. ): dependencies <dependencies> <dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. EJB</artifact. Id> <version>${project. version}</version> <type>ejb</type> <exclusions> <exclusion> <group. Id>commons-logging</group. Id> <artifact. Id>commons-logging</artifact. Id> </exclusions> </dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. WAR</artifact. Id> <version>${project. version}</version> <type>war</type> </dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. Impl</artifact. Id> <version>${project. version}</version> <exclusions> <exclusion> <group. Id>commons-logging</group. Id> <artifact. Id>commons-logging</artifact. Id> </exclusions> v 131013 </dependency> EJB: Session Beans </dependencies> Enterprise Java 66
EAR Project (cont. ): plugins Enterprise Java <build> <plugins> <plugin> <group. Id>org. apache. maven. plugins</group. Id> <artifact. Id>maven-ear-plugin</artifact. Id> <configuration> <description> Example Session Bean Bank Application </description> <default. Lib. Bundle. Dir>lib</default. Lib. Bundle. Dir> <!-- eliminates use of version in EAR JNDI name portion --> <application. Name>${project. artifact. Id}</application. Name> <modules> <web. Module> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. WAR</artifact. Id> <context. Root>ejbsession. Bank</context. Root> </web. Module> <!-- eliminates use of the version in the EJB JNDI name --> <ejb. Module> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. EJB</artifact. Id> <bundle. File. Name>ejbsession. Bank. EJB. jar</bundle. File. Name> </ejb. Module> </modules> </configuration> </plugins> </build> v 131013 EJB: Session Beans 67
EAR Project (cont. ) Enterprise Java • Use cargo plugin to undeploy built and deployed EARs <profile> <id>undeploy</id> <build> <plugins> <plugin> <group. Id>org. codehaus. cargo</group. Id> <artifact. Id>cargo-maven 2 -plugin</artifact. Id> <executions> <execution> <id>undeploy-ear</id> <phase>pre-clean</phase> <goals> <goal>undeploy</goal> </goals> </executions> </plugins> </build> </profile> v 131013 EJB: Session Beans 68
EAR Project (cont. ) Enterprise Java ejbsession. Bank. EAR/target/ejbsession. Bank. EAR-3. 0. 2012. 2 -SNAPSHOT |-- ejbsession. Bank. EJB. jar |-- ejbsession. Bank. WAR-3. 0. 2012. 2 -SNAPSHOT. war |-- lib | |-- ejava-util-3. 0. 2012. 2 -SNAPSHOT. jar | `-- ejbsession. Bank. Impl-3. 0. 2012. 2 -SNAPSHOT. jar `-- META-INF `-- application. xml v 131013 EJB: Session Beans 69
RMI Test Project Enterprise Java ejbsession. Bank. Test/ |-- pom. xml `-- src |-- main `-- test |-- java | `-- examples | `-- ejbsessionbank | `-- ejbclient | |-- Teller. Owner. Remote. Test. java | `-- Teller. Remote. Test. java `-- resources |-- jndi. properties `-- log 4 j. xml • pom. xml <project> <parent> <artifact. Id>ejbsession. Bank</artifact. Id> <group. Id>ejavaee. ejb</group. Id> <version>3. 0. 2012. 2 -SNAPSHOT</version> <relative. Path>. . </relative. Path> </parent> <model. Version>4. 0. 0</model. Version> <artifact. Id>ejbsession. Bank. Test</artifact. Id> <packaging>jar</packaging> <name>Session Bank Test</name> v 131013 EJB: Session Beans 70
RMI Test Project (cont. ) Enterprise Java <dependencies>. . . <!-- component to test within deployment--> <dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. EJB</artifact. Id> <version>${project. version}</version> <type>ejb-client</type> <scope>test</scope> </dependency> <!-- package being deployed must be a dependency --> <dependency> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. EAR</artifact. Id> <version>${project. version}</version> <type>ear</type> <scope>compile</scope> </dependency> <group. Id>ejava. common</group. Id> <artifact. Id>jboss-rmi-client</artifact. Id> <version>${project. version}</version> <type>pom</type> <scope>test</scope> </dependency>. . . v 131013 EJB: Session Beans 71
RMI Test Project (cont. ): plugins Enterprise Java <build> <plugins> <!-- artifacts to deploy to server --> <plugin> <group. Id>org. codehaus. cargo</group. Id> <artifact. Id>cargo-maven 2 -plugin</artifact. Id> <configuration> <deployables> <deployable> <group. Id>${project. group. Id}</group. Id> <artifact. Id>ejbsession. Bank. EAR</artifact. Id> <type>ear</type> </deployables> </configuration> </plugin> <group. Id>org. apache. maven. plugins</group. Id> <artifact. Id>maven-failsafe-plugin</artifact. Id> <configuration> <system. Property. Variables> <foo>${foovar}</foo> </system. Property. Variables> </configuration> </plugins> </build> v 131013 EJB: Session Beans 72
Summary Enterprise Java • Integrates Bean activity (“task script”) • Server-side code for client – Stateless and Stateful • Server-side cache for client – Stateful • POJO with minor amount of class metadata v 131013 EJB: Session Beans 73
References Enterprise Java • “Enterprise Java. Beans 3. 0, 5 th Edition”; Burke & Monsen-Haefel; ISBN 0 -596 -00978 -X; O'Reilly • “Mobile Design Patterns and Architectures”, http: //www. titu. jyu. fi/modpa/ (MODPA) – Remote Facade • http: //www. titu. jyu. fi/modpa/Patterns/pattern. Remote. Facade. html • “Patterns of Enterprise Archecture, Chapter 15: Remote Facade”; Martin Fowler – http: //www. theserverside. com/tt/articles/content/Fowler. P atterns/Fowler_ch 15. pdf v 131013 EJB: Session Beans 74
- Slides: 74