EJB 3.1, Time and Date and JPA 2.0 Java Champion,Netbeans Dream Team Member, (JavaONE) speaker, freelancer, consultant and author: 7 German books + working on “Real World Java EE Patterns– Rethinking Best Practices” http://press.adam-bien.com Trainer, Developer and Architect (since JDK 1.0) Project owner/committer: http://kenai.com/projects/javaee-patterns, greenfire.dev.java.net, p4j5.dev.java.net, fishfarm.dev.java.net
conventions... (there was no XML in my last projects except persistence.xml) EJB 3 are just annotated Java classes (if you love XML you can even use just Deployment Descriptors instead of annotation) Container “services” like transactions, security, concurrency or state are implemented with aspects (often realized with dynamic proxies)
another container, using similar techniques as EJB 3.1 EJB 3 containers are surprisingly small. Glassfish v3 EA comes with two jars (688kB + 8kB = 696kB). The EJB 3 container is an OSGI bundle... The whole EJB 3.1 API is about 47 kB.
outside the container, you will need to have the EJB 3.1 annotations available in your classpath. In recent projects we deployed EJB 3.0 components directly to Eclipse / Netbeans RCP application. We could start and test the application without even having an application server involved. If you can start EJBs outside the container, you can start them in a unit test as well...
annotated POJOs - you can test them as such. Transaction / Security can be harder to test - but integration tests are better for that purpose. In EJB 3.1 the testing experience is even better with:
- EJB 3.X / JPA specs cover more real world stuff (locking, optimistic concurrency etc.). Vendor specific deployment descriptor were painful for migration - they are basically gone. In most cases a EJB-JAR module is nothing but a JAR without any XML descriptors (neither ejb-jar.xml nor vendor specific) Vendor specific annotations are not needed to develop a Java EE application. There is NOTHING vendor specific in an EAR. The portability is really good.
the Bean instance directly. Having an instance available - you can manipulate it; inject members use reflection to invoke methods, or set fields... It is very interesting for the integration of existing “legacy” IoC frameworks :-)
solution was 2391 transactions/second. The slowest method call took 7 milliseconds. The average wasn't measurable. Please keep in mind that in every request two session beans were involved - so the overhead is doubled. POJO: The throughput of the POJO solution was 2562 requests/second (request - there are no transactions here). The slowest method call took 10 ms. The difference is 171 requests / seconds, or 6.6% (therefore 3.3% for a single session bean).
3.0 and 3.1) are always executed in a dedicated thread - they appear as single threaded for the developer. For every thread (=user request, transaction) a new EJB instance is created (or reused from pool) - there is actually no shared state, except you access singletons, files etc. - which is not allowed. Actually the spec even prohibits the usage of the synchronization primitives and threading functionality inside EJBs.
rather procedural (or if you will "service oriented") - so in the @Stateless Session Beans the methods process some input data and give it back to the caller. Even the @Stateful Session Beans do not brake the rule - the container still prohibits concurrent access to the @Stateful instance. Because a @Stateful Session Bean can be only executed in a single thread - you do not have (you shouldn't!) care about the threading either.
- the container synchronizes the data for you. Every transaction receives a copy of the JPA-entity (it is often implemented in this way), so nothing bad can happen even in this case. Every thread is (hopefully) executed in a single core. So if you keep the transactions short, and do not "hack" the EJBs accessing static variables or singletons - you are on the bright side :-).
a (pooled) thread. Bean instances are bound to the thread for the duration of the execution. Load balancing works perfectly - you can start as many servers as you like to. Even without having a cluster... For SFSB “session affinity” can improve the scaleability significantly. Programming restrictions do encourage “functional programming” (no shared state, blocking, threads)
Glassfish v2ur2 on Linux, Clustered, a 4 way, Intel based machine and JDK 1.5 (JDK 1.6 would be better, but was not available in this case). Two load-generators ran remotely (via IIOP, standard EJB 3 client), each with 50 virtual users. Settings: -Xmx to 512m: no further tuning was performed. Configuration: CRUD application as load generator, without think-time, and almost empty database, just to stress the appserver as much as possible. Result: 250 - 500 Transactions / second (we weren't alone on the machine :-().
concurrent platform per definition. It mainly abstracts already existing products (messaging, EIS, relational databases) Distributed programming with shared state is always a challenge. In the Cloud Computing / SOA era non-functional requirements like: monitoring (JMX), management, fail- over or elasticity become more and more important. Think about the ratio between the essential and accidential complexity...
additional declaration in web.xml 2. No programmatic configuration needed. 3. Just inject SLSB into request-scoped and SFSB into session-scoped backing beans public class StatefulBackingBean{ @EJB private OrderGateway orderGateway; }
declaration in web.xml 2. No programmatic configuration needed. 3. Just inject SLSB into the servlet and lookup SFSB and put them into the HTTPSession public class LoadServlet extends HttpServlet{ @EJB private PersonService service; }
test scenarios for the EJB layer: • Inject your bean into the servlet • Implement the test-flow in doGet method • Use e.g. http://jakarta.apache.org/jmeter to generate the load • Use JConsole / VisualVM to monitor server • Watch the resource consumption and throughput.
can be configured using XML in different ways. You can use dependency injection, as well as programmatic lookup for this purpose. The dependency injection approach allows you the definition of default values in the bean class, which can be overwritten in the deployment descriptor (the XML- file).
with EJB 2 You can deploy EJB 2 beans as EJB 3 You can then inject EJB 2 instances straight into EJB 3 After this step you can just delete the XML etc. Is up to you, whether you would like to delete the superfluous artifacts like home-, remote interfaces. XML deployment descriptors are no more needed after the migration...
will need the the EJB 3.0 / 3.1 API in the classpath, or at least the @Stateless annotation. How to deploy: Just JAR the class and put the JAR into e.g: [glassfishv3-prelude- b23]\glassfish\domains\domain1\autodeploy How to use: import javax.ejb.EJB; public class MyServlet extends HttpServlet{ @EJB private SimpleSample sample; }
is an exposed service. A service is a contract with significant business value. A clear relationship should exist between the service contract and a business requirement, a use case, or even a user story. A service can be realized as a single action or a set of cohesive actions. A service might comprise a single action that performs the actual order, or a group of related operations that also include canceling the order and receiving the order status
details about how a service must be implemented; it aims for services to be technology- and even location-agnostic. Whether the service is local or remote, the business logic should always be executed consistently. A component needs a dedicated remoting and transaction boundary interface, which acts as a gatekeeper. The main responsibility of such a facade is to keep the granularity of the methods coarse and the persistent state of the component consistent.
business logic, rather than realize the “flow”. Boundaries are coordinators. Services do implement business logic and are exposed with the Boundary (ServiceFacade). Boundaries makes the Services coarser.
it is the realization of the business logic. In the SOA world it has rather procedural nature. A service resides behind the facade, so it can never be accessed directly by the UI or other presentation components. A service is stateless and can be only called by the facade. Every facade's method starts a new transaction, so a service can safely rely on the transactions' existence.
bit. A Service is a procedural activity. It realizes activities or sub processes. In an object oriented, domain driven context, a Service realizes cross cutting, domain object independent logic. In a SOA a Service plays the main role and implements the actual business logic.
bean. Service resides in a component which is realized as Java- package with domain-specific name e.g. ordermgmt. The realization of the service (business interface and the bean implementation) resides in a sub-package with the name “service” e.g. ordermgmt.service. This makes the automatic verification of the architecture easier. The business interface is named after business concepts, without the obligatory local or remote suffix e.g. OrderService and OrderServiceBean.
are transient. Service Facades (boundaries) are transient either. Entities do contain persistent state, but no business logic (procedural again). Entity are actually not objects, rather than structs. Entities are manipulated by Services, sometimes Service Facades.
Entity: persistent object (“domain objects” from conceptual model) Control: process knowledge - entity independent logic, the glue between the boundary and the entity Boundary: the interface between the actor and the use case
where o.customerId = :customerId") public class Order { public final static String PREFIX ="..ordermgmt.domain.Order"; public final static String findByCustomerId = PREFIX + "findByCustomerId"; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private int customerId; //millions of getters/setters :-) }
@PersistenceContext EntityManager em; public Order processOrder(int customerId, int productId, float price) { Order order = new Order(customerId, productId, price); em.persist(order); return order; } }
to the design of software, based on the two premises that complex domain designs should be based on a model, and that, for most software projects, the primary focus should be on the domain and domain logic (as opposed to being the particular technology used to implement the system).
form a common language given by domain experts for describing system requirements, that works equally well for the business users or sponsors and for the software developers.
Directly Stateful Local (should be accessed “per reference”) Its lifecycle depends on the web components Realizes only domain object independent logic and cross cutting aspects
views No-interface view is sufficient Often caches the root entity - plays the role of Domain Repository Controls transactions Implements queries and basic CRUD operations Is accessed directly by the UI
state. There is no need for further encapsulation – they can be directly exposed to the presentation. A Gateway provides an entry point to the root PDOs. A Gateway could be even considered as an anti-Service Façade – in fact its responsibilities are inverted.
to access them directly without an execution context. The next problem is the stateless nature of most Java EE applications... After a method invocation of a transaction boundary (e.g. a Stateless Session Bean) all JPA-entities (PDOs) become detached. The client loses its state.
objects” does mean cohesive classes with encapsulated state, related behavior and with inheritance. Just put business logic into the domain objects and use inheritance were appropriate. JPA turns is really flexible in mapping rich domain objects into relational tables. The more complex logic you have to realize, the easier can object oriented persistence be maintained and developed.
to differentiate between the entity types. Such checks are needed to realize type-dependent behavior in procedural way. Every introduction of a new subclass, or even change of the existing business logic requires to find, enhance and test the type checks. The computation of shipping costs dependent on weight and the OrderItem type would look like this in procedural world.
to domain logic and not the technology. PDO resides in a component which is realized as Java- package with domain-specific name e.g. ordermgmt. The PDO resides in a sub-package (layer) with the name domainordermgmt.domain. This makes the automatic verification of the architecture easier. The name of the domain object is derived from the target domain. Getters and setters are not obligatory – they should be only used in justified cases.
but they model behavior which also changes the state of the domain objects. All methods are named in fluent way. It is not required to use the term “PDO” in the name of the entity – it is redundant. For identification purposes you could use a @PDO annotation.
JPA introduced inheritance and polymorphic queries to the persistence layer. JPA entities are just annotated Java classes with only insignificant restrictions, so already object oriented approaches and patterns can be applied to persistence layer now.
way, how complex logic is going to be developed. The persistence layer should consist of self-contained domain objects with clear responsibilities and encapsulated state and behavior. The persistence is just an aspect concern and should not have any impact on design and not in particular on the amount of logic residing in domain objects.
often procedural logic should be implemented in a Service. Actually the Persistent Domain Objects becomes a best practice and the Anemic Domain Model an anti pattern, ...at least in more ambitious projects.
powerful new set of services to Java EE components. The lifecycle and interactions of stateful components bound to well- defined lifecycle contexts, where the set of contexts is extensible A sophisticated, typesafe dependency injection mechanism, including a facility for choosing between various components that implement the same Java interface at deployment time Integration with the Unified Expression Language (EL), allowing any component to be used directly within a JSF or JSP page The ability to decorate injected components An event notification model A web conversation context in addition to the three standard web contexts defined by the Java Servlets specification An SPI allowing portable extensions to integrate cleanly with the Java EE environment
typesafe dependency injection model, contextual lifecycle management for injectable objects, an event notification model, interceptor bindings via user-defined annotations, typesafe decorators, a complete SPI for integration of third-party web or component frameworks, and integration with JSF, servlets and JSP, including a conversation context for JSF
box you can inject into just about any kind of thing in the Java EE environment, including servlets, servlet filters, servlet event listeners, JAX-WS web service endpoints and JAX-RS resources. The kinds of objects you can inject include: managed beans (plain Java classes), local EJB session beans, objects obtained from a producer method or producer field, Java EE component environment resources (datasources, connectors, persistence contexts, JMS message destinations, web services, remote EJBs, etc.)
so that any third-party framework (for example, a web framework like Wicket) can easily ask the 299 implementation to perform injection upon objects managed by the framework.
of JSR-299 is planned, which will support the JSR-330 bootstrap API. For now, if you want to run JSR-299 in the SE environment, you'll need to use a vendor-specific bootstrap API.
Design. In Java EE 6 there are no conversations (aka Map in HttpSession:-)) JSR-299 will allow multiple sub-sessions inside the HttpSession The lifecycle of @Stateful Beans is managed by web- components -> “memory leaks” possible. DI is more powerful, than in EJB 3.1.