deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Karl Kildén (JIRA) <j...@apache.org>
Subject [jira] [Commented] (DELTASPIKE-156) documentation for ContainerControl API
Date Fri, 19 Oct 2012 22:10:12 GMT

    [ https://issues.apache.org/jira/browse/DELTASPIKE-156?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13480439#comment-13480439
] 

Karl Kildén commented on DELTASPIKE-156:
----------------------------------------

h1. CdiControl Module

As the name implies this module allows you to switch off the contextual auto pilot and grab
the steering wheels.

This module is quite beneficial for SE modules that otherwise would have to go knees deep
in the implementation code of the container leading to a complicated yet not portable solution.
CdiControl definitely has its uses for Java EE as well. Maybe most notably Providing the ability
to start a Request Context in a new thread in order to give it access to contextual instances.
It's also worth mentioning that is has several useful functions for unit testing.

{note:title=Regarding Weld EE support}
Currently Weld support is limited to SE. [Deltaspike-284#https://issues.apache.org/jira/browse/DELTASPIKE-284?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13480263#comment-13480263]
{note}

h2. Maven Artifacts
{code:xml|title=CdiControl module api dependency}
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-api</artifactId>
    <version>${deltaspike.version}</version>
    <scope>runtime</scope>
</dependency>
{code}

Use one implementation dependency from below: 

{code:xml|title=CdiControl module impl-OpenWebBean dependency }
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-owb</artifactId>
    <version>${deltaspike.version}</version>
    <scope>runtime</scope>
</dependency>
{code}


{code:xml|title=CdiControl module impl-Weld dependency }
<dependency>
    <groupId>org.apache.deltaspike.cdictrl</groupId>
    <artifactId>deltaspike-cdictrl-weld</artifactId>
    <version>${deltaspike.version}</version>
    <scope>runtime</scope>
</dependency>
{code}

h2. Usage

There are basically two parts
The *CdiContainer* Interface will provide you with a way to boot and shutdown the CDI Container
in SE applications.
The *ContextControl* interface provides a way to control the life cycle of the built-in Contexts
of the CDI container.

h2. CdiContainer

You can use the CdiContainerLoader as a simple factory to gain access to the underlying CdiContainer
implementation.

{code:java|title=a CDI container for a unit test or in a Java SE application}
// this will give you a CdiContainer for Weld or OWB, depending on the jar you added
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();

// now we gonna boot the CDI container. This will trigger the classpath scan, etc
cdiContainer.boot();

// and finally we like to start all built-in contexts
cdiContainer.getContextControl().startContexts();

// now we can use CDI in our SE application.
// And there is not a single line of OWB or Weld specific code in your project!

// finally we gonna stop the container
cdiContainer.shutdown();
{code}

Those two classes are of no interest for Java EE applications since the CDI Container already
gets properly booted and shut down by the Servlet container integration.

h2. ContextControl usage

The ContextControl interface allows you to start and stop built-in standard Contexts like
@RequestScoped, @ConversationScoped, @SessionScoped, etc. It is provided as @Dependent bean
and can get injected in the classic CDI way. This is not only usable in Java SE projects but
also very helpful in Servlets and Java EE containers!
The following samples should give you an idea about the power of this tool:

*Restarting the RequestContext in a unit test*

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 [entitymanager-per-request approach#http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Server/1.0/html/Hibernate_Entity_Manager_Reference_Guide/transactions.html]
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. With
the ContextControl this is no problem anymore as the following code fragment shows:

{code:java|title=Using ContextControl the detach entities}
@Test
public void testMyBusinessLogic() {
  doSomeJpaStuff()
  MyEntity me = em.find(...);

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

  // stoping the request context will dispose the @RequestScoped EntityManager
  ctxCtrl.stopContext(RequestScoped.class);

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

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

h2. Attaching a Request Context to a new thread in EE

Everyone who tried to access @RequestScoped CDI beans in a new Thread created in a Servlet
or any other Java EE related environment has for sure experienced the same pain: accessing
the @RequestScoped bean will result in a ContextNotActiveException. But how comes? Well, the
Request Context usually gets started for a particular thread via a simple ServletRequestListener.
The problem is obvious: no servlet-request means that there is no Servlet Context for the
Thread\! While the normal CDI container controlled behavior is almost always desirable there's
definitely cases when having no control over the Request Context is clearly a negative. For
example if you like to reuse your nice business services in e.g. a Quartz Job. And again as
the name implies ContextControl can help you in those situations as well:

{code:java|title=Contextual thread with ContextControl}
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 your current thread
    ctxCtrl.startContext(RequestScoped.class);

    doYourWork();

    // at the end of the Job, we gonna stop the RequestContext
    // to ensure that all beans get properly cleaned up.
    ctxCtrl.stopContext(RequestScoped.class);
  }
}
{code}

Other cases could be support for legacy code using threads, portlets and plenty of other situations.
                
> documentation for ContainerControl API
> --------------------------------------
>
>                 Key: DELTASPIKE-156
>                 URL: https://issues.apache.org/jira/browse/DELTASPIKE-156
>             Project: DeltaSpike
>          Issue Type: Sub-task
>          Components: CdiControl, Documentation
>    Affects Versions: 0.2-incubating
>            Reporter: Gerhard Petracek
>            Assignee: Mark Struberg
>             Fix For: 0.4-incubating
>
>         Attachments: cdiContro.patch
>
>
> the wiki is outdated

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Mime
View raw message