1 / 30

Session Beans EJB3.0

Session Beans EJB3.0. February 2010 – August 2010 eric.gerlofsma@hu.nl 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.

lizina
Download Presentation

Session Beans EJB3.0

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Session Beans EJB3.0 February 2010 – August 2010 eric.gerlofsma@hu.nl www.ericgerlofsma.nl

  2. 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

  3. A Remote Stateless SessionBean and his interface package efg.ejb; import javax.ejb.Remote; @Remote public interface HelloWorld { String sayHello(); } This is the Remote Interface implements package efg.ejb; import javax.ejb.Stateless; @Stateless public class HelloWorldBean implements HelloWorld { public String sayHello() { return "HelloWorld!"; } } This is the Remote EJB

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

  5. 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>

  6. JNDI binding • startup browser • http://Localhost:8080 • JMX Console • jboss service=JNDIView • 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)

  7. Client, lookup, cast, call package 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()); } } jndi.properties java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099

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

  9. 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>

  10. Client, lookup, no interface package 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)); } } jndi.properties java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099

  11. 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)

  12. Life cycle Stateless SessionBean? Does Not Exist Class.newinstance() injections @PostConstruct @PreDestroy Method Ready Pool business methods

  13. 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()"); }

  14. Interceptors for special jobs(1) package efg.ejb; import javax.ejb.Stateless; import javax.interceptor.Interceptors; @Stateless @Interceptors(MyInterceptor.class) public class HelloWorldBean implements HelloWorld { . . . } Class-declared-Interceptors are invoked, instead of calling a business method. An Interceptor gets the responsibility of calling the next entry in the interceptor chain. Finally the business method is called. Before and after the call special action, like logging, checking authentication and timing can be done.

  15. 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; } }

  16. Interceptors for special jobs(3) javax.interceptor.InvocationContext Map<String, Object> getContextData() Method getMethod() Object[] getParameters() Object getTarget() Object proceed() void setParameters(Object[] params)

  17. 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!

  18. Injected SessionContext @Resource private SessionContext sessionContext; EJBContext Principal getCallerPrincipal() booleanisCallerInRole(String rolename) Object lookup(String name) TimerServicegetTimerService() booleangetRollbackOnly() void setRollbackOnly() SessionContext

  19. 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>

  20. 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>

  21. 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.

  22. Life cycle Stateful SessionBean? Does Not Exist timeout Class.newinstance() injections @PostConstruct Exception @PreDestroy Method Ready Pool business methods @PrePassivate @PostActivate Passive

  23. Annotations • @PostConstruct • @PreDestroy • @PrePassivate • @PostActivate • @EJB • @Resource • @Stateless • @Stateful • @Remote • @Local • @RemoteBinding • @SecurityDomain • @DeclareRoles • @RolesAllowed

  24. 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>; }

  25. 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

  26. 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

  27. 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

  28. 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.

  29. 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; }

  30. Questions • 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? • A session bean has a local interface. Why is this session bean unreachable from the outside?

More Related