[[ejb-component]]
== EJB Component

*Available as of Camel version 2.4*

The *ejb:* component binds EJBs to Camel message exchanges.

Maven users will need to add the following dependency to their `pom.xml`
for this component:

[source,xml]
------------------------------------------------------------
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-ejb</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
------------------------------------------------------------

### URI format

[source,java]
---------------------
ejb:ejbName[?options]
---------------------

Where *ejbName* can be any string which is used to look up the EJB in
the Application Server JNDI Registry

### Options



// component options: START
The EJB component supports 4 options, which are listed below.



[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *context* (producer) | The Context to use for looking up the EJBs |  | Context
| *properties* (producer) | Properties for creating javax.naming.Context if a context has not been configured. |  | Properties
| *cache* (advanced) | If enabled, Camel will cache the result of the first Registry look-up. Cache can be enabled if the bean in the Registry is defined as a singleton scope. |  | Boolean
| *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
|===
// component options: END




// endpoint options: START
The EJB endpoint is configured using URI syntax:

----
ejb:beanName
----

with the following path and query parameters:

==== Path Parameters (1 parameters):


[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *beanName* | *Required* Sets the name of the bean to invoke |  | String
|===


==== Query Parameters (4 parameters):


[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
| *method* (producer) | Sets the name of the method to invoke on the bean |  | String
| *cache* (advanced) | If enabled, Camel will cache the result of the first Registry look-up. Cache can be enabled if the bean in the Registry is defined as a singleton scope. |  | Boolean
| *parameters* (advanced) | Used for configuring additional properties on the bean |  | Map
| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
|===
// endpoint options: END


### Bean Binding

How bean methods to be invoked are chosen (if they are not specified
explicitly through the *method* parameter) and how parameter values are
constructed from the Message are all defined by the
Bean Binding mechanism which is used throughout
all of the various Bean Integration
mechanisms in Camel.

### Examples

In the following examples we use the Greater EJB which is defined as
follows:

*GreaterLocal.java*

[source,java]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
public interface GreaterLocal {
 
    String hello(String name);
 
    String bye(String name);
 
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------

And the implementation

*GreaterImpl.java*

[source,java]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
@Stateless
public class GreaterImpl implements GreaterLocal {
 
    public String hello(String name) {
        return "Hello " + name;
    }
 
    public String bye(String name) {
        return "Bye " + name;
    }
 
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------

#### Using Java DSL

In this example we want to invoke the `hello` method on the EJB. Since
this example is based on an unit test using Apache OpenEJB we have to
set a `JndiContext` on the <<ejb-component,EJB>> component with the OpenEJB
settings.

[source,java]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
@Override
protected CamelContext createCamelContext() throws Exception {
    CamelContext answer = new DefaultCamelContext();
 
    // enlist EJB component using the JndiContext
    EjbComponent ejb = answer.getComponent("ejb", EjbComponent.class);
    ejb.setContext(createEjbContext());
 
    return answer;
}
 
private static Context createEjbContext() throws NamingException {
    // here we need to define our context factory to use OpenEJB for our testing
    Properties properties = new Properties();
    properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
 
    return new InitialContext(properties);
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Then we are ready to use the EJB in the Camel route:

[source,java]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
from("direct:start")
    // invoke the greeter EJB using the local interface and invoke the hello method
    .to("ejb:GreaterImplLocal?method=hello")
    .to("mock:result");
-------------------------------------------------------------------------------------------------------------------------------------------------------------

*In a real application server*

In a real application server you most likely do not have to setup a
`JndiContext` on the <<ejb-component,EJB>> component as it will create a
default `JndiContext` on the same JVM as the application server, which
usually allows it to access the JNDI registry and lookup the
<<ejb-component,EJB>>s. However if you need to access a application server on a remote JVM or
the likes, you have to prepare the properties beforehand.

#### Using Spring XML

And this is the same example using Spring XML instead:

Again since this is based on an unit test we need to setup the
<<ejb-component,EJB>> component:

[source,XML]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
<!-- setup Camel EJB component -->
<bean id="ejb" class="org.apache.camel.component.ejb.EjbComponent">
    <property name="properties" ref="jndiProperties"/>
</bean>
 
<!-- use OpenEJB context factory -->
<p:properties id="jndiProperties">
    <prop key="java.naming.factory.initial">org.apache.openejb.client.LocalInitialContextFactory</prop>
</p:properties>
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Before we are ready to use <<ejb-component,EJB>> in the Camel routes:

[source,XML]
-------------------------------------------------------------------------------------------------------------------------------------------------------------
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:start"/>
        <to uri="ejb:GreaterImplLocal?method=hello"/>
        <to uri="mock:result"/>
    </route>
</camelContext>
-------------------------------------------------------------------------------------------------------------------------------------------------------------

### See Also

* Configuring Camel
* Component
* Endpoint
* Getting Started
* <<bean-component,Bean>>
* Bean Binding
* Bean Integration
