EJB Concepts: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(104 intermediate revisions by the same user not shown)
Line 2: Line 2:


* [[EJB#Subjects|EJB]]
* [[EJB#Subjects|EJB]]
=Local and Remote Interfaces=
In EJB, a ''remote interface'' is the definition of the bean's contract for functionality that is intended to provided to remote clients. A remote client is a client that runs in a different JVM than the one that executes the target EJB container. The remote interface semantics implies ''pass-by-value'': this allows the method's arguments and results to be serialized, and possibly sent over the network. Hence, the arguments and the result must be Serializable. The remote programming model provides loose coupling between components. The pass-by-value semantics provides isolation between caller and callee and protection against inadvertent modification of data. Remote programming model comes with a performance penalty, because they must assume serialization/deserialization costs, network latency, the overhead of the client and server software stack, etc. This is why it is a good idea to use remote interface model coarse-grained business interaction - multiple calls at a high rate into remote interfaces may not be feasible.
A ''local interface'' contains the definition of the functionality available to local clients, which mean clients running in the same JVM, and more than that, clients deployed as part of the same application artifact. Supporting local access to clients deployed as part of a different application deployed in the same JVM is optional, but may be provided if the JEE server implementation decided so; however, applications relying on inter-application local interface access should be seen as non-portable. A local interface implies ''pass-by-reference'' semantics, which means the bean will have access to the instances of the objects whose references are passed as argument, and the caller will have access to the instances of the object whose reference is returned as result. EJBs that provide a local client view must be coded to assume that the state of any Java object that is passed as argument and result is potentially shared by caller and callee. Caution should be exercised in determining which object pass across the local view, especially when there is a change in a transactional or security context.
While it is possible to provide both a remote client view and a local client view for an EJB, more typically only one or the other will be provided.
Also see:
* [[EJB_Annotations#.40javax.ejb.Remote|@Remote]]
* [[EJB_Annotations#.40javax.ejb.Local|@Local]]


=EJB and JNDI=
=EJB and JNDI=


Session beans are bound to JNDI according to the following naming scheme:
Session beans are bound to JNDI according to a portable naming scheme. The most generic format is:


<pre>
<pre>
ejb:/<application-name>/<module-name>/<distinct-name>/<bean-name>!<view-class-name>?stateful
ejb:[/<application-name>]/<module-name>/<distinct-name>/<bean-name>[!<view-class-name>]?stateful
</pre>
</pre>


where:
Simplified formats are possible within the context of specific namespaces, as described in the [[#Namespaces|Namespaces]] section.
 
==JNDI Path Components==


====application-name====
====application-name====


''application-name'' is the name of the EAR application the session bean is deployed as part of.
''application-name'' is the name of the EAR application the session bean is deployed as part of. It is an optional component. If the session bean is not deployed as part of an EAR, that part is left blank, and the JNDI name starts with ejb:/<module-name>.... If the session bean deployed as part of an EAR, the part is by default the name of the EAR file, without the .ear suffix. The name can be overridden in the application.xml deployment descriptor by specifying the [[Application.xml#.3Capplication-name.3E|<application-name>]] element.


If the session bean is not deployed as part of an EAR, that part is left blank.
====module-name====


If the session bean deployed as part of an EAR, the part is by default the name of the EAR file, without the .ear suffix. The name can be overridden in the application.xml deployment descriptor by specifying the [[Application.xml#.3Capplication-name.3E|<application-name>]] element.
''module-name'' is the name of the JAR (or WAR) file the session bean is deployed in. It is a mandatory component. By default, is the file name of the JAR without the ".jar" suffix. The module name can be override in ejb-jar.xml by specifying the [[Ejb-jar.xml#.3Cmodule-name.3E|<module-name>]] element.


====module-name====
====distinct-name====


''module-name'' is the name of the JAR file the session bean is deployed in. By default, is the file name of the JAR without the ".jar" suffix. The module name can be override in ejb-jar.xml by specifying the [[]] element.
Each deployment may specify an optional distinct name. It is an optional component. If the deployment does not have a distinct name, the corresponding JNDI path element should be left blank.


The JNDI bindings for session bean named 'SimpleStatelessBean' in deployment unit 'deployment "stateless-ejb-example.jar"' are as follows:
The JNDI bindings for session bean named 'SimpleStatelessBean' in deployment unit 'deployment "stateless-ejb-example.jar"' are as follows:


====bean-name====
The simple name of the class implementing the session bean. It is a mandatory component.
====view-class-name====
The fully qualified class name of the remote interface. It is an optional component.
====?stateful====
This suffix is required when the JNDI name refers to a stateful session bean.
==Namespaces==
Upon deployment, the component will be registered in JNDI, in the following contexts: [[#java:global|java:global]], [[#java:app|java:app]] and [[#java:module|java:module]], which are accessible only to the current JVM, and also in [[#java:jboss.2Fexported|java:jboss/exported]], which is accessible remotely.
For more details on JEE JNDI Namespaces, see {{Internal|WildFly_JNDI_Concepts#JNDI_JEE_Namespaces|JNDI JEE Namespaces}}
==JNDI Name Examples==
===EJB deployed in JAR===
The following bean has been deployed as part of stateless-ejb-example.jar, it is implemented by io.novaordis.playground.jee.ejb.stateless.SimpleStatelessBean and exposes the io.novaordis.playground.jee.ejb.stateless.SimpleStateless remote interface.
<pre>
<pre>
java:global/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:global/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
Line 37: Line 74:
</pre>
</pre>


=Invoking into EJBs=
The last three names are short forms, and they are registered if the EJB component only exposed one interface.
 
===EJB deployed in EAR===
 
The following bean has been deployed as part of a stateless-ejb-example.jar, which was embedded in stateless-ejb-and-servlet.ear.
 
<pre>
java:global/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:app/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:module/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:jboss/exported/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:global/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean
java:app/stateless-ejb-example/SimpleStatelessBean
java:module/SimpleStatelessBean
</pre>


<font color=red>TODO https://blog.akquinet.de/2014/09/26/jboss-eap-wildfly-three-ways-to-invoke-remote-ejbs/</font>
The last three names are short forms, and they are registered if the EJB component only exposed one interface.


=EJB Remote Applications=
=Remote EJB Applications=


An EJB remote application can be one of the following:
An EJB remote application can be one of the following:
* <span id="standalone_ejb_client"></span>a standalone Java application
* <span id="standalone_ejb_client"></span>a standalone Java application
* <span id="deployed_application">another component that runs within a application server instance, and makes invocations into remote EJBs. In this case, each deployed application will have its own [[#EJB_Client_Context|EJB client context]], and the application's components will share the EJB client context.
* <span id="deployed_application">another component that runs within a application server instance, and makes invocations into remote EJBs. In this case, each deployed application will have its own [[#EJB_Client_Context|EJB client context]], and the application's components will share the EJB client context.
=Invoking into EJBs=
The invocation mechanics is different depending on where the caller and the target EJBs reside relatively to each other. There are several cases:
==Collocated Client Component and Target EJB==
* The caller is a component collocated with the target EJB in the same deployment unit (JAR, WAR or EAR).
{{Internal|Session EJB and Servlet Collocated in Same WAR, JNDI Lookup|Servlet and EJB deployed as part of the same WAR, the servlet looks up the EJB in JNDI}}
{{Internal|Session EJB and Servlet Collocated in Same WAR, @EJB Injection|Servlet and EJB deployed as part of the same WAR, the servlet gets the EJB reference injected with @EJB}}
{{Internal|Session EJB and Servlet as Different EAR Modules, JNDI Lookup|Servlet and EJB deployed as part of the same EAR, in different modules, the servlet looks up the EJB in JNDI}}
{{Internal|Session EJB and Servlet as Different EAR Modules, @EJB Injection|Servlet and EJB deployed as part of the same EAR, in different modules, the servlet gets the EJB reference injected with @EJB}}
* The caller is a component deployed as part of a different deployment unit than the target EJB, but both components are deployed on the same Application Server (JBoss) instance. This is an example that shows how the client component looks up the EJB via JNDI and also how can it get it via @EJB injection:
{{Internal|Session EJB and Servlet in Different Deployment Units on Same JBoss Instance|Session EJB and Servlet in Different Deployment Units on Same JBoss Instance}}
==Remote EJB==
* The caller is a component deployed on an Application Server (JBoss) instance, while the target EJB is deployed on a different Application Server (JBoss) instance. This case qualifies as a [[#deployed_application|remote EJB application]]. Remote invocations are necessary. This is an example that shows how the client component looks up the EJB deployed on a different JBoss instance and invokes remotely:
{{Internal|Session EJB and Servlet on Different JBoss Instances|Session EJB and Servlet on Different JBoss Instances}}
* The caller is a [[#standalone_ejb_client|standalone application]]. Remote invocations are necessary.
{{Internal|Standalone Application Invocation into a Remote Session EJB|Standalone Application Invocation into a Remote Session EJB}}
==Clustered Remote EJB==
* The caller invokes into a cluster of remote EJBs.
==EJB Remote Invocations over REST==
{{Internal|EJB Remote Invocations over REST|EJB Remote Invocations over REST}}
==Invoking into EJBs TODO==
{{Error|<br><center>Desktop/Learning/NOKB TODO/Invoking into EJBs/Invoking into EJBs TODO.docx</center>}}


=EJB Client API=
=EJB Client API=
Line 52: Line 145:


=EJB Client Context=
=EJB Client Context=
The EJB client context is a JBoss-specific mechanism that allows a client application to look up and invoke into a remote EJB.


The EJB client context may be associated with, and used by more than one thread concurrently.
The EJB client context may be associated with, and used by more than one thread concurrently.
Line 66: Line 161:


An EJB receiver is a component that knows how to communicate with a server that is capable of handling EJB invocations.
An EJB receiver is a component that knows how to communicate with a server that is capable of handling EJB invocations.
=Exceptions=
==Application Exception==
An ''application exception'' is an exception defined by the EJB as part of the business logic of the application, to inform the client of abnormal application-level conditions. Applications can typically recover from application exceptions.
To designate a checked exception as an application exception, the developer may declare it in the <tt>throws</tt> clause of the bean's business interface or web service endpoint.
An unchecked exception may be designated an application exception by annotating it with [[@javax.ejb.ApplicationException|@ApplicationException]] or declaring it as <tt>application-exception</tt> in the descriptor.
Application exceptions are handled differently than [[#System_Exception|system exceptions]]  by various internal JEE components, such as transaction interceptors.
If the message listener method of an MDB throws an application exception, the application exception is propagated by the container to the resource adapter.
==Application Exceptions and Transactions==
An application exception does not automatically result in marking the on-going transaction for rollback unless the @ApplicationException annotation is applied to the exception class and is specified with the <tt>rollback</tt> element value true (or the corresponding deployment descriptor element).
==System Exception==
A ''system exception'' is an exception that is a <tt>java.rmi.RemoteException</tt> or one of its subclasses, or a <tt>RuntimeException</tt> that is not an application exception. Other examples of system exceptions are those exception that signal failure to obtain a database connection, JNDI exceptions, JVM errors, etc.
If an EJB method encounters a system-level exception or error that does not allow the method to successfully complete, the method does not have to catch the exception, and it should simply propagate it to the container, by throwing a suitable non-application exception that is compatible with the method’s throws clause.  If there is not matching exception in the signature, the EJB should throw a <tt>javax.ejb.EJBException</tt> that wraps the original exception. Note that <tt>javax.ejb.EJBException</tt> is a subclass of the <tt>java.lang.RuntimeException</tt>, and therefore it does not have to be listed in the throws clauses of the business methods.
In case of an MDB, it should not, in general, throw RuntimeException.
=Concurrency=
<span id="ConcurrentAccessTimeoutException"></span>If a concurrent access timeout occurs on a stateful session or a singleton bean, the container will throw [https://docs.oracle.com/javaee/7/api/javax/ejb/ConcurrentAccessTimeoutException.html javax.ejb.ConcurrentAccessTimeoutException].
<span id="ConcurrentAccessException"></span>If concurrent access is not allowed, and the container detects concurrent access attempt to a stateful session or singleton bean, it will throw [https://docs.oracle.com/javaee/7/api/javax/ejb/ConcurrentAccessException.html javax.ejb.ConcurrentAccessException].
For aspects related to concurrent behavior of various bean types, see:
* [[Singleton_Session_EJB#Concurrency|Singleton Session EJB Concurrency]]
=Singleton Session EJB=
{{Internal|Singleton Session EJB#Concepts|Singleton Session EJB Concepts}}
=Persistence=
{{Internal|JPA Concepts|JPA Concepts}}
=Timer Service=
{{Internal|EJB Timer Service|The EJB Timer Service}}

Latest revision as of 15:09, 28 September 2017

Internal

Local and Remote Interfaces

In EJB, a remote interface is the definition of the bean's contract for functionality that is intended to provided to remote clients. A remote client is a client that runs in a different JVM than the one that executes the target EJB container. The remote interface semantics implies pass-by-value: this allows the method's arguments and results to be serialized, and possibly sent over the network. Hence, the arguments and the result must be Serializable. The remote programming model provides loose coupling between components. The pass-by-value semantics provides isolation between caller and callee and protection against inadvertent modification of data. Remote programming model comes with a performance penalty, because they must assume serialization/deserialization costs, network latency, the overhead of the client and server software stack, etc. This is why it is a good idea to use remote interface model coarse-grained business interaction - multiple calls at a high rate into remote interfaces may not be feasible.

A local interface contains the definition of the functionality available to local clients, which mean clients running in the same JVM, and more than that, clients deployed as part of the same application artifact. Supporting local access to clients deployed as part of a different application deployed in the same JVM is optional, but may be provided if the JEE server implementation decided so; however, applications relying on inter-application local interface access should be seen as non-portable. A local interface implies pass-by-reference semantics, which means the bean will have access to the instances of the objects whose references are passed as argument, and the caller will have access to the instances of the object whose reference is returned as result. EJBs that provide a local client view must be coded to assume that the state of any Java object that is passed as argument and result is potentially shared by caller and callee. Caution should be exercised in determining which object pass across the local view, especially when there is a change in a transactional or security context.

While it is possible to provide both a remote client view and a local client view for an EJB, more typically only one or the other will be provided.

Also see:

EJB and JNDI

Session beans are bound to JNDI according to a portable naming scheme. The most generic format is:

ejb:[/<application-name>]/<module-name>/<distinct-name>/<bean-name>[!<view-class-name>]?stateful

Simplified formats are possible within the context of specific namespaces, as described in the Namespaces section.

JNDI Path Components

application-name

application-name is the name of the EAR application the session bean is deployed as part of. It is an optional component. If the session bean is not deployed as part of an EAR, that part is left blank, and the JNDI name starts with ejb:/<module-name>.... If the session bean deployed as part of an EAR, the part is by default the name of the EAR file, without the .ear suffix. The name can be overridden in the application.xml deployment descriptor by specifying the <application-name> element.

module-name

module-name is the name of the JAR (or WAR) file the session bean is deployed in. It is a mandatory component. By default, is the file name of the JAR without the ".jar" suffix. The module name can be override in ejb-jar.xml by specifying the <module-name> element.

distinct-name

Each deployment may specify an optional distinct name. It is an optional component. If the deployment does not have a distinct name, the corresponding JNDI path element should be left blank.

The JNDI bindings for session bean named 'SimpleStatelessBean' in deployment unit 'deployment "stateless-ejb-example.jar"' are as follows:

bean-name

The simple name of the class implementing the session bean. It is a mandatory component.

view-class-name

The fully qualified class name of the remote interface. It is an optional component.

?stateful

This suffix is required when the JNDI name refers to a stateful session bean.

Namespaces

Upon deployment, the component will be registered in JNDI, in the following contexts: java:global, java:app and java:module, which are accessible only to the current JVM, and also in java:jboss/exported, which is accessible remotely.

For more details on JEE JNDI Namespaces, see

JNDI JEE Namespaces

JNDI Name Examples

EJB deployed in JAR

The following bean has been deployed as part of stateless-ejb-example.jar, it is implemented by io.novaordis.playground.jee.ejb.stateless.SimpleStatelessBean and exposes the io.novaordis.playground.jee.ejb.stateless.SimpleStateless remote interface.

java:global/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:app/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:module/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:jboss/exported/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:global/stateless-ejb-example/SimpleStatelessBean
java:app/stateless-ejb-example/SimpleStatelessBean
java:module/SimpleStatelessBean

The last three names are short forms, and they are registered if the EJB component only exposed one interface.

EJB deployed in EAR

The following bean has been deployed as part of a stateless-ejb-example.jar, which was embedded in stateless-ejb-and-servlet.ear.

java:global/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:app/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:module/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:jboss/exported/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean!io.novaordis.playground.jee.ejb.stateless.SimpleStateless
java:global/stateless-ejb-and-servlet/stateless-ejb-example/SimpleStatelessBean
java:app/stateless-ejb-example/SimpleStatelessBean
java:module/SimpleStatelessBean

The last three names are short forms, and they are registered if the EJB component only exposed one interface.

Remote EJB Applications

An EJB remote application can be one of the following:

  • a standalone Java application
  • another component that runs within a application server instance, and makes invocations into remote EJBs. In this case, each deployed application will have its own EJB client context, and the application's components will share the EJB client context.

Invoking into EJBs

The invocation mechanics is different depending on where the caller and the target EJBs reside relatively to each other. There are several cases:

Collocated Client Component and Target EJB

  • The caller is a component collocated with the target EJB in the same deployment unit (JAR, WAR or EAR).
Servlet and EJB deployed as part of the same WAR, the servlet looks up the EJB in JNDI
Servlet and EJB deployed as part of the same WAR, the servlet gets the EJB reference injected with @EJB
Servlet and EJB deployed as part of the same EAR, in different modules, the servlet looks up the EJB in JNDI
Servlet and EJB deployed as part of the same EAR, in different modules, the servlet gets the EJB reference injected with @EJB
  • The caller is a component deployed as part of a different deployment unit than the target EJB, but both components are deployed on the same Application Server (JBoss) instance. This is an example that shows how the client component looks up the EJB via JNDI and also how can it get it via @EJB injection:
Session EJB and Servlet in Different Deployment Units on Same JBoss Instance

Remote EJB

  • The caller is a component deployed on an Application Server (JBoss) instance, while the target EJB is deployed on a different Application Server (JBoss) instance. This case qualifies as a remote EJB application. Remote invocations are necessary. This is an example that shows how the client component looks up the EJB deployed on a different JBoss instance and invokes remotely:
Session EJB and Servlet on Different JBoss Instances
Standalone Application Invocation into a Remote Session EJB

Clustered Remote EJB

  • The caller invokes into a cluster of remote EJBs.

EJB Remote Invocations over REST

EJB Remote Invocations over REST

Invoking into EJBs TODO



Desktop/Learning/NOKB TODO/Invoking into EJBs/Invoking into EJBs TODO.docx


EJB Client API

JBoss EAP 6 introduced the EJB client API for managing remote EJB invocations. The EJB client API uses the EJB Client Context.

EJB Client Context

The EJB client context is a JBoss-specific mechanism that allows a client application to look up and invoke into a remote EJB.

The EJB client context may be associated with, and used by more than one thread concurrently.

There can potentially be more than one EJB client contexts into a JVM. For deployed applications, each application will have its own EJB client context. Whenever that application invokes another EJB, the corresponding EJB client context is used to find the correct EJB receiver, which then handles the invocation.

For standalone applications, a remote standalone client typically has just one EJB client context backed by any number of EJB receivers

An EJB client context may contain any number of EJB receivers.

The EJB client context is configured with jboss-ejb-client.properties for standalone applications and with jboss-ejb-client.xml for applications deployed within the EAP.

EJB Receiver

An EJB receiver is a component that knows how to communicate with a server that is capable of handling EJB invocations.

Exceptions

Application Exception

An application exception is an exception defined by the EJB as part of the business logic of the application, to inform the client of abnormal application-level conditions. Applications can typically recover from application exceptions.

To designate a checked exception as an application exception, the developer may declare it in the throws clause of the bean's business interface or web service endpoint.

An unchecked exception may be designated an application exception by annotating it with @ApplicationException or declaring it as application-exception in the descriptor.

Application exceptions are handled differently than system exceptions by various internal JEE components, such as transaction interceptors.

If the message listener method of an MDB throws an application exception, the application exception is propagated by the container to the resource adapter.

Application Exceptions and Transactions

An application exception does not automatically result in marking the on-going transaction for rollback unless the @ApplicationException annotation is applied to the exception class and is specified with the rollback element value true (or the corresponding deployment descriptor element).

System Exception

A system exception is an exception that is a java.rmi.RemoteException or one of its subclasses, or a RuntimeException that is not an application exception. Other examples of system exceptions are those exception that signal failure to obtain a database connection, JNDI exceptions, JVM errors, etc.

If an EJB method encounters a system-level exception or error that does not allow the method to successfully complete, the method does not have to catch the exception, and it should simply propagate it to the container, by throwing a suitable non-application exception that is compatible with the method’s throws clause. If there is not matching exception in the signature, the EJB should throw a javax.ejb.EJBException that wraps the original exception. Note that javax.ejb.EJBException is a subclass of the java.lang.RuntimeException, and therefore it does not have to be listed in the throws clauses of the business methods.

In case of an MDB, it should not, in general, throw RuntimeException.

Concurrency

If a concurrent access timeout occurs on a stateful session or a singleton bean, the container will throw javax.ejb.ConcurrentAccessTimeoutException.

If concurrent access is not allowed, and the container detects concurrent access attempt to a stateful session or singleton bean, it will throw javax.ejb.ConcurrentAccessException.

For aspects related to concurrent behavior of various bean types, see:

Singleton Session EJB

Singleton Session EJB Concepts

Persistence

JPA Concepts

Timer Service

The EJB Timer Service