session beans ejb3.0

30
Session Beans EJB3.0 February 2010 – August 2010 [email protected] www.ericgerlofsma.nl

Upload: lizina

Post on 29-Jan-2016

30 views

Category:

Documents


0 download

DESCRIPTION

Session Beans EJB3.0. February 2010 – August 2010 [email protected] www.ericgerlofsma.nl. Basic Architecture of EJB3.0. Implementation Server and Client Stateless versus Stateful Remote versus Local The JNDI binding Life Cycle Interceptors Context The Annotations Deployment. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Session Beans EJB3.0

Session Beans EJB3.0

February 2010 – August [email protected] www.ericgerlofsma.nl

Page 2: Session Beans EJB3.0

Basic Architecture of EJB3.0• Implementation Server and Client• Stateless versus Stateful• Remote versus Local• The JNDI binding• Life Cycle• Interceptors• Context• The Annotations• Deployment

Page 3: Session Beans EJB3.0

A Remote Stateless SessionBean and his interface

package efg.ejb;import javax.ejb.Stateless;

@Statelesspublic class HelloWorldBeanimplements HelloWorld{ public String sayHello() { return "HelloWorld!"; }}

package efg.ejb;import javax.ejb.Remote;

@Remotepublic interface HelloWorld{ String sayHello();}

implements

This is the Remote Interface

This is the Remote EJB

Page 4: Session Beans EJB3.0

Directory Structure

HelloWorld├─jar│ └─efg│ └─ejb│ ├─HelloWorld.class│ └─HelloWorldBean.class├─src│ ├─HelloWorld.java│ └─HelloWorldBean.java└─build.xml

Page 5: Session Beans EJB3.0

Deployment build.xml<project name="efg_ejb3_stateless_helloworld" basedir="." default="jar" >

<property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server" value="${jboss.home}/server/default"/> <property name="jboss.deploy" value="${jboss.server}/deploy"/> <property name="app" value="${ant.project.name}.jar"/>

<path id="j2ee"> <fileset dir="${jboss.home}/client"> <include name="**/*.jar"/> </fileset> </path>

<target name="compile"> <javac srcdir="src" destdir="jar" deprecation="on"> <include name="**/*.java" /> <classpath refid="j2ee"/> </javac> </target>

<target name="jar" depends="compile"> <jar destfile="${app}" basedir="jar"/> <move file="${app}" todir="${jboss.deploy}"/> </target>

</project>

Page 6: Session Beans EJB3.0

JNDI binding1. startup browser2. http://Localhost:8080 3. JMX Console4. jboss service=JNDIView5. invoke list() and see:

Global JNDI Namespace with:+- HelloWorldBean (class: org.jnp.interfaces.NamingContext) +- remote (class: Proxy for: efg.ejb.HelloWorld) +- remote-efg.ejb.HelloWorld (class: Proxy for: efg.ejb.HelloWorld)

java:comp namespace of the component jboss.j2ee:jar=efg_ejb3_stateless_helloworld.jar ,name=HelloWorldBean ,service=EJB3 :

+- EJBContext (class: javax.ejb.EJBContext) +- TransactionSynchronizationRegistry[link -> java:TransactionSynchronizationRegistry] (class: javax.naming.LinkRef) +- UserTransaction (class: org.jboss.ejb3.tx.UserTransactionImpl) +- env (class: org.jnp.interfaces.NamingContext) +- ORB[link -> java:/JBossCorbaORB] (class: javax.naming.LinkRef)

Page 7: Session Beans EJB3.0

Client, lookup, cast, callpackage efg.ejb;import javax.naming.InitialContext;

public class Main{ public static void main(String[] args) throws Exception { InitialContext ctx = new InitialContext(); HelloWorld helloWorld = (HelloWorld)ctx.lookup("HelloWorldBean/remote"); System.out.println(helloWorld.sayHello()); }}

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactoryjava.naming.provider.url=jnp://localhost:1099

jndi.properties

Page 8: Session Beans EJB3.0

Client Directory Structure

client├─efg│ └─efg│ └─ejb│ ├─HelloWorld.class│ └─Main.class├─src│ ├─HelloWorld.java│ └─Main.java├─log4j.xml├─jndi.properties└─build.xml

Page 9: Session Beans EJB3.0

Deployment build.xml(only for TextPad not for Eclips)

<project name="HelloWorldClient" basedir="." default="exec" >

<property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server" value="${jboss.home}/server/default"/>

<path id="j2ee"> <pathelement path="."/> <fileset dir="${jboss.home}/client"> <include name="**/*.jar"/> </fileset> <fileset dir="${jboss.home}/lib"> <include name="**/*.jar"/> </fileset> </path>

<target name="compile"> <javac srcdir="src" destdir="."> <include name="**/*.java" /> <classpath refid="j2ee"/> </javac> </target>

<target name="exec" depends="compile"> <java classname="efg.ejb.Main" fork="false"> <classpath refid="j2ee"/> </java> </target>

</project>

Page 10: Session Beans EJB3.0

Client, lookup, no interfacepackage efg.ejb;import java.lang.reflect.Method;import javax.naming.InitialContext;

public class Main{ public static void main(String[] args) throws Exception { String sayHello = "sayHello"; InitialContext ctx = new InitialContext(); Object helloWorld = ctx.lookup("HelloWorldBean/remote"); Class[] param = {}; Method method = helloWorld.getClass().getMethod(sayHello, param); Object[] arg = {}; System.out.println(method.invoke(helloWorld, arg)); }}

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactoryjava.naming.provider.url=jnp://localhost:1099

jndi.properties

Page 11: Session Beans EJB3.0

Changing the JNDI-Name@Stateless(mappedName="ejb/HelloWorld/mappedName", name="ejb/HelloWorld/name")

+- ejb (class: org.jnp.interfaces.NamingContext) | +- HelloWorld (class: org.jnp.interfaces.NamingContext) | | +- name (class: org.jnp.interfaces.NamingContext) | | | +- remote-efg.ejb.HelloWorld (class: Proxy for: efg.ejb.HelloWorld)| | +- mappedName (class: Proxy for: efg.ejb.HelloWorld)

Page 12: Session Beans EJB3.0

Life cycle Stateless SessionBean?

Does Not Exist

Method Ready Pool

Class.newinstance()injections@PostConstruct

@PreDestroy

business methods

Page 13: Session Beans EJB3.0

Showing the Life cycle

/*****************************************************************\ Life Cycle Methods \*****************************************************************/ @PostConstruct public void postConstruct() { System.out.println("("+id+")HelloWorldBean.postConstruct()"); }

@PreDestroy public void preDestroy() { System.out.println("("+id+")HelloWorldBean.preDestroy()"); }

Page 14: Session Beans EJB3.0

Interceptors for special jobs(1)package efg.ejb;

import javax.ejb.Stateless;import javax.interceptor.Interceptors;

@Stateless@Interceptors(MyInterceptor.class)public class HelloWorldBeanimplements HelloWorld{ . . .}

Class-declared-Interceptors are invoked, instead of calling a business method.

An Interceptor gets the responsibility ofcalling the next entry in the interceptor chain.Finally the business method is called.

Before and after the call special action,like logging, checking authentication andtiming can be done.

Page 15: Session Beans EJB3.0

Interceptors for special jobs(2)package efg.ejb;

import javax.interceptor.InvocationContext;import javax.interceptor.AroundInvoke;

public class MyInterceptor{ @AroundInvoke public Object test(InvocationContext invocationContext) throws Exception { . . . Object ret = invocationContext.proceed(); . . . return ret; }}

Page 16: Session Beans EJB3.0

Interceptors for special jobs(3)javax.interceptor.InvocationContext

Map<String, Object> getContextData()Method getMethod()Object[] getParameters()Object getTarget()Object proceed()void setParameters(Object[] params)

Page 17: Session Beans EJB3.0

Interceptors for special jobs(2)15:46:14,775 INFO [STDOUT] (0)HelloWorldBean()15:46:14,775 INFO [STDOUT] MyInterceptor()15:46:14,775 INFO [STDOUT] MyInterceptor.test([ target=efg.ejb.HelloWorldBean@1bce9a , method=public java.lang.String efg.ejb.HelloWorldBean.sayHello() , parameters=[] , contextData={} ])15:46:14,775 INFO [STDOUT] Method=public java.lang.String efg.ejb.HelloWorldBean.sayHello()15:46:14,775 INFO [STDOUT] (0)HelloWorldBean.sayHello()15:46:14,775 INFO [STDOUT] return=HelloWorld!

Page 18: Session Beans EJB3.0

Injected SessionContext

@Resource private SessionContext sessionContext;

EJBContextPrincipal getCallerPrincipal()boolean isCallerInRole(String rolename)Object lookup(String name)TimerService getTimerService()boolean getRollbackOnly()void setRollbackOnly()

SessionContext

Page 19: Session Beans EJB3.0

No Annotations ejb-jar.xml(1)<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0"> <enterprise-beans> <session> <ejb-name>HelloWorldSessionBean</ejb-name> <mapped-name>HelloWorldMappedName</mapped-name> <business-remote>efg.ejb.HelloWorld</business-remote> <ejb-class>efg.ejb.HelloWorldBean</ejb-class> <session-type>Stateless</session-type> <remove-method> <bean-method> <method-name>sayHello</method-name> </bean-method> </remove-method> <post-construct> <lifecycle-callback-method>postConstruct</lifecycle-callback-method> </post-construct> <pre-destroy> <lifecycle-callback-method>preDestroy</lifecycle-callback-method> </pre-destroy> </session> </enterprise-beans>

Page 20: Session Beans EJB3.0

No Annotations ejb-jar.xml(2) <interceptors> <interceptor> <interceptor-class>efg.ejb.MyInterceptor</interceptor-class> <around-invoke> <method-name>test</method-name> </around-invoke> </interceptor> </interceptors> <assembly-descriptor> <security-role> <role-name>beheerder</role-name> </security-role> <security-role> <role-name>klant</role-name> </security-role> <method> <ejb-name>HelloWorldSessionBean</ejb-name> <method-name>sayHello</method-name> </method> </method-permission> <interceptor-binding> <ejb-name>HelloWorldSessionBean</ejb-name> <interceptor-class>efg.ejb.MyInterceptor</interceptor-class> <method> <method-name>sayHello</method-name> </method> </interceptor-binding> </assembly-descriptor></ejb-jar>

Page 21: Session Beans EJB3.0

Stateless or Stateful SessionBean?

A SLSB has no state: they don’t have properties(global variables).A SLSB is thread safe: multiple clients can share the same SSB.The container instantiates a SLSB only once.The container can hold 100 SLSB’s. see server/default/conf/standardjboss.xml

A SFSB has state.A SFSB is connected to one client only.A SFSB must be destroyed if the client timed out. A SFSB needs a complex management model.Don’t use a SFSB if it is not necessary.

Page 22: Session Beans EJB3.0

Life cycle Stateful SessionBean?

Does Not Exist

Method Ready Pool

Class.newinstance()injections@PostConstruct

@PreDestroy

business methods

Passive

@PrePassivate @PostActivate

timeout

Exception

Page 23: Session Beans EJB3.0

Annotations• @Stateless• @Stateful• @Remote• @Local• @RemoteBinding

• @SecurityDomain• @DeclareRoles• @RolesAllowed

• @PostConstruct• @PreDestroy• @PrePassivate• @PostActivate

• @EJB• @Resource

Page 24: Session Beans EJB3.0

Stateless / Stateful

package javax.ejb;

@Target(TYPE)@Retention(RUNTIME)public @interface Stateless{ String description() default ""; String mappedName() default ""; String name() default <ejb-name>;}

package javax.ejb;

@Target(TYPE)@Retention(RUNTIME)public @interface Stateful{ String description() default ""; String mappedName() default ""; String name() default <ejb-name>;}

Page 25: Session Beans EJB3.0

Remote / Local

package javax.ejb;

@Target(TYPE)@Retention(RUNTIME)public @interface Remote{ Class[] value default {};}

package javax.ejb;

@Target(TYPE)@Retention(RUNTIME)public @interface Local{ Class[] value default {};}

If the SessionBean has no Remote or Local annotations and the SessionBean implements a business interface, that interface is by default a Local business interface.

A default global JNDI binding is created. <ejb-name>/remote<ejb-name>/local

Page 26: Session Beans EJB3.0

Life Cycle

package javax.annotation;

@Documented@Target(METHOD)@Retention(RUNTIME)public @interface PostConstruct

package javax.annotation;

@Documented@Target(METHOD)@Retention(RUNTIME)public @interface PreDestroy

package javax.ejb;

@Target(METHOD)@Retention(RUNTIME)public @interface PostActivate

package javax.ejb;

@Target(METHOD)@Retention(RUNTIME)public @interface PrePassivate

Page 27: Session Beans EJB3.0

Security

package javax.annotation.security;

@Documented@Target(TYPE)@Retention(RUNTIME)public @interface DeclareRoles

package javax.annotation.security;

@Documented@Target(TYPE, METHOD)@Retention(RUNTIME)public @interface RolesAllowed

Page 28: Session Beans EJB3.0

EJB reference

package javax.ejb;

@Target(TYPE, METHOD, FIELD)@Retention(RUNTIME)public @interface EJB{ String description default ””; Class beanInterface default Object.class; String beanName default ””; String mappedName default ””; String name default ””;}

If mappedName is used: it is the global JNDI name of the EJB you are referencing, and all other attributes are ignored.

If beanName is used: the container searches for the beanName as <ejb-link> , and all other attributes are ignored.

If no attributes are used: the container searches for the declarated bean interface, and throws an Exception if duplicates are found.

Page 29: Session Beans EJB3.0

Resource reference

package javax.annotation;

@Target(TYPE, METHOD, FIELD)@Retention(RUNTIME)public @interface Resource{ String description default ””; Class type default Object.class; String name default ””; String mappedName default ””; boolean sharable default true; Resource.AuthenticationType authentication default CONTAINER;}

Page 30: Session Beans EJB3.0

Questions

1. The interface HelloWorld in the client is a copy of the HelloWorld interface in the Server. Is it still the same interface if the packages are different? Is it still the same interface if the classnames are different?

2. A session bean has a local interface. Why is this session bean unreachable from the outside?