[[EJB3]]
= EJB3 subsystem configuration guide

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

This page lists the options that are available for configuring the EJB
subsystem.

A complete example of the config is shown below, with a full explanation
of each

[source,xml,options="nowrap"]
----
<subsystem xmlns="urn:jboss:domain:ejb3:10.0">
  <session-bean>
    <stateless>
      <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
    </stateless>
    <stateful default-session-timeout="600000" default-access-timeout="5000" cache-ref="distributable" passivation-disabled-cache-ref="simple"/>
    <singleton default-access-timeout="5000"/>
  </session-bean>
  <mdb>
    <resource-adapter-ref resource-adapter-name="hornetq-ra"/>
    <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
  </mdb>
  <entity-bean>
    <bean-instance-pool-ref pool-name="entity-strict-max-pool"/>
  </entity-bean>
    <pools>
    <bean-instance-pools>
      <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
      <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
      <strict-max-pool name="entity-strict-max-pool" max-pool-size="100" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
    </bean-instance-pools>
  </pools>
  <caches>
    <simple-cache name="simple"/>
    <distributable-cache name="distributable" bean-management="default"/>
  </caches>
  <async thread-pool-name="default"/>
  <timer-service thread-pool-name="default" default-data-store="default-file-store">
    <data-stores>
      <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
    </data-stores>
  </timer-service>
  <remote connectors="remoting-connector" thread-pool-name="default">
    <profiles>
        <profile name="profile" exclude-local-receiver="false" local-receiver-pass-by-value="false">
          <remoting-ejb-receiver name="receiver" outbound-connection-ref="remote-ejb-connection"/>
          <remote-http-connection name="connection" uri="http://localhost:8180/wildfly-services"/>
          <static-ejb-discovery>
            <module uri="http://localhost:8180/wildfly-services" module-name="foo" app-name="bar" distinct-name="baz"/>
          </static-ejb-discovery>
        </profile>
    </profiles>
  </remote>
  <thread-pools>
    <thread-pool name="default">
      <max-threads count="10"/>
      <core-threads count="10"/>
      <keepalive-time time="60" unit="seconds"/>
    </thread-pool>
  </thread-pools>
  <iiop enable-by-default="false" use-qualified-name="false"/>
  <in-vm-remote-interface-invocation pass-by-value="false"/> <!-- Warning see notes below about possible issues -->
</subsystem>
----

[[session-bean]]
== <session-bean>

[[stateless]]
=== <stateless>

This element is used to configure the instance pool that is used by
default for stateless session beans. If it is not present stateless
session beans are not pooled, but are instead created on demand for
every invocation. The instance pool can be overridden on a per
deployment or per bean level using `jboss-ejb3.xml` or the
`org.jboss.ejb3.annotation.Pool` annotation. The instance pools
themselves are configured in the `<pools>` element.

[[stateful]]
=== <stateful>

This element is used to configure Stateful Session Beans.

* `default-session-timeout` This optional attribute specifies the default
amount of time in milliseconds a stateful session bean can remain idle
before it is eligible for removal by the container.
It can be overridden via `ejb-jar.xml` deployment descriptor or via
`jakarta.ejb.StatefulTimeout` annotation.

* `default-access-timeout` This attribute specifies the default time
concurrent invocations on the same bean instance will wait to acquire
the instance lock. It can be overridden via the deployment descriptor or
via the `jakarta.ejb.AccessTimeout` annotation.

* `cache-ref` This attribute is used to set the default cache for
beans which require a passivating cache. It can be overridden by `jboss-ejb3.xml`, or via
the `org.jboss.ejb3.annotation.Cache` annotation.

* `non-passivating-cache-ref` This attribute is used to set the default cache
for beans which require a non-passivating cache.

[[singleton]]
=== <singleton>

This element is used to configure Singleton Session Beans.

* `default-access-timeout` This attribute specifies the default time
concurrent invocations will wait to acquire the instance lock. It can be
overridden via the deployment descriptor or via the
`jakarta.ejb.AccessTimeout` annotation.

[[mdb]]
== <mdb>

[[resource-adaptor-ref]]
=== <resource-adaptor-ref>

This element sets the default resource adaptor for Message Driven Beans.

[[bean-instance-pool-ref]]
=== <bean-instance-pool-ref>

This element is used to configure the instance pool that is used by
default for Message Driven Beans. If it is not present they are not
pooled, but are instead created on demand for every invocation. The
instance pool can be overridden on a per deployment or per bean level
using `jboss-ejb3.xml` or the `org.jboss.ejb3.annotation.Pool`
annotation. The instance pools themselves are configured in the
`<pools>` element.

[[entity-bean]]
== <entity-bean>

This element is used to configure the behavior for EJB2 EntityBeans.

[[bean-instance-pool-ref-1]]
=== <bean-instance-pool-ref>

This element is used to configure the instance pool that is used by
default for Entity Beans. If it is not present they are not pooled, but
are instead created on demand for every invocation. The instance pool
can be overridden on a per deployment or per bean level using
`jboss-ejb3.xml` or the `org.jboss.ejb3.annotation.Pool` annotation. The
instance pools themselves are configured in the `<pools>` element.

[[pools]]
== <pools>

[[bean-instance-pools]]
=== <bean-instance-pools>

This element is used to configure pools used by stateless session, message driven beans and entity beans.

[[strict-max-pool]]
==== <strict-max-pool>

Each pool is configured using `strict-max-pool` element.

* `name` Name of the pool.
* `max-pool-size` Configured maximum number of bean instances that the pool can hold at a given point in time.
* `instance-acquisition-timeout` The maximum amount of time to wait for a bean instance to be available from the pool.
* `instance-acquisition-timeout-unit` The instance acquisition timeout unit

[[caches]]
== <caches>

This element is used to define named cache factories to support the persistence of SFSB session states.
Cache factories may be passivating (an in-memory cache with the ability to passivate to persistant store
the session states of beans not recently used and then activate them when needed) or non-passivating
(an in-memory cache only). Default values for passivating and non-passivating caches are specified
in the <stateful> element mentioned above. A SFSB may override the named cache used to store its session states
via the @Cache annotation (in its class definition) or via a corresponding deployment descriptor.

[[simple-cache]]
=== <simple-cache>

This element defines a non-passivating (in-memory only) cache factory for storing session states of a SFSB.

[[distributable-cache]]
=== <distributable-cache>

This element defines a passivating cache factory (in-memory plus passivation to persistent store) for storing
session states of a SFSB. A passivating cache factory relies on a bean-management provider to configure
the passivation mechanism and the persistent store that it uses.

* `bean-management` This attribute specifies the bean-management provider to be used to
support passivation of cache entries. The bean-management provider is defined and configured
in the distributable-ejb subsystem (see the link:High_Availability_Guide{outfilesuffix}[High Availability Guide]).
If the attribute is non-defined, the default bean management provider
defined in the distributable-ejb subsystem is used.

[[async]]
== <async>

This element enables async EJB invocations. It is also used to specify
the thread pool that these invocations will use.

[[timer-service]]
== <timer-service>

This element enables the EJB timer service. It is also used to specify
the thread pool that these invocations will use.

[[data-store]]
=== <data-store>

This is used to configure the directory that persistent timer
information is saved to.

[[remote]]
== <remote>

This element is used to enable remote EJB invocations. In other words, it allows a remote EJB client
application to make invocations on Jakarta Enterprise beans deployed on the server.

It specifies the following attributes:

* `connectors` specifies a space-separated list of remoting connectors to use (as defined in the remoting
subsystem configuration) for accepting invocations.

* `thread-pool` specifies a thread pool to use for processing incoming remote invocations

[[profile]]
=== <profile>

A remote profile specifies a configuration of remote invocations that can
be referenced by many deployments. EJBs that are meant to be invoked can
be discovered in either a static or a dynamic way.

Static discovery decides which remote node to connect to based on the information
provided by the administrator.

Dynamic discovery is responsible for monitoring the available EJBs on all the
nodes to which connections are configured and decides which remote node to
connect to based on the gathered data.

* `name` the name of the profile
* `exclude-local-receiver` If set, no local receiver is used in this profile
* `local-receiver-pass-by-value` If set, local receiver will pass ejb beans by value

[[static-ejb-discovery]]
==== <static-ejb-discovery>

Static ejb discovery allows the administrator to explicitly specify on which remote nodes
given EJBs are located. The `module` tag is used to define it:

* `module-name` the name of EJB module
* `app-name` the name of EJB app
* `distinct-name` the distinct name EJB
* `uri` the address on which given EJB is located

[[remoting-ejb-receiver]]
==== <remoting-ejb-receiver>

The `remoting-ejb-receiver` tag is used to define dynamic discovery based on
the remoting protocol:

* `name` name of the remote connection
* `outbound-connection-ref` reference to outbound connection defined in
the remoting subsystem
* `connection-timeout` the timeout of the connection

[[remote-http-connection]]
==== <remote-http-connection>

The `remote-http-connection` tag is used to define dynamic discovery based on
HTTP protocol:

* `name` name of the HTTP connection
* `uri` URI of the connection

[[thread-pools]]
== <thread-pools>

This is used to configure the thread pools used by async, timer and
remote invocations.

* `max-threads` specifies the maximum number of threads in the thread pool.
It is a required attribute and defaults to `10`.

* `core-threads` specifies the number of core threads in the thread pool.
It is an optional attribute and defaults to `max-threads` value.

* `keepalive-time` specifies the amount of time that non-core threads can
stay idle before they become eligible for removal. It is an optional
attribute and defaults to `60` seconds.

[[iiop]]
== <iiop>

This is used to enable IIOP (i.e. CORBA) invocation of EJB's. If this
element is present then the JacORB subsystem must also be installed. It
supports the following two attributes:

* `enable-by-default` If this is true then all EJB's with EJB2.x home
interfaces are exposed via IIOP, otherwise they must be explicitly
enabled via `jboss-ejb3.xml`.

* `use-qualified-name` If this is true then EJB's are bound to the corba
naming context with a binding name that contains the application and
modules name of the deployment (e.g. myear/myejbjar/MyBean), if this is
false the default binding name is simply the bean name.

[[in-vm-remote-interface-invocation]]
== <in-vm-remote-interface-invocation>

By default remote interface invocations use pass by value, as required
by the EJB spec. This element can use used to enable pass by reference,
which can give you a performance boost. Note WildFly will do a shallow
check to see if the caller and the EJB have access to the same class
definitions, which means if you are passing something such as a
List<MyObject>, WildFly only checks the List to see if it is the same
class definition on the call & EJB side. If the top level class
definition is the same, JBoss will make the call using pass by
reference, which means that if MyObject or any objects beneath it are
loaded from different classloaders, you would get a ClassCastException.
If the top level class definitions are loaded from different
classloaders, JBoss will use pass by value. JBoss cannot do a deep check
of all of the classes to ensure no ClassCastExceptions will occur
because doing a deep check would eliminate any performance boost you
would have received by using call by reference. It is recommended that
you configure pass by reference only on callers that you are sure will
use the same class definitions and not globally. This can be done via a
configuration in the jboss-ejb-client.xml as shown below.

To configure a caller/client use pass by reference, you configure your
top level deployment with a META-INF/jboss-ejb-client.xml containing:

[source,xml,options="nowrap"]
----
<jboss-ejb-client xmlns="urn:jboss:ejb-client:1.0">
    <client-context>
        <ejb-receivers local-receiver-pass-by-value="false"/>
    </client-context>
</jboss-ejb-client>
----

[[server-interceptors]]
== <server-interceptors>

This element configures a number of server-side interceptors which can be
configured without changing the deployments.

Each interceptor is configured in _<interceptor>_ tag which contains the
following fields:

* `module` - the module in which the interceptor is defined
* `class` - the class which implements the interceptor

In order to use server interceptors you have to create a module that implements
them and place it into _${WILDFLY_HOME}/modules_ directory.

Interceptor implementations are POJO classes which use
_jakarta.interceptor.AroundInvoke_ and _jakarta.interceptor.AroundTimeout_ to
mark interceptor methods.

Sample configuration:

[source,xml,options="nowrap"]
----
<server-interceptors>
	<interceptor module="org.foo:FooInterceptor:1.0" class="org.foo.FooInterceptor"/>
</server-interceptors>
----

Sample interceptor implementation:
[source,java,options="nowrap"]
----
package org.foo;

import jakarta.annotation.PostConstruct;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.InvocationContext;

public class FooInterceptor {

    @AroundInvoke
    public Object bar(final InvocationContext invocationContext) throws Exception {
        return invocationContext.proceed();
    }
}
----

[[client-interceptors]]
== <client-interceptors>

This element configures a number of client-side interceptors which can be
configured without changing the deployments.

Each interceptor is configured in _<interceptor>_ tag which contains the
following fields:

* `module` - the module in which the interceptor is defined
* `class` - the class which implements the interceptor

In order to use server interceptors you have to create a module that implements
them and place it into _${WILDFLY_HOME}/modules_ directory.

Interceptor implementations must implement _org.jboss.ejb.client.EJBClientInterceptor_
interface.

Sample configuration:

[source,xml,options="nowrap"]
----
<client-interceptors>
	<interceptor module="org.foo:FooInterceptor:1.0" class="org.foo.FooInterceptor"/>
</client-interceptors>
----

Sample interceptor implementation:
[source,java,options="nowrap"]
----
package org.foo;

import org.jboss.ejb.client.EJBClientInterceptor;
import org.jboss.ejb.client.EJBClientInvocationContext;

public class FooInterceptor implements EJBClientInterceptor {

    @Override
    public void handleInvocation(EJBClientInvocationContext context) throws Exception {
        context.sendRequest();
    }

    @Override
    public Object handleInvocationResult(EJBClientInvocationContext context) throws Exception {
        return context.getResult();
    }
}
----

NOTE: References in this document to Enterprise JavaBeans (EJB) refer to the Jakarta Enterprise Beans unless otherwise noted.
