Monday 10 December 2012

Java EE6 as the universal backend

Introduction

Java EE6 is referred to by many people to be the most easy, productive, lightweight and best version of the enterprise environment. As a developer you can concentrate on the business logic and you don't have to spend time on the infrastructure side of the application.
Since J2EE 1.4, they made great efforts for simplifying the creation of Enterprise applications.  With the principles of 'convention over configuration', intelligent defaults and the usage of annotations, you can create EJB's or REST style webservices in minutes.
Due to the lightweight aspect of the current application servers, like JBoss AS 7 starts up in 7 seconds, you can have short development cycles where you can quickly test your new code.
In addition to these developments in the standard, there are other great initiatives which makes the Java EE 6 environment very attractive.
  • You have the Arquillian framework which gives the term testing a complete new dimension.  As it is a container-oriented testing framework, it allows you to execute integration tests in a real container as if it were unit tests.  Since they are portable, you can test for cross container compatibility of your application.
  • Another great framework is MyFaces CODI, a CDI extension, which is currently integrated with JBoss Seam3 into Apache DeltaSpike. It unleashes the power of the CDI framework and enables you to use Dependency Injection in radical new ways.
  • A third initiative I want to mention here is PrimeFaces. The PrimeFaces JSF components became very popular with JSF 2. They allow you to create powerful modern Rich Internet Application and yet keep the component library easy to use.

All on Java EE 6

In October, I had the privilege to give a course and presentation together with Çagatay Çivici, project lead of PrimeFaces project. During my presentation I showed a few cases where you can use the Java EE 6 environment as backend for your applications.
In that week, PrimeUI was first announced. And it made my realize that my story about the Java EE 6 environment could be extended even further. There was yet another type of applications that I could add to the picture.
So here is a short overview of the types of applications that are possible with Java EE 6
  1. JavaServer Faces
    This is the most obvious type of applications since JSF is part of the Java EE 6 specification.  But due to the nature of the framework, it is best suited for administrative applications which run in the browser of the desktop. With his component based nature and the standard facilities for conversion and validation, it makes it excellent for handling user input.
    However it requires some state kept in the session memory of the user. And although they have made quit some improvements in the JSF 2.x versions, it isn't the best choice for high volume websites.
  2. Mobile apps
    With the popularity of smartphones, there is a whole new market emerged that creates applications for the mobile devices.  They are native apps, running on the device itself and can access the services of the device easily.  But most of them also need data that are supplied from an external source, mostly in JSON format.
    With the JAX-RS component of Java EE 6, you can create easily some restful services that, annotated correctly, supply the caller the requested data in JSON format or take some data in. By just adding the @Path annotation to a CDI or EJB bean, you have created a restful services endpoint. This allows you to reuse your knowledge (and even functionality if needed) and support your native application quickly.
  3. Browser based mobile application
    The downside for mobile applications is the fact that you need to learn, or use, a specific language, like Objective C, and that your application is not compatible between all the type of devices.  With PrimeFaces Mobile, based on JQuery Mobile, you can create web applications that run in the browser of the mobile device but has the look and feel of a native app.
    PrimeFaces Mobile is just a component library, so it can be used easily by someone that knows JSF. And of course, here you can also use the complete power and functionality of the Java EE 6 stack.
These type of applications where presented during my presentation and can be summarized in the following picture.
Universal_Java_EE6_Backend

But don't focus on the database in the picture, in the demos I also used Hazelcast as a NoSQL solution and integrated it with CDI.

StatelessPrime

The fourth option in the picture is something I'm experimenting with since October. With PrimeUI, the widgets of the PrimeFaces component library will be available as a JavaScript version.  As communication, JSON data will be used. So why not using Java EE 6 stack then?


That is how the idea of StatelessPrime was born.  Creating stateless Web applications with HTML5, CSS, JavaScript and PrimeUI on the client side and Java EE 6 with the JAX RS module that does the communication in JSON format on the server side.
But the idea goes further. Is it possible to create a component library that allows some kind of compiler to generate the HTML5, JavaScript and JAX RS classes?  That way you can reuse your JSF and CDI knowledge to rapidly create stateless web applications.

You can follow my experiments on the StatelessPrime blog.

Sunday 25 November 2012

Advanced PrimeFaces Graphic Image renderer for dynamic content

PrimeFaces has a component to render graphic resources and has added support for dynamic generated content.
There is a special StreamedContent class for this, so that you stream the generated resources from the JSF application to the browser.

But there are a few limitations for the component when it comes to dynamic generated content.  And they are not related to PrimeFaces but to the communication model between the browser and the application server.
Since there were lately a few questions in the PrimeFaces forum that had to do with these limitations, I decided to create an advanced renderer for the component. But there are a few warnings in using it.
For the impatient ones, you can find the project on GitHub.

How does the PrimeFaces Graphic Image renderer work?

The PrimeFaces Graphic Image renderer generates a html img tag where the src attribute points back to the application.  The URL contains a unique id and stores within the http session of the user, the EL expression linked to that unique id.
The EL expression comes from the value attribute of the p:graphicImage tag that the developer wrote in the JSF file and which points to the StreamedContent value that contains the dynamic generated content.
The browser interprets the html page and ask for the image content based on the URL found in the src attribute.

Since this URL points back to the JSF application, the PrimeFaces resource handler gets a chance to handle the request.  It recognize that the browser asks for a graphic resource with dynamic content based on the URL parts and parameters.
Based on the unique id which is available as parameter in the URL, it can take the corresponding EL and stream the content to the browser.

At this last step, the limitations can be hit in some use cases. Since the resource handler has no idea whatsoever of the page where the dynamic content is located, which bean is involved etc...  It can only rely on the EL expression the renderer has placed in the http session.  It is possible that this EL expression is only valid within a certain context.

The most striking example is the use of a composite component attribute.  Something like #{cc.attr.image} can be perfectly valid within the context of a custom composite component but it is clearly not when arbitrary executed.
The same reasoning goes for the dataTable component.  Whenever you use the alias defined in the var attribute for indicating the dynamic content, the PrimeFaces resource handler will be unable to retrieve the contents.
And the renderer can't determine the  EL expression that can give us the reference to the StreamedContent

Solution

The solution that I implemented is that we store the contents of the dynamic generated content on a location that can is always accessible, without the restriction of a context. This means we need to copy the contents to another location, the file system in our case.
The renderer copies the StreamedContent to a file in the System temp directory. For scaling reasons, this is a better alternative then storing the content directly in the http session area. We now only need to keep the file name next to the unique id instead of the EL expression.

On the other side, there is also another resource handler defined that uses the contents of the file to serve the browser request for the image resource.
The temporary files are removed when the http session is invalidated so that we don't have a problem with the disk storage size. We can't do it earlier because the browser can request the image multiple times as the user goes back in the screen flow or asks for a refresh.

Usage warnings

There is one issue with the above described solution, there is a performance drop.  It all depends on the size of the images of course but we need to write the content to disk, an additional step, and the resource handler serve it from disk which is slower then memory access.
For optimal performance, the storage on the disk is performed by using java.nio.channel.Channels.  That should guaranty to most efficient solution.

The clearing of the files is done when http session is invalidated by a HttpSessionBindingListener.  And although we can be pretty sure that the files gets removed, if the server implementation is correct, the files are kept during the user session.  When you have an application with a lot of dynamic generated content and the user works for a long time with your application, a lot of files can be created.

Intelligence of the advanced renderer

Therefore, there is some intelligence build into the Graphic Image renderer.  The scenario where the content is stored on disk is by default only used when the graphicImage tag is used within a custom composite component or a component that implements the UIData interface like dataTable.
These 2 cases are the situations where there is a lot of chance that the standard algorithm of PrimeFaces will fail. If this is not the case, the standard PrimeFaces functionality will be used (without the storage on disk).

Intelligent default functionality is fine but sometimes you need to take control yourself. This can be achieved by nesting a advancedRenderering tag within the graphicImage tag.  By specifying a boolean value for the value attribute, you can control the usage of the advanced rendering functionality.

Use cases where this can be handy.
1) You are using the graphicImage tag within a custom composite component but you as developer know that the EL you have specified can be used outside of the component (it is 'general' and not tied to a certain context) then you can disable the advanced rendering.
2) You have created the dynamic content with a bean on a request scope.  The resource handler can perfectly access the bean but in most cases the generated content is lost.  Here you can ask for the advanced rendering so that at render time, the image is stored on disk ready for streaming to the browser.

Code

The code can be found on GitHub and is released under the Apache License, Version 2.0.

Friday 2 November 2012

Disabled selection button for PrimeFaces data table

Introduction

When you use the disabled attribute of a button, you can have some troubles executing the action and actionListener bound targets. The same goes for an input component where you can loose the user input.
But there are various use cases where an initial disabled button could be vary handy. The easiest solution could be that you change the scope of the managed bean the property is located that determines the value of the disabled attribute. But in this post I’ll describe an alternative and why it is maybe the best solution.

Disabled button problem

In the Apply request values phase of the JSF life cycle, you can find various resources on the internet that explain this important concept of JSF, there is a check if the post values contains the id of the button.
In that case, the specific button is clicked and an event is generated that the logic attached to the button needs to be executed in the Invoke application phase.
This kind of check is required because a form can contain multiple buttons and thus we need to know which functionality needs to be executed.  But the check that the button must be enabled can give us sometimes a problem.
The EL expression specified in the disabled attribute is evaluated in the Apply request values phase and when it evaluates to true, the event isn't posted.
So even when the button is enabled on the screen, during the Apply request values phase
of the JSF lifecycle, the EL expression can return a disabled true value and thus the click on the button has no effect.

Selection button for PrimeFaces data table

So, let us try with the PrimeFaces data table. You have various row selection options but I want to use the one where a button is placed in a footer of the table.
Suppose you have a JSF managed bean called personListView on a view scope that contains the list of records that you need to show in the page.
The view scope will be used in a lot of cases for the backing of a data table as you don't need to read the data in the database every time you change the sorting or filtering. This of course if the list of records you want to show isn't too long and read them all at once in memory.
The second managed bean, personView called, is on request scope and will be used to edit the selected record. It is on request scope because it only need to capture the data entered by the user and save it to the database.
The JSF page contains a section like this:
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
   <p:column headerText="first name">
      ...
   </p:column>
   <f:facet name="footer">
     <p:commandButton ajax="false" value="Edit" action="person.jsf"
                      actionListener="#{personView.checkPerson}"/>
   </f:facet>
</p:dataTable>

In the footer, the button is shown to navigate to the second page, person.jsf, and calls here for demonstration purposes an actionListener method that just add an information message.

The idea is that the edit button stays disabled as long as you haven't selected a record in the data table.

So we change the markup to use the disabled attribute of the commandButton and an ajax call that listens to a row selection so that we can ask for a re-rendering of the button.
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
  <p:ajax event="rowSelect" update="editBtn" />
  <p:column headerText="first name">
                ...
  </p:column>
  <f:facet name="footer">
    <p:commandButton ajax="false" value="Edit" action="person.jsf"
                     actionListener="#{personView.checkPerson}" id="editBtn"
                     disabled="#{empty personView.selectedPerson}"/>
  </f:facet>
</p:dataTable>    

Now the button is disabled as long as we don’t click on a row in the data table.  If we do so, the ajax event is fired, it sets the selected record to the selectedPerson property of the personView managed bean. The re-rendering of the button enables it so that we can click on it.

But if we do click on it, nothing happens. The first thing you should check with a PrimeFaces commandButton that is supposed to do navigation, is that we aren't using ajax.  But in this case, we haven't made any mistake. (ajax=”false” attribute on the commandButton)

The reason why the click on the button has no effect is because of the disabled attribute.  As described above, during Apply request values phase, the EL expression points to a new instance of the personView managed bean, it is at request scope, and thus the selectedPerson property is still null. It will be filled during the Apply model values phase, later on in the life cycle.

Scope change as a solution?


The easiest solution is to change the scope of the personView managed bean to view scope. The bean is first initialized when the ajax call is executing for the row selection. And the bean is kept alive for the click on the button and thus the selectedPerson value has still a value and the button is processed as we expect.

But view scope is a kind of session scope. Surely it has his advantages and usages but a bean with a view scope is stored in the session of the user.  Additional processing is required to remove the bean from the session storage when the user navigates to another view.  So in terms of processing time and server memory consumption, a view scoped bean is worse then a session bean.

So my first reflex is always to use beans on a request scope.  When the situations justifies to use another, longer scope, I will use it of course. So can we fix the above described problem by keeping the personView on request scope?  Yes we can.

The binding attribute.


The solution lies in the binding attribute that each JSF component has. Using this attribute can lead also to some problems (maybe this can be the inspiration for another blog item) but here it makes the selection button responsive again.

The binding attribute gives you to opportunity to have a reference in your backing bean to the java object instance that is used on the component tree representation of your view. It allows programmatic access and changes to the component. So JSF view fragment becomes this:
<p:dataTable value="#{personListView.personList}" var="person" selectionMode="single"
                     selection="#{personView.selectedPerson}" rowKey="#{person.id}">
   <p:ajax event="rowSelect" update="editBtn" listener="#{personView.enableEditBtn}"/>
   <p:column headerText="first name">
      ...
   </p:column>
   <f:facet name="footer">
      <p:commandButton ajax="false" value="Edit" action="person.jsf" binding="#{personView.button}"
                       actionListener="#{personView.checkPerson}" id="editBtn"
                       disabled="#{empty personView.selectedPerson}"/>
   </f:facet>
</p:dataTable>

It has 2 additions; the binding attribute on the commandButton and the listener attribute on the ajax rowSelect tag.

The binding refers to a property in the request scopes personView bean of type HtmlCommanfButton. During the first phase of the life cycle, Restore view Phase, it gets the reference to the java object instance on the component tree for the selection button.
 
private HtmlCommandButton button;

// Setter and getter


The listener attribute of the ajax component is bound to a method in the personView managed bean that manipulates the button programmatically.
 
public void enableEditBtn() {
   button.setDisabled(false);
}
 

When we now click on a record in the data table, the enableEditBtn method is also executed. It 'overrides' the EL expression #{empty personView.seelctedPerson} with the constant value false. It makes the button enabled on the screen when it gets re-rendered but the most important thing of all, the actionListener and navigation are executed since the value of the disabled property is no longer true during the Apply request values phase.

Conclusion

When a JSF commandButton is initially disabled, there are situations that it doesn't respond to a user click when it is re-enabled. Changing the scope of the bean in the EL expression of the disabled button can solve it. But view scope isn't good for the performance of your application. The use of the binding attribute can be the solution.

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.

Friday 31 August 2012

CSS3 ellipsis functionality with PrimeFaces (Client side and server side)

Introduction

If you have a certain user UI requirement, you have basically 2 options when using JSF.
Since the output of the JSF system is in most cases just plain HTML, you can mixing the required CSS and javaScript to have your UI feature. Or you can have some server component that does most of the work and generates the required HTML from their renderers.
An example makes this situation clear.  In a project I had the requirement that on a screen there were a lot of long descriptions of codes that needed to be displayed.
In fact there were so much of them that the screen was very crowded when the full description of all codes was shown. The solution was that only a part of it was shown on the screen and when the mouse hoovered over, the complete description was shown

Server side solution

As I'm much more experienced in writing Custom JSF components, I created a new PrimeFaces component that is capable of showing some truncated text. It is almost identical to the outputText component and has only one additional attribute called truncateAt.
You can define with it the maximum number of characters it shows before three dots are generated.  In the case the text has more characters then specified in the truncateAt attribute, the complete text is placed in the title property of the span element surrounding the shortened text.
This custom PrimeFaces component is quit easy and the important parts of the code responsible for the rendering is shown below:

        writer.startElement("span", null);
        writer.writeAttribute("id", clientId, null);
        String value = outputText.getValue().toString();
        Integer truncateAt = outputText.getTruncateAt();
        if (truncateAt != null && value.length() > truncateAt) {
            writer.writeAttribute("title", value, null);
            value = value.substring(0, truncateAt-1)+"...";
        }

        writer.writeText(value, null);
        writer.endElement("span");
You can improve the above code by searching the words in the description and not slash words in two.

After creating a simple POJO for the component itself (extending HtmlOutputText) and registering your work in the faces-config.xml
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
                version="2.0">
    <namespace>http://www.c4j.be/primefaces</namespace>

    <tag>
        <tag-name>outputText</tag-name>
        <component>
            <component-type>be.c4j.jsf.primefaces.outputtext.OutputText</component-type>
            <renderer-type>be.c4j.jsf.primefaces.outputtext.OutputTextRenderer</renderer-type>
        </component>
        <attribute>
        ....
    </tag>


You have your required functionality.

Cient side solution


Afterwards, some people pointed me to the CSS3 ellipsis (text-overflow attribute) as an alternative solution.  With some standard PrimeFaces components and the use of a proper css style definition, you can achieve the same effect.

The css style class looks like this
.ellipsis {
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 400px;
    vertical-align: bottom;
}


where the width property can be varied to your convenience.  The central element here is the text-overflow: ellipsis line.  Since you can only specify the size of a html element in block mode, you have to specify the display: inline-block to allow more information on the same 'line'

Within the JSF view we can use the tooltip PrimeFaces component to show us the long description when we hoover over the truncated area.
<h:panelGroup styleClass="ellipsis" id="longText">${bean.text}</h:panelGroup>
<p:tooltip for="longText" value="#{bean.text}"></p:tooltip>

Differences of solutions


Both solutions are resulting in more or less the same visual and functional result in the browser but there are a few small differences.
  • With the client side solution, the truncation of the description is performed based on the size it takes on the screen.  When the user changes the font size, there are a different number of characters displayed. With the server side solution, the number of characters is always the same, despite of the user font settings.
  • The tooltip is only shown when some truncation of the description occurs in the server side solution in contract to always for the client side solution.  This can be changed by adapting the rendering code and always add the description to the title property.  However showing the same text in the tooltip isn't common practice.

Comparison of solution


As said, both solutions are resulting in more or less the same visual and functional result in the browser but each has his pro and contra. An overview of them

pro server side
  • Works on all browsers, no CSS3 support required
  • No CSS required, good for CSS/JavaScript newbies (I'm one of them)
  • Advanced algorithm determining the ... position easy to implement.

contra server side
  • Custom JSF component required (you need to use another tag in the JSF view if you want the functionality)
  • Less skinnable (look and feel changes by just changing CSS and JavaScript)

For the client side solution, the pro and contras are basically switched.

pro client side
  • No special/custom JSF component required, only the tooltip component of PrimeFaces
  • Skinnable
  • Screen layout is better preserved when user changes font size in browser.

contra client side
  • CSS3 browser support required.  This time Firefox was very late to include support for it and it is only available since version 7.
  • Positioning of the ... is difficult to align with the word boundaries.

Conclusion


I still prefer the server side solution, the one I used in the project.  I find it easy to create a simple JSF custom component where I'm in control of the result in Java and don't need any CSS3 or other client side solution to have the functionality that I need.
But for all the other people that like playing with those things, you can see how easy it is to do it with PrimeFaces.

You can find an example demo here.

Thursday 26 July 2012

Trial with some Java generics

Introduction

It has been a while that I was able to post anything on this blog.  Due to various reasons, I didn't had any time to post an entry.
But things are slowly changing again, in the positive direction, and thus I found some time to create the following entry.  However, it is slightly off topic because it is not directly related to JSF or JEE but has to do with Java generics.

In the project, I needed the current date (system date) but in various 'formats', as a String, a java.util.Date and org.joda.time.LocalDate version. And I didn't want to use a method that returned the current date in the JodaTime version and call utility methods to convert it in the other formats if I needed them.  I went for the elegant solution like this.
 
String today = DateUtil.today();

Date todayAsDate = DateUtil.today();

Type erasure


I thought the solution was easy, I should have know that this kind of problem can't be solved, and created the following method
 
public static T today() {

   T result = null;

   // Logic goes here 

   return result; 

}

But the problem is that there is no way at runtime to determine what the return type should be. I started with reflection and used the method getGenericReturnType(). But other information than that the method should return Object and I defined something like T, wasn't available.
And then I realized that the kind of method I would like to write, isn't possible. Generics are used by the java compiler, but at runtime, there is no information about them available (there are some exceptions).  The processed is referred to as 'type erasure' and allowed backward binary compatible code.

So if we write code like this
        List myList = new ArrayList();
        myList.add("test");
        String value = myList.get(0);

The compiler converts it to this pre-5 compatible version
        List myList = new ArrayList();

        myList.add("test");

        String value = (String) myList.get(0);

And in the mean time, it is able to verify if we don't add anything else then a string to the collection.

Solution


I had to define a parameter which can be used to determine the return type like this
public static T today(Class returnType) {

   T result = null;

   // Logic goes here

   return result; 

}

This results in more code to type, but still quit elegant and type safe.
So something like
 
long time = DateUtil.today(Long.class);

won't compile.

On the other hand, using the class parameter leads to some ugly if statements which can be avoided by defining an Enum. But then we loose the type safety again and we need to introduce casting again.

Conclusion


In many situation, I love the possibilities that generics can offer.  And I don't know the impact of course, but having the extra generics information at runtime, maybe only when a compiler argument is specified, could be very handy in this situation.

Friday 13 January 2012

PrimeFaces 3 on non CSS3 compliant browsers

PrimeFaces 3

PrimeFaces 3, final release at the beginning of this year, is using CSS3 features to have some nice features and functionality.  And although there is a fair amount of CSS3 in the latest versions of the browser, also in IE9, their are a lot of people that uses a browser which isn’t capable of handling these nice things like rounded corners.
And for most of the widgets, like input field, it is no problem for the end user that he doesn’t have a rounded corner.  But for some, like a radio button, it is confusing that the user sees a rectangular shape instead of the, for him familiar, circle.
As an example, go to the showcase of PrimeFaces and look how the radio buttons are displayed.  Do you see a circle, then you have a CSS3 compliant (at least for the rounded corners feature) browser.  For those that have Internet Explorer 9, they can see how it is displayed for users having IE7 or IE8.  Go to the developers tools (or press F12) and select there the option ‘Browser mode: IE7’. The radio buttons become squared and I can understand the reaction of the end user that filed an issue on my last project.

Find a solution

On the internet, there are plenty solutions that provide you the possibility to have something like rounded corners in Internet Explorer 8 or older. You can split them up in 2 groups.

JavaScript

Here you have to include a JavaScript on your page and in the windows.onload function you have to pass the id’s of the elements that you like to decorate with a rounded corner. The problem with this approach, in combination with PrimeFaces, is that the DOM elements that are responsible for the presentation don’t contain an id attribute.  (Yes, there isn’t any input tag for the radio button so that it can be made styleable)

<div class="ui-radiobutton-box ui-widget ui-corner-all ui-radiobutton-relative ui-state-default">
   <span class="ui-radiobutton-icon"></span>
</div>

VML


The other solution is based on Vector Markup Language (or VML in short), a specification of Microsoft and others that lost the battle against SVG.  However, it was integrated in some of Microsoft products, like the browser.  With VML, it is possible to have rounded corners and a good site where everything is explained, with the inevitable pitfalls, is here.

So I added the script and updated the css file of the project to include the property behaviour in the style classes .ui-radiobutton .ui-radiobutton-box.  It worked like a charm on my computer (emulating IE7 with the help of the developer tools) and on a lot of the computers of other testers. But on another machine it crashed IE completely. Since it isn’t a reliable solution for a public website, I had to find something else.

Adapt skinning


Since PrimeFaces is using themes, there had to be a solution to fix the problem that way.  If I can just place the image of radio button on the area where the user expects it, there couldn’t be any problem like the VML not supported or browser incompatibilities.

And after trying a few scenarios, I’m not a css expert you know, I came to a solution which is quit simple.  I even didn’t need two images, one for the selected and one for the deselected situation.  This is what I added to the css file of the project.

.ui-radiobutton-box {
    background: url("../javax.faces.resource/radio_button.png.jsf?ln=images") no-repeat !important;
    border-style: none !important;
}

.ui-radiobutton .ui-radiobutton-box {
    width: 18px !important;
    height: 18px !important;
}

Some words of explanation:
  • All the properties need the !important marker to overrule the values that comes from the theme css file.

  • The background property defines the image that needs to be displayed.  I’m using the JSF resource notation to reference the image.

  • The border style is there to remove the square of the div element.

  • The size is maybe strange at first glance. The original size of the div element is 16 and then you have to add the border size (1 pixel) to it.  The image contains the complete radio button and needs to be 18 pixels wide.

And to my surprise, the default behaviour of PrimeFaces was providing me a dot in the center of the circle when the radio button is selected.

The easiest way to create the image is to take a snapshot of the screen area in a browser that is capable of rendering CSS3 rounded corners.

Disadvantage


The solution described above has a one major disadvantage, it isn’t compatible with the theme support.  To formulate it maybe a bit more correct, whenever you change the theme, you have to change the image that is used for the radio button whenever you want the background colour to match with the rest of the colours in the PrimeFaces theme.

Conclusion


Since the PrimeFaces 3 JSF component library uses CSS3 features, the representation on browsers that doesn’t support it, like IE7 and IE8, can be a little bit awkward.  A solution for the squared representation of radio buttons can be found in this text.  I uploaded also a test project on Google code for those that want to play with it.

Friday 6 January 2012

CODI on Oracle WebLogic server 12c

Introduction

Oracle released recently their EE6 compliant version of the WebLogic server. It is a full EE6 profile, so everything you need is at your disposal.  Adam Bien did a smoke test and I made a small demo application where some CDI beans are defined inside a jar file placed in the WEB-INF\lib directory of the war file.
All these tests passed so we are ready to test some real world like application.  Just as JSF is an open system (it is build with extensibility in mind), CDI (Contexts and dependency injection, JSR-299) adhere to the same philosophy. And thus any real world application should use one of the extensions that make the life of the developer easy.
One of the popular CDI extensions is Apache MyFaces CODI, which brings you some goodies that you can use in your project.  You can read about the project on the wiki page.

 

Testing CODI

Testing CODI was done with the scope testing program that you can find here. I made the required adjustments in dependency scopes so that it works on any EE6 server. After deploying it on the Oracle WebLogic Server, I received the following error:
java.lang.IllegalStateException: No bean found for type:
org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig at
org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils.getOrCreateBeanByClass(CodiUtils.java:198)
Apparently this kind of error occurred also on older Glassfish v3 versions. So someone posting this issue on the mailing list received a solution very rapidly.

 

How to package a CODI application for WebLogic 12c?

So I tried the suggestions in the mailing list and the scope testing program works, except for one small issue. And it is not related to WebLogic only, in fact all containers running on Weld have the same problem. A method annotated with @PostConstruct isn’t executed when it is defined on a method in a super class of a bean with a custom scope.
This is the contents of the pom.xml file:
<dependency>
    <groupId>org.apache.myfaces.extensions.cdi.bundles</groupId>
    <artifactId>myfaces-extcdi-bundle-jsf20</artifactId>
    <version>${myfaces_codi.version}</version>
    <scope>provided</scope>
</dependency>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>unpack-codi</id>
            <phase>process-test-resources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
            <configuration>
               <includeGroupIds>org.apache.myfaces.extensions.cdi.bundles</includeGroupIds>
                <includeArtifactIds>myfaces-extcdi-bundle-jsf20</includeArtifactIds>
                <outputDirectory>
                    ${project.build.directory}/classes
                </outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>
Some words of explanation:

Defining the CODI dependency as provided, means that it isn’t included in the packaged war, but you can use the classes in you code.

The maven-dependency-plugin is used to unpack the contents of the CODI jar into the classes directory so that the required classes are available in the war file.

The last thing that needs to be done is to copy the contents of the beans.xml found in the CODI jar file, into the beans.xml file of your web application.

This way, you can use CODI, on the Oracle WebLogic Server 12c.

UPDATE: Seems that there is also a problem when the 'autodeploy' directory is used.  So for the moment only regular deployed WAR files can be used as described above.