= Container Control Module

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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.

== Overview
The Container Control module provides CDI container booting and shutdown, crucial for CDI use in Java SE6+ environments, and associated context lifecycle management. The module abstracts individual CDI container implementations, ensuring projects are container-independent.

== Project Setup
The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <<configure#, Configure DeltaSpike in Your Projects>>. For Maven-independent projects, see <<configure#config-maven-indep,Configure DeltaSpike in Maven-independent Projects>>.

=== Enable CDI For Your Java Environment
This module requires a CDI implementation to be available in the Java environment where your projects are deployed. Dependent on the Java environment you choose, some setup may be necessary as detailed at the <<cdiimp#,Enable CDI For Your Java Environment>> page.

=== Declare Container Control Module Dependencies
Add the Container Control module to the list of dependencies in the project `pom.xml` file using this code snippet:

[source,xml]
----
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-api</artifactId>
    <version>${deltaspike.version}</version>
    <scope>compile</scope>
</dependency>
----

Or if you're using Gradle, add these dependencies to your `build.gradle`:

[source]
----
     compile 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api'
----

== Start the CDI Container from Your Project
To start a CDI container in your application, you must instantiate a `CdiContainer` object and call the `#boot` method. When `#boot` is called, the `CdiContainer` scans CDI-enabled
archives for beans and CDI extensions. Before the application exits, `#shutdown` must be called to correctly destroy all beans. An example is given in the code snippet here.

[source,java]
----
import org.apache.deltaspike.cdise.api.CdiContainer;
import org.apache.deltaspike.cdise.api.CdiContainerLoader;

public class MainApp {
    public static void main(String[] args) {

        CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
        cdiContainer.boot();

        // You can use CDI here

        cdiContainer.shutdown();
    }
}
----

Starting the container does not automatically start all CDI Contexts. Contexts must be started independently using the provided `ContextControl` class. An example of starting the Context for `@ApplicationScoped` beans is added to the code snippet here.

[source,java]
----
import org.apache.deltaspike.cdise.api.CdiContainer;
import org.apache.deltaspike.cdise.api.CdiContainerLoader;
import org.apache.deltaspike.cdise.api.ContextControl;
import javax.enterprise.context.ApplicationScoped;

public class MainApp {
    public static void main(String[] args) {

        CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
        cdiContainer.boot();

        // Starting the application-context enables use of @ApplicationScoped beans
        ContextControl contextControl = cdiContainer.getContextControl();
        contextControl.startContext(ApplicationScoped.class);

        // You can use CDI here

        cdiContainer.shutdown();
    }
}
----

To resolve project beans, you can use the DeltaSpike `BeanProvider` class. Whether `EchoService` is a concrete implementation or just an interface depends on the application. In the case that it is an interface, the corresponding implementation is resolved. The resolved bean is a standard CDI bean and it can be used for all CDI concepts, such as `@Inject`, in the class without further uses of `BeanProvider`. An example of resolving the bean without qualifiers is given in the code snippet here.

[source,java]
----
EchoService echoService = BeanProvider.getContextualReference(EchoService.class, false);
----

== CdiContainer
The `CdiContainer` interface provides booting and shutdown of the CDI containers from deployed applications, with `CdiContainerLoader` a simple factory providing access to the underlying `CdiContainer` implementation.

This is useful to Java SE6+ applications in which a standalone CDI implementation must be provided and booted and shutdown by the application. Booting and shutdown of the CDI container for Java EE and servlet containers is managed by the servlet container integration.

For instructions and examples on using this feature in your projects, see <<cdiimp#javase6,Enable CDI For Your Java Environment: Java SE6+>>.

== ContextControl Usage
The `ContextControl` interface provides life-cycle control of the CDI container built-in contexts. This includes starting and stoping built-in standard contexts like `@RequestScoped`, `@ConversationScoped`, and `@SessionScoped`. It is provided as an `@Dependent` bean and can be injected in the classic CDI way. This feature can be used and is helpful in all Java environments, including Java SE, as illustrated here.

== Procedure for building an uber jar
Uber jar or executable jar can created by using the maven shade plugin. Some things you needs to be aware of when you use it.

* Multiple `beans.xml` and `javax.enterprise.inject.spi.Extension` files needs to be merged into the final jar using a transformer.
[source,xml]
----
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
----
* The _asm:asm:3.3.1_ transitive dependency of OpenWebBeans isn't properly included in the Uber jar.  Add it as a project dependency if you use OWB. (Only needed for OWB 1.1.8 !)
* Some frameworks, like logging frameworks, aren't CDI compatible.  So you need to exclude them from scanning. Use for example the `scan` feature of Weld to define which packages needs to be excluded.

=== Restart the RequestContext in Unit Tests
In unit testing it can be necessary to test with attached and also with
detached JPA entities. A very common approach for JPA is the
http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Server/1.0/html/Hibernate_Entity_Manager_Reference_Guide/transactions.html[entitymanager-per-request
approach] and thus have a producer method which creates a @RequestScoped
EntityManager. Since a single unit test is usually treated as one
‘request’ a problem arises detaching entities.

.Using ContextControl to Detach Entities
[source,java]
---------------------------------------------------------------------------------------
@Test
public void testMyBusinessLogic()
{
    doSomeJpaStuff()
    MyEntity me = em.find(...);

    ContextControl ctxCtrl = BeanProvider.getContextualReference(ContextControl.class);

    //stop the RequestContext to dispose of the @RequestScoped EntityManager
    ctxCtrl.stopContext(RequestScoped.class);

    //immediately restart the context again
    ctxCtrl.startContext(RequestScoped.class);

    //the entity 'em' is now in a detached state!
    doSomeStuffWithTheDetachedEntity(em);
}
---------------------------------------------------------------------------------------

=== Attach a RequestContext to a New Thread in EE
Accessing the `@RequestScoped` bean in a new thread will result in a
`ContextNotActiveException`. The RequestContext usually gets started
for a particular thread via a simple `ServletRequestListener`. So "no
servlet-request" means that there is no Servlet-Context for the current
(/new) Thread. You might face such issues, if you would like to reuse
business services in for example a Quartz Job.

.Using ContextControl to Control the RequestContext for a Quartz-Job
[source,java]
---------------------------------------------------------------------------------------------
public class CdiJob implements org.quartz.Job
{
    public void execute(JobExecutionContext context) throws JobExecutionException
    {
        ContextControl ctxCtrl = BeanProvider.getContextualReference(ContextControl.class);

        //this will implicitly bind a new RequestContext to the current thread
        ctxCtrl.startContext(RequestScoped.class);

        try
        {
            doYourWork();
        }
        finally
        {
            //stop the RequestContext to ensure that all request-scoped beans get cleaned up.
            ctxCtrl.stopContext(RequestScoped.class);
        }
    }
}
---------------------------------------------------------------------------------------------

== Embedded Servlet Support
From DeltaSpike 1.0.2, you can use DeltaSpike to power embedded Servlet
runtimes. This work is done via Servlet Listeners. The configuration is
specific to each container, below are some examples.

The two main listeners are `CdiServletRequestListener` and
`CdiServletContextListener`. `CdiServletRequestListener` is responsible
for starting a `RequestContext` on each incoming request. In most
containers this is all you need. For Tomcat specifically, you need to
use `CdiServletContextListener` which registers the
`CdiServletRequestListener`.

The main use case for this feature is for lightweight embedded runtimes,
microservices. For each of these, it is assumed that you are using the
following start up code somewhere:

[source,java]
-----------------------------------------------------------------
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
cdiContainer.getContextControl().startContexts();
-----------------------------------------------------------------

=== Jetty

For Jetty, you need to add an `EventListener` which will be your
`CdiServletRequestListener`. The object must be instantiated. This must
be done before the server is started.

[source,java]
------------------------------------------------------------------------------------------
Server server = new Server(port);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);

context.addEventListener(new CdiServletRequestListener());
context.addServlet(new ServletHolder(new YourServlet()),"/*");

server.start();
------------------------------------------------------------------------------------------

=== Undertow

For Undertow, you register the `CdiServletRequestListener` via
`ListenerInfo` by passing in the class to their builders. Then you add
the `ListenerInfo` to your deployment before starting.

[source,java]
--------------------------------------------------------------------------------------------------------
ServletInfo servletInfo = Servlets.servlet("YourServletName", YourServlet.class).setAsyncSupported(true)
    .setLoadOnStartup(1).addMapping("/*");
ListenerInfo listenerInfo = Servlets.listener(CdiServletRequestListener.class);
DeploymentInfo di = new DeploymentInfo()
        .addListener(listenerInfo)
        .setContextPath("/")
        .addServlet(servletInfo).setDeploymentName("CdiSEServlet")
        .setClassLoader(ClassLoader.getSystemClassLoader());
DeploymentManager deploymentManager = Servlets.defaultContainer().addDeployment(di);
deploymentManager.deploy();
Undertow server = Undertow.builder()
        .addHttpListener(port, "localhost")
        .setHandler(deploymentManager.start())
        .build();
server.start();
--------------------------------------------------------------------------------------------------------

=== Tomcat

For Tomcat, you need to register the `CdiServletContextListener` instead
of the `CdiServletRequestListener`. It is added as an
`ApplicationListener` by passing in the class name as a `String`.

[source,java]
-----------------------------------------------------------------------------------
Tomcat tomcat = new Tomcat();
tomcat.setPort(port);
File base = new File("...");
Context ctx = tomcat.addContext("/",base.getAbsolutePath());
StandardContext standardContext = (StandardContext)ctx;
standardContext.addApplicationListener(CdiServletContextListener.class.getName());
Wrapper wrapper = Tomcat.addServlet(ctx,"YourServlet",YourServlet.class.getName());
wrapper.addMapping("/*");
tomcat.start();
-----------------------------------------------------------------------------------
