Showing posts with label CDI. Show all posts
Showing posts with label CDI. Show all posts

Thursday, 24 April 2014

PrimeFaces, JSF 2.2 and CDI on Google App Engine

Introduction

Recently we did a proof of concept on Google App Engine, the cloud solution of Google. The Java version, supports servlets and you can already find various resources on the internet where the procedure is described to have the technologies listed in the title working on the platform.

But some of them are already quit old or give only a partial solution.  So I decided to put our findings together in this blog post.  All the frameworks are from the Apache group or have the Apache License.

We used version 1.9.1 of the Java GAE SDK.

JSF

The most difficult technology of the list is JSF. You can find various posts where you have to create your custom version of Mojarra to be able to deploy it.  This has to do with the use of JNDI sources which is not allowed on AppEngine.

We tried the Apache MyFaces 2.2.2 version and it went remarkable smooth.  We made the following  configuration options in the appengine-web.xml file.

    <sessions-enabled>true</sessions-enabled> 
    <threadsafe>true</threadsafe> 
    <static-files> 
        <exclude path="/**.xhtml" /> 
    </static-files>


The least obvious things was that we needed to tell AppEngine that xhtml files aren’t static, so that we can define it as an url pattern for the faces servlet.  Using this url extension is a best practice so that you can’t retrieve the raw html files of JSF.

EL 2.2

At this point, we were already able to deploy a JSF application and had the hello world style application working.  But if we tested with method expressions, like

<h:commandButton value="Greet" actionListener="#{testAction.doGreeting()}" />


We received an error that the brackets weren’t expected.  So it was clear that only value expressions are recognised and not the method expressions.

We tried various EL expression factories, and it turned out that the one of JBoss worked best.  But we weren’t able to use the latest version of the framework. we received following security exception

access denied ("java.lang.RuntimePermission" "modifyThreadGroup")

Although it is a CR release, it did the job so we stayed with this maven artefact  org.jboss.el:jboss-el:1.0_02.CR6

PrimeFaces

Plain JSF applications aren’t attractive, that is why you use some component library like PrimeFaces which became the de facto standard.  Adding this to artefact to the maven dependencies, we hit another issue, but this time we identified it as a known GAE bug.

It has to do with the handling of the If-Modified-Since request header.  But we quickly found an excellent solution by Derek Berube.

Adding the 2 classes and define the filter in the web.xml file, the problem was solved.

We even tried the latest PrimeFaces 5.0 version (it was just before it went into his first CR release) and there was no other issue we could see at first glance.  So this means you can now create web application targeted to mobile devices on Google App Engine.

CDI

As I’m a strong believer of Java EE, so I tried to use CDI for the middleware instead of the Spring approach too many people take without considering the alternatives.

There is an excellent Apache implementation of CDI, called OpenWebBeans.  The following artefacts where added to the project

  • openwebbeans-impl
  • openwebbeans-spi
  • openwebbeans-web
  • openwebbeans-jsf
  • openwebbeans-el22

Regarding the configuration of OpenWebBeans, we just had to follow the procedure for a regular web server like Tomcat or Jetty.
After adding an empty beans.xml file and define the WebBeansConfigurationListener in the web.xml, the dependency injection worked like a charm.

Just as with JSF, there exists also for CDI an extension beyond the basic stuf and I choose CODI (Apache MyFaces Extensions CDI). Just adding the dependency was enough to make it work.

Other technologies

We also added the JPA option and used a maven plugin to handle the deploy to Google App Engine automatically when a mvn deploy command is issued.

I find it a pity that there is no database solution available for free on Google App Engine. It doesn’t need to be very powerful. Just a simple schema that you can use for demonstration purposes of your application.

This is in contrast with the JBoss OpenShift offering, where you can have a full Java EE stack with a database for free.  But that will be covered in another blog post.

Conclusion

Apart from one little issue (bug 8415) which can easily be bypassed, it was quit easy to assemble the required stack to have a JSF based web development environment on Google App Engine. This is in contrast with a few years back where various issues limited the possibilities.



Sunday, 10 November 2013

GenericMessage for DeltaSpike supporting JSF and REST

Introduction

In the post of January 2013, I described the feature of DeltaSpike to have type safe messages from within a CDI bean which are displayed within the <h:messages> tag of JSF.
It is a great feature which has a minor drawback, especially in the perspective of Java EE as a universal backend system. (see this post for the idea behind this)
In the case a CDI bean, like a service type of bean, is used in the context of JSF and REST contexts, because you have multiple types of clients, there is an issue with JsfMessage of DeltaSpike.

Custom version

Since DeltaSpike is an open source project, you can easily find out how the feature is coded. And you can create something similar which isn’t tied to JSF quit easy as you can see in this post.
First we need to define the alternative for the JsfMessage interface, lets call it BusinessMessage.
public interface BusinessMessage<T> {

    T failing();

    T warning();

    T information();
}

We have 3 methods, so that we can define an error, warning and information message. 

The usage of this interface will be identical to the JsfMessage one of DeltaSpike.  Se we need to define an interface which will be annotated as MessageBundle and we are ready to use it.
@MessageBundle
public interface ApplicationMessages {

    @MessageTemplate(value = "Person already registered")
    String personAlreadyRegistered();
}


@ApplicationScoped
public class AttendeeService {

    @Inject
    private BusinessMessage<ApplicationMessages> message;

    public void addPerson(Person person) {
        //....
        message.failing().personAlreadyRegistered();
    }
}

Within the implementation of the BusinessMessage interface we will make, we can now make sure it will work within a JSF and REST context.

BusinessMessage implementation details

I’m not going to describe all the implementation details in this post.  In a few weeks, the code of a demo application will be made available that highlights almost all of the things that kept me busy the last year. And it is using the BusinessMessage described here.

The code is using the org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler class of DeltaSpike to have a dynamic implementation of the @MessageBundle annotated interfaces like ApplicationMessages we have in the above example block.

Once we have the message text the user wants, we will store it in a Thread local variable, maintained by a new class BusinessMessageContext.  This class makes it possible to keep some messages independent of the view technology used. So it is supporting JSF and REST style of working.

Show the messages

The last step to solve our issue is that we need use the messages stored in the BusinessMessageContext and send it to the correct view.

For JSF we can create a PhaseListener implementation which is triggered before each Render Response phase.  It can add the messages to the JSF system using the facesContext.addMessage method.

For REST, we can use a javax.ws.rs.container.ContainerResponseFilter concept explained in this post, to send the messages to the client as a JSON response. Some of the aspects will be described in more detail in a future post on that blog.

In both cases, we need to do the clean up of the Thread local variable we have used to store the messages to reclaim the memory.  Therefor the class BusinessMessageContext has a method release() to perform this clean up.

Conclusion

JsfMessage of DeltaSpike is a great feature to have type safe messages. But in some cases your CDI bean will be used in multiple ‘environments’, JSF and REST for example. In that case, we need an alternative which works almost the same but stores the messages, at least initially, in a view neutral way.

Code will be available as part of the demo which will be released in a few weeks.

Monday, 5 August 2013

From CODI to DeltaSpike

Introduction

CODI is my favourite CDI extension framework where you can find all kind of goodies when you are working in a CDI environment.
Some time ago, there was a decision to create a new CDI extension framework which brings together all the good features of CODI and Seam 3 and other features from other CDI extension libraries.

They have gone through the incubation process at Apache and moving along steadily. The question is, can you already switch from CODI to DeltaSpike for an application?

Not all features of CODI are implemented but my 2 favourites ones are
- The additional scopes like ViewAccessScope
- The fluent API for adding FacesMessages.
So can we create a DeltaSpike application with these 2 features.

Scopes

In the current version of the DeltaSpike framework, version 0.4, there is no support for something like the CODI's ViewAccessScope .
Therefor, Gerhard Petracek created an extension for DeltaSpike to have the missing scopes from CODI version 1.0.5 into DeltaSpike. See here.
So adding the required dependency to the POM


<repositories>
 <repository>
  <id>os890</id>
  <name>Gerhard personal repository</name>
  <url>http://os890-m2-repository.googlecode.com/svn/tags/os890/</url>
  <layout>default</layout>
 </repository>
</repositories>

<dependency>
    <groupId>org.os890.cdi.ext.scope.modules</groupId>
    <artifactId>os890-cdi-ext-jsf2-module-impl</artifactId>
    <version>1.0.5_0.4_01</version>
    <scope>runtime</scope>
</dependency>



The version of the extension is a concatenation of the 2 libraries it will bridge. So we have the structure  &CODI version&_&DS version&_&extension version&.

You only have to use the new package name to have the additional CODI scopes.  The API is identical so that existing code which works for CODI, will also work with DeltaSpike.


So for example for ViewAccessScope,

import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;

becomes 
import org.os890.cdi.ext.scope.api.scope.conversation.ViewAccessScoped;
So for any of the scope packages, you have to replace org.apache.myfaces.extensions.cdi.core with org.os890.cdi.ext.scope.

Messaging


The support for a fluent messaging API is already present in DeltaSpike. So to have this kind of functionality, we don't need to use an extension as we did for having the scopes.

But here we have the issue that the API is changed and thus we need to adapt existing code.

CODI version

messageContext.message().text("{msgKey}").add();

DeltaSpike version

Message defitions.
@MessageBundle
public interface AppMessages {
    @MessageTemplate("{msgKey}")
    String buttonClicked();
}

Within CDI bean
    @Inject
    private JsfMessage jsfMessage;

     
    public void addTestMsg(ActionEvent actionEvent) {
        jsfMessage.addInfo().buttonClicked();
    }


Servers

 The DeltaSpike application was tested successful on Glassfish 3.1.2.2 and JBoss as 7.1.1.Final.

Also the original CODI version was running without a problem on the new Glassfish 4 version.

On this server, the DeltaSpike version had a problem.  There was an exception thrown in the extension as there is no problem with the DeltaSpike code itself. All the integrations tests of DeltaSpike are running also on a Weld 2 version (used in the Glassfish 4) so you can expect that it is working on it without any problem.

With the new WLS 12C server, version 12.1.2, there is also an issue running the DeltaSpike application.   The application deployment fails during validation where it can't inject an Extension class into another bean.

Conclusion

With the help of the DeltaSpike extension, you can create already applications that uses a lot of the features of the CODI framework.
So check what features you need and maybe you can already create your application with the DeltaSpike framework.

Monday, 13 May 2013

JSF 2.2 Stateless views explained

Introduction

The JSF 2.2 specification (JSR-344) is recently approved. There are a few examples available but there seems no detailed explanation yet of the new features.
Although the development is still in progress, I like to start today already with the stateless view features which was fairly late added to the list of JSF 2.2 features.
The ticket had many votes and stateless is hot, so for many people this is a very wanted feature which is added.
But be aware of the implementation details and some other facts that are very good explained in this section of the excellent overview of Arjan Tijms on JSF 2.2 features.

transient=”true”

The explanation of the feature is fairly simply. By specifying the attribute transient on the f:view tag, we are able to run that page in a stateless mode. Stateless here means that the JSF StateManager isn’t storing any data into the memory related to this view.
During restore view phase, the view is created, as always, but now there isn’t any state applied to it.
It is a fairly simple change but has a lot of consequences.

viewScoped beans

The most important effect of the stateless operation mode is that all viewScoped beans are lost. Those kind of beans, tied to a certain view, aren’t stored anymore and thus, when the same page is rendered again, a new version of the bean needs to be instantiated again.
It can easily demonstrated by a ‘classic’ scope testing application, for example the one I used here to test CODI on WLS 12c server. You create beans with a different scope, like requestScope, viewScope, sessionScope and applicationScope and initialize a timestamp in the constructor.  The value of this property is then shown on screen where you can do a post to stay on the same page or go to another page which has the same beans on it.
In the case of the transient view, even if you stay on the same page, a new instance of the viewScoped bean is created. The other scopes aren’t affected.
I tried this with the Glassfish 4 promoted build 87 and a Tomcat 7 instance where I used the latest available Mojarra 2.2 snapshot.

viewScope != viewScope

Although not immediately linked to the stateless view features, there are now 2 ViewScoped annotation classes. We had already the RequestScoped, SessionScoped and ApplicationScoped from JSF (package javax.faces.bean) and the CDI version (in package javax.enterprise.context).
As requested by many developers, there is now also a CDI version of the ViewScoped (from package javax.faces.bean) but defined in JSF (and not CDI). The new class is defined in javax.faces.view. Look careful to import the correct class in relation to the @ManagedBean or @Named annotation because mixing them will lead to unexpected behaviour.

When to use

What are the use cases for the stateless view operation mode. As already mentioned in the feature description by Arjan Tijms, performance and memory gain is minimal, except when you are working with very large pages that contains thousands of components.
Besides the fact that ViewScoped beans behave differently, a lot of components are relying on the fact that they can save and restore their state within the view. So many components, standard ones but also from component libraries like PrimeFaces will not function properly anymore on stateless views.
On the other side, views are stateless and this means you can even post your data back to the server, after your session has expired or even after a server reboot.

Conclusion

Since there is a large impact on AJAX behaviour, commonly used with ViewScoped beans, and the proper functioning of components, considering stateless views must be evaluated thoroughly and tested very profound.
And initiatives like the one from Industrie IT should also be considered when you are interested in those kind of setups.

Sunday, 6 January 2013

DeltaSpike JSF message system

Introduction

One of the main aspects of the Java EE 6 version was type safety. With the introduction of CDI, there are many tasks that can be done in a type safe way, with no needs of Strings anymore.
This improves the quality of the code since it reduces the chance of typo errors. During compilation, you can be warned of your mistake.
DeltaSpike is a CDI extension that combines all the goodies of the Apache CODI and SEAM 3 frameworks. It is a work in progress and lately the work on some JSF goodies is started.
In this text, I want to explain the message feature of DeltaSpike. And although there is still some String handling required, at least it makes it very flexible and extensible.  This is not the case with the default JSF functionality.

Getting started

The message feature is based on some advanced features of CDI where we can define our message as methods in an interface where no implementation is needed. Lets explain this based on the classic Hello world style example.
So we start with an interface that we annotate with MessageBundle

@MessageBundle
public interface ApplicationMessages
{
    String helloWorld(String name);
}
In a managed bean/controller we can inject then the message component and ask for the text linked with the message.  This is an example of a managed bean using the JsfMessage.

@Named
@RequestScoped
public class ControllerView
{
    private String name;
    @Inject
    private JsfMessage msg;
    public void doGreeting()
    {
        msg.addInfo().helloWorld(name);
    }
}

In the typical Hello world style where there is an input field on the screen linked with the name property and a button linked to the doGreeting method, the above code shows a JSF Info message on the screen.

JsfMessage is also an interface and can take only as type parameter an interface which is annotated with MessageBundle such as in our example above.
On the JsfMessage interface there are methods available to add a message to the JSF Message system with a certain severity, like info in our example, add the message for a certain component or just get the text of the message, without adding it.

The default implementation takes care of looking up the correct locale, message text and assembles the resulting String.

It isn't CDI as it wasn't customizable and extensible. But before we look at the possibilities, I have to explain first where, by default, it looks for the text definition.

In the above example, a resource bundle ApplicationMessages in the same directory as the package of the interface is interrogated for the key helloWorld.
So by default, it looks in the same directory for a key which equals the method name.
 
helloWorld=Welcome %s

Also pay attention on how you need to specify the place of the parameter in the text.  The default version uses the String#format() method which requires the %-character as placeholder indicator.  This is different from the standard JSF where we used the {0} type of placeholder.

But this can be customized by the MessageInterpolator but first try some easy configuration options.

Configuration options

In the previous section, we used the JsfMessage feature in his most basic format.  We used all the default settings and implementations.  In this section, I'll explain how you can customize the ResourceBundle and the key which will be used.

On the methods, we can place the MessageTemplate annotation.  With this annotation we can specify the key or the entire text which will be used. In case it is a key in the resource bundle, we need to wrap it inside {} characters as you can see in the example below.
The second customization is the ResourceBundle name which will be searched, in addition to the default one. It can be specified by the MessageContextConfig#messageSource member.

As you noticed in my wording, it defines additional ResourceBundles, so be careful if you define multiple candidates where the resource key can be found.

@MessageBundle
@MessageContextConfig(messageSource = {"org.apache.deltaspike.example.message.ApplicationMessages" }) 
public interface CustomizedMessages
{
    @MessageTemplate(value = "{nowMessage}")
    String getTimestampMessage(Date now);
}

When we use the above code, we look for a key nowMessage in the ApplicationMessages ResourceBundle. Without the curly brackets, the text itself would be used without looking up a ResourceBundle.

Pay attention to the typos in the messageSource member. When you specify a non existing ResourceBundle, you don’t get a warning or error and of course, the text won’t be displayed correctly.

Customizing individual MessageBundles

With the MessageContextConfig annotation, when can also customize other functionality of the Message system. In this section I'll explain how you can change the MessageInterpolator back to the standard JSF version.

The MessageFormatMessageInterpolator class uses the java.text.MessageFormat to replace the placeholders in the string with the arguments as we are used too. The class implements the interpolate method from the MessageInterpolator interface.

The Custom annotation is a CDI qualifier that I created and is required before the example can work.  I'll explain in a moment the reason for this.

@Custom
public class MessageFormatMessageInterpolator implements MessageInterpolator
{
    @Override
    public String interpolate(String messageText, Serializable[] arguments, Locale locale)
    {
        return MessageFormat.format(messageText, arguments);
    }
}

As already mentioned, with the MessageContextConfig annotation we can decide to use this MessageInterpolator on certain MessageBundles like this

@MessageBundle
@MessageContextConfig(messageInterpolator = MessageFormatMessageInterpolator.class)
public interface CustomizedMessages
{

Why do we need a CDI qualifier on our implementation?  We are not using it for injection, we refer to it by its class name!  Since the default implementation is also available in the Bean archive, the CDI container has 2 implementations available and don't know which one to choose when he needs to inject a MessageInterpolator into the default JsfMessage implementation.

So without the qualifier, our application will fail during deployment with an ambiguous dependency error.

So it is easier and probably also much more useful to replace the default implementation with your version.  This is explained in the next section.

Replace default implementation

In the previous section we changed the behavior for one MessageBundle.  But most of the time, we need to change the default implementation and don't want to specify this for each MessageBundle we create in our application.

As an example, I'll show you how you can define that the message bundle in the Faces config file is also used when a resource key is searched in the ResourceBundles.

@Specializes
public class CustomMessageResolver extends DefaultMessageResolver
{
    @Override
    public String getMessage(MessageContext messageContext, String messageTemplate, String category)
    {
        addMessageBundleFromFacesConfig(messageContext);
        return super.getMessage(messageContext, messageTemplate, category);
    }
    private void addMessageBundleFromFacesConfig(MessageContext someMessageContext)
    {
        String messageBundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle();
        if (messageBundle != null && messageBundle.length() > 0)
        {
            someMessageContext.messageSource(messageBundle);
        }
    }
}

For this, we need to override the DefaultMessageResolver and intercept the call to the getMessage method.  This is the only method in the MessageResolver interface and is responsible for looking up the resource key in resource bundles.  But custom implementation can be written to look up the message text in a database system for example.

Here we use the CDI specilization functionality.  When we annotate an extended CDI bean with Specializes, CDI will use our version, the CustomMessageResolver, in all the cases where DefaultMessageResolver would be used.  Without the need of a CDI qualifier and without the issue of having an ambiguous dependency error.

In our extension of the default functionality, we look in the faces configuration to see if there is a MessageBundle defined.  If so, we add it to the list of messageSources maintained and searched to find the requested message.

The same procedure can be used to define a custom MessageInterpolator and LocaleResolver, dedicated to find the language in which the message text must be returned.

Plain message text

In the hello World example at the beginning of the text, we used the JsfMessage DeltaSpike functionality to add a JSF message.  We can also ask for the text without the need to show it as a JSF Message.
The JsfMessage interface has the get() method for this purpose.  The following snippet could be used to display the current time as text on the screen with #{bean.now}

    public String getNow()
    {
        return custom.get().getTimestampMessage(new Date());
    }

Conclusion

There is no type safety, which is popular in Java EE6, with the JsfMessage feature of DeltaSpike because you always need to specify somehow the resource key that needs to be used when the text is looked up.  But you have a flexible and extensible system that is much more readable due to the builder like pattern.
The JsfMessage feature is currently (begin January 2013) under development in the 0.4-INCUBATING version and the code can be found here.
In the JsfExample module you can find the examples described in this text.

Saturday, 29 September 2012

From backend event to Screen update with PrimeFaces Push

Introduction

Maybe the longest title of a post that I will ever write, but it gives a good idea about what the text explains.  There are various use cases where an action on the backend should be reflected on the screen of the users that are currently working with the application.
An example could be that the number of available places for a training is updated on the screen when another user finishes the registration for that same training. But not only the number on the screen should change, but when the counters reaches zero, we must disable the ‘submit’ button for the user who was almost ready with filling in his data.
With the recently released version 3.4 of PrimeFaces, the JSF community has an easy way of making those things possible. With PrimeFaces Push, powered by the Atmosphere framework, you can have parts of your JSF based screens updated by server side push technology.  And the best thing of all, you don’t need to write a single JavaScript statement to achieve this.  Those people that know me, know that this is a huge advantage because I can’t write a decent line of JavaScript.
The following code snippets assume you have an JEE6 application.

PrimeFaces Push

Lets start from the end result and work our way to the source that triggered the update on the screen. The setup of PrimeFaces Push is very easy.  I assume, you already use PrimeFaces in your project.  Since PrimeFaces Push is a layer around Atmosphere, we only need to add those libraries in our application. If you use Maven, it is sufficient to add the runtime to your maven POM file.
        <dependency>
            <groupId>org.atmosphere</groupId>
            <artifactId>atmosphere-runtime</artifactId>
            <version>1.0.0.RC1</version>
        </dependency>

You can always add the atmosphere libraries to the lib directory of your web app folder.

The second, and last, thing we need to do is to specify a servlet that is used as entry point for the web browser calls. The following snippet can be placed in the web.xml file.
    <servlet>
        <servlet-name>Push Servlet</servlet-name>
        <servlet-class>org.primefaces.push.PushServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Push Servlet</servlet-name>
        <url-pattern>/primepush/*</url-pattern>
    </servlet-mapping>

The URL pattern of the servlet mapping is of no importance.  We just need some value as entry point.

The screen


We now can adjust the JSF screen to integrate the push technology. The main PrimeFaces component for this is the p:socket component. It is responsible for all the stuff related to the server side push technology.  In the case you want to update a part of the screen in reaction to a notification from the server that an update is required, the following snippet is enough.
        <h:form id="form">
          ...
        </h:form>
        <p:socket channel="/registrationEvent">
            <p:ajax event="message" update="form:activities"/>
        </p:socket>


The JSF form contains the regular components that make up your page. The p:socket has an attribute that specifies the channel on which it needs to be bound.  You can define different channels so that you can send different types of events to the browser.  Here in this case, we say that we are interested in the event type registrationEvent. What should the screen do when it receives this kind of event from the server? Here we launch a partial page update with the p:ajax component and update a component. In the above example it has the id activities and it is for example a table containing all the trainings and the number of available places.
The attribute event of the ajax component, specifies that the partial update is triggered when we receive a message from the server.  But the actual payload of that message is never used and thus we will see in the next paragraph that we keep it very small.

Initiate the push


You can initiate the push to the browser on various locations in your code.  But I prefer to have it centralized according to the principles of DRY (Don’t Repeat Yourself) and Separation of concerns.  I have a certain class responsible for sending the events to the browsers and they will be triggered by CDI events as you can see in the following code sample.
public class NewRegistration {

    public void observeRegistrationActivity(@Observes RegistrationActivity someRegistrationActivity) {
        PushContext pushContext = PushContextFactory.getDefault().getPushContext();
        pushContext.push("/registrationEvent", "There was another registration");
    }
}


It is a CDI bean with a @Dependent scope (ApplicationScoped is also possible, see further on) and the method observeRegistrationActivity gets called by those code parts that do something with the registration for an activity like a training.  The CDI event gets fired over there (see next chapter) but doesn’t know what exactly is performed in response of that action (like an update of a browser screen).  Implementing the required functionality is the task of the various listeners of that CDI event.  This way we achieve a very loose coupling between the required functionalities.

The 2 lines of Java code comes straight from the PrimeFaces documentation and have the result that all registered browsers receive an event on the channel registrationEvent.  When we make sure that the channel name in the java code and in the p:socket component are the same, the result is that the partial screen update is performed. (tip: With custom EL function you can make sure that the channels is only defined once as a Java constant)

The scope of the CDI bean is important and must be @Dependent or @ApplicationScoped. Since request and session scoped beans are always linked with an HTTP request from the browser, those beans are not always ‘active’ which results in exceptions.

Initiate the event


We have now the possibility to trigger a partial screen update in the browser when we fire a certain CDI event. The code for firing such an event is easy and can be located in any kind of bean (CDI or EJB)
    @Inject
    private Event<RegistrationActivity> events;

    public void changedEntry(Activity someData) {
        events.fire(new RegistrationActivity(someData.getId()));
    }

When the method changedEntry is called, the whole chain is set into motion and the user sees the new information.

This code can be used in a Stateless Session Bean (EJB) when we have updated the database and have now a new value for the available places of the specified training.

But the placement of this kind of code can be much more exotic, let say an EntryListener of Hazelcast.
Hazelcast is a in-memory data grid solution that can be clustered and can be categorized as NoSQL.
For a distributed Map for example, you can register an EntryListener. Every time, any Hazelcast client makes a change to that map, the listener is triggered.  But such an EntryListener can be a CDI bean that fires the CDI event that goes all to way up to the browser.

This creates a very powerful system that any application that changes some value in a distributed Map of Hazelcast, will trigger an update on the screen.  Wooow.

Conclusion


PrimeFaces Push is an easy to setup system that uses the Atmosphere framework to integrate the server side push technology in a JSF component library.  Combined with the power of CDI events, you can trigger a screen update from anywhere in the application.  You can extend this even to a in-memory data grid solution.

And all this can be achieved by a few lines of code so that you once again can concentrate on the business problems and don’t have to worry about the infrastructure.