<?xml version="1.0" encoding="UTF-8"?>
<chapter id="sid-19398999">
   <title>Errai CDI</title>
   <para>CDI (Contexts and Dependency Injection) is the Jave EE standard (JSR-299) for handling dependency injection. In addition to dependency injection, the standard encompasses component lifecycle, application configuration, call-interception and a decoupled, type-safe eventing specification.</para>
   <para>The Errai CDI extension implements a subset of the specification for use inside of client-side applications within Errai, as well as additional capabilities such as distributed eventing.</para>
   <para>Errai CDI does not currently implement all life cycles specified in JSR-299 or interceptors. These deficiencies may be addressed in future versions.</para>
   <important>
      <para>
        The Errai CDI extension itself is implemented on top of the Errai IOC Framework (see
        <xref linkend="sid-5931402"/>
        ), which itself implements the JSR-330 specification. Inclusion of the CDI module your GWT project will result in the extensions automatically being loaded and made available to your application.
      </para>
   </important>
   <section id="sid-5931498">
      <title>Features and Limitations</title>
      <para>Beans that are deployed to a CDI container will automatically be registered with Errai and exposed to your GWT client application. So, you can use Errai to communicate between your GWT client components and your CDI backend beans.</para>
      <para>Errai CDI based applications use the same annotation-driven programming model as server-side CDI components, with some notable limitations. Many of these limitations will be addressed in future releases.</para>
      <orderedlist inheritnum="ignore" continuation="restarts">
         <listitem>
            <para>There is no support for CDI interceptors in the client. Although this is planned in a future release.</para>
         </listitem>
         <listitem>
            <para>Passivating scopes are not supported.</para>
         </listitem>
         <listitem>
            <para>The JSR-299 SPI is not supported for client side code. Although writing extensions for the client side container is possible via the Errai IOC Extensions API.</para>
         </listitem>
         <listitem>
            <para>
            The
            <code>@Typed</code>
            annotation is unsupported.
          </para>
         </listitem>
         <listitem>
            <para>
            The
            <code>@Disposes</code>
            annotation is unsupported.
          </para>
         </listitem>
         <listitem>
            <para>
            The
            <code>@Specializes</code>
            annotation is unsupported.
          </para>
         </listitem>
         <listitem>
            <para>
            Qualifier attributes are not currently supported. (eg.
            <code>@MyQualifier(foo=BAR)</code>
            and
            <code>@MyQualifier(foo=FOO)</code>
            will be considered equivalent in the client).
          </para>
         </listitem>
      </orderedlist>
      <section id="sid-5931498_FeaturesandLimitations-Otherfeatures">
         <title>Other features</title>
         <para>
          The CDI container in Errai is built around the
          <link linkend="sid-5931402">Errai IOC module</link>
          , and thus is a superset of the existing functionality in Errai IOC. Thus, all features and APIs documented in Errai IOC are accessible and usable with this Errai CDI programming model.
        </para>
      </section>
   </section>
   <section id="sid-21758054">
      <title>Events</title>
      <para>
        Any CDI managed component may produce and consume
        <ulink url="http://docs.jboss.org/weld/reference/latest/en-US/html/events.html">events</ulink>
        . This allows beans to interact in a completely decoupled fashion. Beans consume events by registering for a particular event type and optional qualifiers. The Errai CDI extension simply extends this concept into the client tier. A GWT client application can simply register an
        <code>Observer</code>
        for a particular event type and thus receive events that are produced on the server-side. Likewise and using the same API, GWT clients can produce events that are consumed by a server-side observer.
      </para>
      <para>Let's take a look at an example.</para>
      <example>
         <title>FraudClient.java</title>
         <programlisting language="java">public class FraudClient extends LayoutPanel {

  @Inject
  private Event&lt;AccountActivity&gt; event; (1)

  private HTML responsePanel;
  
  public FraudClient() {
    super(new BoxLayout(BoxLayout.Orientation.VERTICAL));
  }

  @PostConstruct
  public void buildUI() {
    Button button = new Button("Create activity", new ClickHandler() {
      public void onClick(ClickEvent clickEvent) {
        event.fire(new AccountActivity());
      }
    });
    responsePanel = new HTML();
    add(button);
    add(responsePanel);
  }

  public void processFraud(@Observes @Detected Fraud fraudEvent) { (2)
    responsePanel.setText("Fraud detected: " + fraudEvent.getTimestamp());
  }
}</programlisting>
      </example>
      <para>Two things are noteworthy in this example:</para>
      <orderedlist inheritnum="ignore" continuation="restarts">
         <listitem>
            <para>
            Injection of an
            <code>Event</code>
            dispatcher proxy
          </para>
         </listitem>
         <listitem>
            <para>
            Creation of an
            <code>Observer</code>
            method for a particular event type
          </para>
         </listitem>
      </orderedlist>
      <para>
        The event dispatcher is responsible for sending events created on the client-side to the server-side event subsystem (CDI container). This means any event that is fired through a dispatcher will eventually be consumed by a CDI managed bean, if there is an corresponding
        <code>Observer</code>
        registered for it on the server side.
      </para>
      <para>In order to consume events that are created on the server-side you need to declare an client-side observer method for a particular event type. In case an event is fired on the server this method will be invoked with an event instance of type you declared.</para>
      <para>To complete the example, let's look at the corresponding server-side CDI bean:</para>
      <example>
         <title>AccountService.java</title>
         <programlisting language="java">@ApplicationScoped
public class AccountService {
  
  @Inject @Detected
  private Event&lt;Fraud&gt; event;

  public void watchActivity(@Observes AccountActivity activity) {
    Fraud fraud = new Fraud(System.currentTimeMillis());
    event.fire(fraud);
 }
}</programlisting>
      </example>
      <section id="sid-21758054_Events-Conversationalevents">
         <title>Conversational events</title>
         <para>
          A server can address a single client in response to an event annotating event types as
          <code>@Conversational</code>
          . Consider a service that responds to a subscription event.
        </para>
         <example>
            <title>SubscriptionService.java</title>
            <programlisting language="java">@ApplicationScoped
public class SubscriptionService {
  
  @Inject
  private Event&lt;Documents&gt; welcomeEvent;

  public void onSubscription(@Observes Subscription subscription) {
    Document docs = createWelcomePackage(subscription);
    welcomeEvent.fire(docs);
 }
}</programlisting>
         </example>
         <para>
          And the
          <code>Document</code>
          class would be annotated like so:
        </para>
         <example>
            <title>Document.java</title>
            <programlisting language="java">@Conversational @Portable
public class Document {
   // code here
}</programlisting>
         </example>
         <para>
          As such, when
          <code>Document</code>
          events are fired, they will be limited in scope to the initiating conversational contents – which are implicitly inferred by the caller. So only the client which fired the
          <code>Subscription</code>
          event will receive the fired
          <code>Document</code>
          event.
        </para>
      </section>
      <section id="sid-21758054_Events-ClientServerEventExample">
         <title>Client-Server Event Example</title>
         <para>A key feature of the Errai CDI framework is the ability to federate the CDI eventing bus between the client and the server. This permits the observation of server produced events on the client, and vice-versa.</para>
         <para>Example server code:</para>
         <example>
            <title>MyServerBean.java</title>
            <programlisting language="java">@ApplicationScoped
public class MyServerBean {
  @Inject
  Event&lt;MyResponseEvent&gt; myResponseEvent;

  public void myClientObserver(@Observes MyRequestEvent event) {
    MyResponseEvent response;

    if (event.isThankYou()) {
      // aww, that's nice!
      response = new MyResponseEvent("Well, you're welcome!");
    }
    else {
      // how rude!
      response = new MyResponseEvent("What? Nobody says 'thank you' anymore?");
    }

    myResponseEvent.fire(response);
  }
}</programlisting>
         </example>
         <para>Domain-model:</para>
         <example>
            <title>MyRequestEvent.java</title>
            <programlisting language="java">@Portable
public class MyRequestEvent {
  private boolean thankYou;

  public MyRequestEvent(boolean thankYou) {
    setThankYou(thankYou);
  }

  public void setThankYou(boolean thankYou) {
    this.thankYou = thankYou;
  }

  public boolean isThankYou() {
    return thankYou;
  }
}</programlisting>
         </example>
         <example>
            <title>MyResponseEvent.java</title>
            <programlisting language="java">@Portable
public class MyResponseEvent {
  private String message;

  public MyRequestEvent(String message) {
    setMessage(message);
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public String getMessage() {
    return message;
  }
}</programlisting>
         </example>
         <para>Client application logic:</para>
         <example>
            <title>MyClientBean.java</title>
            <programlisting language="java">@EntryPoint
public class MyClientBean {
   @Inject
   Event&lt;MyRequestEvent&gt; requestEvent;

   public void myResponseObserver(@Observes MyResponseEvent event) {
     Window.alert("Server replied: " + event.getMessage());
   }

   @PostConstruct
   public void init() {
     Button thankYou = new Button("Say Thank You!");
     thankYou.addClickHandler(new ClickHandler() {
       public void onClick(ClickEvent event) {
         requestEvent.fire(new MyRequestEvent(true));
       }
     }

     Button nothing = new Button("Say nothing!");
     nothing.addClickHandler(new ClickHandler() {
       public void onClick(ClickEvent event) {
         requestEvent.fire(new MyRequestEvent(false));
       }
     }

     VerticalPanel vPanel = new VerticalPanel();
     vPanel.add(thankYou);
     vPanel.add(nothing);

     RootPanel.get().add(vPanel);
   }
}</programlisting>
         </example>
      </section>
   </section>
   <section id="sid-21758062">
      <title>Producers</title>
      <para>Producer methods and fields act as sources of objects to be injected. They are useful when additional control over object creation is needed before injections can take place e.g. when you need to make a decision at runtime before an object can be created and injected.</para>
      <example>
         <title>App.java</title>
         <programlisting language="java">@EntryPoint
public class App {
  ...

  @Produces @Supported
  private MyBaseWidget createWidget() {
    return (Canvas.isSupported()) ? new MyHtml5Widget() : new MyDefaultWidget();
  }
}</programlisting>
      </example>
      <example>
         <title>MyComposite.java</title>
         <programlisting language="java">@ApplicationScoped
public class MyComposite extends Composite {
  
  @Inject @Supported
  private MyBaseWidget widget;

  ...
}</programlisting>
      </example>
      <para>
        Producers can also be scoped themselves. By default, producer methods are dependent-scoped, meaning they get called every time an injection for their provided type is requested. If a producer method is scoped
        <code>@Singleton</code>
        for instance, the method will only be called once, and the bean manager will inject the instance from the first invokation of the producer into every matching injection point.
      </para>
      <example>
         <title>Singleton producer</title>
         <programlisting language="java">public class App {
  ...

  @Produces @Singleton
  private MyBean produceMyBean() {
    return new MyBean();
  }
}</programlisting>
      </example>
      <para>
        For more information on CDI producers, see the
        <ulink url="http://docs.jboss.org/cdi/spec/1.0/html/">CDI specification</ulink>
        and the
        <ulink url="http://seamframework.org/Weld/WeldDocumentation">WELD reference documentation</ulink>
        .
      </para>
   </section>
   <section id="sid-5931501">
      <title>Deploying Errai CDI</title>
      <para>
        If you do not care about the deployment details for now and just want to get started take a look at the
        <ulink url="https://docs.jboss.org/author/pages/viewpage.action?pageId=5833096">Quickstart Guide</ulink>
        .
      </para>
      <para>The CDI integration is a plugin to the Errai core framework and represents a CDI portable extension. Which means it is discovered automatically by both Errai and the CDI container. In order to use it, you first need to understand the different runtime models involved when working GWT, Errai and CDI.</para>
      <para>
        Typically a GWT application lifecycle begins in
        <ulink url="http://code.google.com/webtoolkit/doc/latest/DevGuideCompilingAndDebugging.html">Development Mode</ulink>
        and finally a web application containing the GWT client code will be deployed to a target container (Servlet Engine, Application Server). This is no way different when working with CDI components to back your application.
      </para>
      <para>What's different however is availability of the CDI container across the different runtimes. In GWT development mode and in a pure servlet environment you need to provide and bootstrap the CDI environment on your own. While any Java EE 6 Application Server already provides a preconfigured CDI container. To accomodate these differences, we need to do a little trickery when executing the GWT Development Mode and packaging our application for deployment.</para>
      <section id="sid-5931501_DeployingErraiCDI-DeploymentinDevelopmentMode">
         <title>Deployment in Development Mode</title>
         <para>In development mode we need to bootstrap the CDI environment on our own and make both Errai and CDI available through JNDI (common denominator across all runtimes). Since GWT uses Jetty, that only supports read only JNDI, we need to replace the default Jetty launcher with a custom one that will setup the JNDI bindings:</para>
         <informalexample>
            <programlisting language="xml">&lt;plugin&gt;
  &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
  &lt;artifactId&gt;gwt-maven plugin&lt;/artifactId&gt;
  &lt;version&gt;${gwt.maven}&lt;/version&gt;

  &lt;configuration&gt;
  ...
    &lt;server&gt;org.jboss.errai.cdi.server.gwt.JettyLauncher&lt;/server&gt;
  &lt;/configuration&gt;
  &lt;executions&gt;
  ...
  &lt;/executions&gt;
&lt;/plugin&gt;</programlisting>
         </informalexample>
         <note>
            <title>Starting Development Mode from within your IDE</title>
            <para>Consequently, when starting Development Mode from within your IDE the following program argument has to be provided: -server org.jboss.errai.cdi.server.gwt.JettyLauncher</para>
         </note>
         <para>Once this is set up correctly, we can bootstrap the CDI container through a servlet listener:</para>
         <informalexample>
            <programlisting language="xml">&lt;web-app&gt;
  ...
  &lt;listener&gt;
    &lt;listener-class&gt;org.jboss.errai.container.CDIServletStateListener&lt;/listener-class&gt;
  &lt;/listener&gt;
 
  &lt;resource-env-ref&gt;
    &lt;description&gt;Object factory for the CDI Bean Manager&lt;/description&gt;
    &lt;resource-env-ref-name&gt;BeanManager&lt;/resource-env-ref-name&gt;
    &lt;resource-env-ref-type&gt;javax.enterprise.inject.spi.BeanManager&lt;/resource-env-ref-type&gt;
  &lt;/resource-env-ref&gt;
  ...
&lt;/web-app&gt;</programlisting>
         </informalexample>
         <note>
            <title>Errai-CDI maven archetype</title>
            <para>Sounds terribly complicated, no? Don't worry we provide a maven archetype that takes care of all these setup steps and configuration details.</para>
         </note>
      </section>
      <section id="sid-5931501_DeployingErraiCDI-DeploymenttoaServletEngine">
         <title>Deployment to a Servlet Engine</title>
         <para>
          Deployment to servlet engine has basically the same requirements as running in development mode. You need to include the servlet listener that bootstraps the CDI container and make sure both Errai and CDI are accessible through JNDI. For Jetty you can re-use the artefacts we ship with the archetype. In case you want to run on tomcat, please consult the
          <ulink url="http://tomcat.apache.org/tomcat-5.5-doc/jndi-resources-howto.html">Apache Tomcat Documentation</ulink>
          .
        </para>
      </section>
      <section id="sid-5931501_DeployingErraiCDI-DeploymenttoanApplicationServer">
         <title>Deployment to an Application Server</title>
         <para>
          We provide integration with the
          <ulink url="http://jboss.org/jbossas">JBoss Application Server</ulink>
          , but the requirements are basically the same for other vendors. When running a GWT client app that leverages CDI beans on a Java EE 6 application server, CDI is already part of the container and accessible through JNDI (
          <code>java:/BeanManager</code>
          ).
        </para>
      </section>
      <section id="sid-5931501_DeployingErraiCDI-ConfigurationOptions">
         <title>Configuration Options</title>
         <para>
          Since the discovery of service implementations (beans) is delegated to the CDI container, we need to disable Errai's own service discovery mechanism. In order to do so, simply turn off the auto-discovery feature in
          <code>ErraiService.properties</code>
        </para>
         <informalexample>
            <programlisting language="java">errai.auto_discover_services=false</programlisting>
         </informalexample>
      </section>
   </section>
</chapter>