//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

==== EJB

This section describes how to add support of EJB in Apache Karaf. It doesn't describe how to develop EJB applications.

===== Apache OpenEJB

Apache Karaf doesn't provide "native" support of EJB (Enterprise Java Beans).

Apache OpenEJB provides EJB support for Apache Karaf by providing a set of features.

You have to update some Karaf configuration to have full OpenEJB support.

First, in the `etc/system.properties`, you have to append the following properties:

----
...
#
# OpenEJB scanner
#
openejb.deployments.classpath.exclude=bundle:*
openejb.deployments.classpath.filter.descriptors=true
----

Due to some OpenEJB version constraint, you also have to update the `etc/jre.properties` by changing the version of
the `javax.xml.namespace` package, and remove the version of the `javax.annotation` package (provided by Geronimo
Annotation API spec bundle, used by OpenEJB):

----
...
javax.annotation, \
javax.annotation.processing, \
...
javax.xml.namespace;version="1.0.0", \
...
----

It enables the OpenEJB bundles scanning, looking for EJBs.

After starting/restart Karaf to take these changes, we can install the OpenEJB feature:

----
karaf@root()> feature:repo-add openejb
----

By default, the `feature:repo-add openejb` command will install the latest OpenEJB version available.

You can specify a target version using the `version` argument:

----
karaf@root()> feature:repo-add openejb 4.5.2
----

Now, you have a set of new OpenEJB features available in your Apache Karaf container:

----
karaf@root()> la
...
openejb-core                  | 4.5.2 |           | openejb-features          |
openejb-server                | 4.5.2 |           | openejb-features          |
openejb-cxf                   | 4.5.2 |           | openejb-features          |
openejb-rest                  | 4.5.2 |           | openejb-features          |
openejb-soap                  | 4.5.2 |           | openejb-features          |
----

You can add EJB support installing the `openejb-core` feature:

----
karaf@root()> feature:install openejb-core
----

===== Apache KarafEE

A custom distribution of Apache Karaf embedding OpenEJB is available in the Apache TomEE project.

The name of this custom distribution is KarafEE: https://svn.apache.org/repos/asf/tomee/karafee/

However, this project is now "deprecated", and all resources from KarafEE will move directly in Apache Karaf soon.