You are currently browsing the monthly archive for February 2008.
This post is to compile many way to access your EJB3 session/entity bean. Also You can use Singlton ServiceLocator(J2EE design pattern) to look up the EJB session bean from the JNDI Naming Server.
So your application flow would be something like this:
JSP (View) -> Servlet (Controller) -> Business Delegate (J2EE Design Pattern) -> Service Locator (J2EE Design Pattern) -> Session Bean (Business Tier)
=====================================================================
EJB3 session bean
=====================================================================
//session interface
package com.myapp;
import javax.ejb.Stateless;
public interface HelloEJB3 {
public String sayHello();
}
//session implementation
package com.myapp;
import java.ejb.Stateless;
@Stateless
@local
public class HelloEJB3Bean implements HelloEJB3 {
private String greeting = “Hello, EJB3!”;
public String sayHello() { return greeting; }
}
=====================================================================
Using Java EE component to call session bean
=====================================================================
/**
* servelt with EJB3 annotation to access session bean
*/
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
public class HelloServlet1 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
@EJB
private HelloEJB3 hellobean;
protected void sayHello() {
System.out.print.(hellobean.sayHello());
}
}
/**
* If you are using a standard Java EE component (Servlet, JSP, EJB, or Java EE Application Client),
* you will not need to set the properties explicitly when creating a JNDI InitialContext , no matter
* which EJB vendor you are using. That’s because the JNDI properties can be configured at deployment time
* and are applied automatically.
*/
public class HelloServlet2 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
Context jndiContext = getInitialContext( );
HelloEJB3 hellobean = (HelloEJB3)jndiContext.lookup(“java:comp/env/ejb/HelloEJB3″);
protected void sayHello() {
System.out.print.(hellobean.sayHello());
}
public static Context getInitialContext( ) throws javax.naming.NamingException {
return new javax.naming.InitialContext( );
}
}
/**
* Once the session bean is deployed into the EJB 3.0 container, a stub object is created and
* it is registered in the server’s JDNI registry. The client code obtains a stub of the bean
* from the JNDI using its default JNDI name formatted as follows.
*
* If the application is deployed in a EAR file, the default JNDI name is
* the EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local for the stub for local interface.
* For the remote interface, it is EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote.
*
* If the bean is deployed in a JAR file, the JNDI names are EJB-CLASS-NAME/local
* and EJB-CLASS-NAME/remote.
*/
/**
* JSF managed bean
*/
public class HelloMagBean {
Context jndiContext = getInitialContext( );
HelloEJB3 hellobean = (HelloEJB3)jndiContext.lookup(“MYEJB3Trail/HelloEJB3/local”);
protected void sayHello() {
System.out.print.(hellobean.sayHello());
}
public static Context getInitialContext( ) throws javax.naming.NamingException {
return new javax.naming.InitialContext( );
}
}
/**
* JSP initial page
*/
<%@ page import=”trail.slsb.*, javax.naming.*, java.text.*”%>
<%!
private HelloEJB3 hellobean = null;
public void jspInit () {
try {
InitialContext ctx = new InitialContext();
hellobean = (HelloEJB3) ctx.lookup(“MYEJB3Trail/HelloEJB3/local”);
} catch (Exception e) {
e.printStackTrace ();
}
}
%>
=====================================================================
stand alone client to access session bean such as swing application
=====================================================================
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import java.util.Properties;
import javax.rmi.PortableRemoteObject;
public class HelloClientPOJO
{
HelloEJB3 hellobean;
public HelloClientPOJO() {
try{
Context jndiContext = getInitialContext( );
Object ref = jndiContext.lookup(“java:comp/env/ejb/HelloEJB3″);
hellobean = (HelloEJB3)ref;
} catch (javax.naming.NamingException ne){
//nothing
}
}
protected void sayHello() {
System.out.print.(hellobean.sayHello());
}
public static void main(String [] args)
{
HelloClientPOJO helloClient= new HelloClientPOJO();
helloClient.sayHello();
}
// developed for JBoss only. this is vender dependency
public static Context getInitialContext( ) throws javax.naming.NamingException {
Properties p = new Properties( );
p.put(Context.INITIAL_CONTEXT_FACTORY, “org.jnp.interfaces.NamingContextFactory”);
p.put(Context.URL_PKG_PREFIXES, ” org.jboss.naming:org.jnp.interfaces”);
p.put(Context.PROVIDER_URL, “jnp://localhost:1099″);
return new javax.naming.InitialContext(p);
}
}
=====================================================================
Spring bean to access session bean
=====================================================================
<bean id=”helloEJB3″ class=”org.springframework.jndi.JndiObjectFactoryBean”>
<property name=”jndiName” value=”java:comp/env/ejb/HelloEJB3″ />
<property name=”expectedType” value=”com.myapp.HelloEJB3″ />
</bean>
<bean id=”helloSpringPOJO” class=”com.nmetric.HelloSpringPOJO”>
<property name=”helloEJB3″ ref=”helloEJB3″/>
</bean>
public class HelloSpringPOJO
{
HelloEJB3 hellobean;
public HelloSpringPOJO() {}
protected void sayHello() {
System.out.print.(hellobean.sayHello());
}
public void setHelloEJB3(HelloEJB3 hellobean){
this.hellobean = hellobean;
}
}
References:
Using an EJB Session Bean as a Model Facade
Using Spring with EJB 3
Accessing objects in JNDI using Spring
JBoss EJB 3.0 and Extensions
The Transaction Context Problem is base on you can’t pass the transaction from one Bean to another. For example, FinacialService and DeptService has their own trnsaction management. If DeptService failed, we can only rollback DeptService. This is violated Transaction’s ACID principle.
class EmployeeServiceBean imeplements EmployeeService {
public void hire(){
FinacialService.insert();
DeptService.insert();
}
}
Using Spring, we can add transaction proxy and AOP to make this method as Unit of work.
<bean id="employeeService" class="com.myapp.EmployeeServiceBean"> ... </bean> <bean id="employeeService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="trxManager"/> <property name="target" ref="employeeService"/> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED, -Exception</prop> </props> </property> </bean>
Using EJB3, we see it’s simple.
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class EmployeeServiceBean {
@Resource
private SessionContext context;
...
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void hire(){
try {
FinacialService.insert();
DeptService.insert();
} catch (ApplicationException ae) {
context.setRollbackOnly();
}
}
}
I am researching how to use JCA (J2EE Connector Architecture) to integrate with ERP, EIS system. Here is my colletions.
J2EE Connector Overview:
The J2EE Connector architecture defines a standard architecture for connecting the J2EE platform to heterogeneous EISs. Examples of EISs include ERP, mainframe transaction processing, database systems, and legacy applications not written in the Java programming language. By defining a a set of scalable, secure, and transactional mechanisms, the J2EE Connector architecture enables the integration of EISs with application servers and enterprise applications
Sun: J2EE Connector Architecture
Understanding JCA transactions
Connect the enterprise with the JCA
Some musings on JCA (Java Connector Architecture)
Develop inbound connectors with JCA 1.5
Using Resource Adapters outside of EE containers
Connectors on JBoss
JCA at Oracle Containers for J2EE (OC4J) plus BEA Tuxedo 8.1
There are many discussion about Spring compared EJB 3.0. Here base on my developing experience, I share my humble opinion and some useful references.
1. Architecture difference:
-Spring advocates OOP and DDD
Using Spring the application usually adopts the Domain Model pattern that implements the business logic using good old fashioned object-oriented analysis and design techniques (OOAD). Most of project follow the Domain-Driven Design and
has the following roles: Entities, Value objects, Factories, Repositories, Services. Spring implements DI and AOP to simplify OOP design.
-EJB3 advocates Session Façade
Using EJB3 the application forces its components into three categories: session beans, entity beans, and message-driven beans even though in a typical object model there are classes that do not fall into one of these three categories. As
a result, many classes are unable to use the services provided by the EJB3 container.
Use a Session Façade to encapsulate business-tier components and expose a coarse-grained service to remote clients.
Clients access a Session Façade instead of accessing business components directly. Inside Session Facade you put the business logic and implement business object(domain object) as Entity bean.
2. Implementation difference:
– Spring is run out of JEE container
Spring is not an alternative for Java EE. Rather, it builds on top of Java EE, by making the JEE libraries less verbose to use, and by solving common programming errors. Spring actually supports EJB3 features, especially the nice Java Persistence API. Spring is not a package deal. You can use the IoC container without using Spring WEB MVC, for instance. You can choose to use the JpaTemplate , but you can also use the EJB3 Java Persistence API directly, by injecting an EntityManager. It´s all about choice.
- EJB3 is supported by JEE container
Despite EJB3 limitations, it is extremely likely that EJB 3 will be widely used for the simple reason that it is part of the J2EE standard. It is also important that EJB is an appropriate implementation technology for two types of applications: Applications that use distributed transactions initiated by remote clients. And applications that are heavily message-oriented and need message-driven beans.
Reference:
POJO Application Frameworks: Spring Vs. EJB 3.0
Make the Right Decision with Our Side-by-Side Comparison of Spring and EJB 3.0 part-I; part-II
J2EE design decision
Pro Spring: Spring and EJB
Something about domain model:
Domain Modeling – What exactly is a Rich Model ?
The relationship between the domain model and repositories





