February 13th, 2012
2:42 pm
CDI/Weld fails to inject a reference with nested parameterised types

Posted under CDI
Tags , , , ,

Weld 1.0 was failing with “WELD-001408 Injection point has unsatisfied dependencies” when nested parameterised types were present.

The referenced bean was correctly present and annotated.

I found that I could work around the problem by simplifying/removing some of the generics. This allowed the beans to inject, but also gave warnings about the use of raw types. For example:-

//Original code
    private @Inject TableCtrl<TreeNodePath<TaxonomyNode>, RowMetadata> selectionTable;

//was replaced with the following
    private @Inject TableCtrl<TreeNodePath, RowMetadata> selectionTable;

Attempts to use a CDI extension to find out more about what was happening did not reveal any more insight. This post discusses Weld performance and debugging and refers to a Stack Overflow post on the subject.

My solution to the problem (which I have also logged on Mantis) is  as follows :-

  1. Injecting the bean into a raw type does not suffer from the problem.
  2. I therefore inject into a temporary raw type, and cast that to the correct type.
  3. Wrapping this in a method annotated with @Inject neatly solves the problem, as the method can take the raw types as arguments, and cast to the correctly parameterised fields in the method.
  4. As all this is done in a method, warnings can be suppressed for the method. This is a tidy solution, as the method only has this specific purpose, and no other warnings in the class are incorrectly suppressed.
  5. This is far better than the original workaround which involved hacking the generics back to non nested parameterised types throughout – this meant hacking a number of classes. The current solution entirely isolates the issue and allows the desired generics to be correctly used everywhere.

An example of the correct generic declarations and the method used follows :-

public abstract class TreeBrowser<N extends TreeNode<T>, T extends Tree<N>, P extends TreeNodePath<N>>
                            implements Serializable, BreadcrumbCtrlEvent<N> {

    private CrumbComparator<N> crumbComparator;
    private BreadcrumbCtrl<N> breadcrumb;   
    private TableCtrl<N, RowMetadata> treeNodeTable;
    private TableCtrl<P, RowMetadataStatusMap> trayTable;

    @Inject
    @SuppressWarnings({"rawtypes", "unchecked"})
    void injectWeldUnsatisfiedGenericBeans(CrumbComparator crumbComparator, BreadcrumbCtrl breadcrumb,
                           TableCtrl treeNodeTable, TableCtrl trayTable) {
        this.crumbComparator = crumbComparator;
        this.breadcrumb = breadcrumb;
        this.treeNodeTable = treeNodeTable;
        this.trayTable = trayTable;
    }

 

This solved the problem.

No Comments »

May 24th, 2011
8:05 am
Weld Debugging and performance issues

Posted under CDI
Tags ,

It seems to be that Weld:-

  • has error/log messages which are not as good as Spring
  • has a lot of magic going on compared with, say, Guice, and so more info is needed about what is going on under the hood.
  • Turning logging up to full is obviously a starter. I haven’t done this yet – need to look at weld log messages to see what to turn up. Note that Weld uses sls4J NOT java.util.logging, and the levels are therefore different – need to look at how they are mapped/how to turn it up.

You can find out more about Weld’s decision making when injecting beans by writing some code to listen to various weld events. You have to use Weld’s extension mechanism to do this but it is apparently very easy. Details of it in this post here on stackoverflow.

There are also some comments around about slow weld performance and memory usage, during startup. Performance is being improved and Weld 1.1 has these fixes in, but you need Glassfish 3.1 to use it which also opens up all the issues of Mojarra client state saving problems etc. which have prevented me moving to it.

There is some negative CDI/Weld comment about on the net, but as with any toolset there is no silver bullet. Any choice will have some downsides and our priorities should and will determine the best choice. Even with these issues, I cannot see a justification to move to Spring as whilst it is mature and very popular, it is a closed standard which is very XML heavy and does not do typesafe injection. Guice is closer in style to CDI, but both Guice and Spring are JSR330 implementations and so are not portable. Weld uses JSR299/CDI and is therefore an open portable (and the most recent) standard, and is built on input from both the Spring and Guice teams. If we can suffer some early adopter pain, I feel Weld will end up being the best choice.

By the time performance becomes a serious issue for this project, Weld will have moved on and these issues should have improved. Note also that there is already (at least) one alternative JSR299 implementation – Apache OpenWebBeans. This means that we can move to another CDI implementation if we have to, with minimum pain, in the same way that if Mojarra screws us we still have Apache Myfaces as a choice.

No Comments »

February 2nd, 2011
7:56 pm
Primefaces Table Sorting–Common Gotchas

Posted under JSF
Tags , , , , , , , ,

Update 2/2/2011

According to this post here by Cagatay Civici, the Primefaces Project Leader, as at Primefaces 2.2M1, client side datatable is not supported and the dynamic attribute is deprecated from then on.
Seemingly it was becoming too hard to support all the table features on both client and server sides.
It is a shame that this was not documented better and more widely – the user manual still documents the dynamic attribute, and there are a number of posts about client side sorting (though in fairness they probably predate 2.2M1).

This behaviour exactly ties up with what I am seeing in my testing – the dynamic attribute does nothing, sortFunction is ignored, and all sorting is done via Ajax server side.

Original Post 2/2/2011

Having successfully got sorting working I was frustrated to find that a new simple example failed to work. Primefaces table sorting is pretty much transparent, requiring minimal effort and working out of the box. The lessons learned on this one are instructive so I summarise them below.

Details of Example and Problem

  1. The example fetched a list using JPA, stored the list in a view backing bean, then displayed it in a table with a sortable header.
  2. When the header was clicked, the up/down arrows were correctly displayed, but the data was not sorted – it was as if the request was ignored.
  3. It was not immediately obvious how the header click was handled – there was no obvious click event on the HTML element, and I could not see any Javascript running after a quick test with Firefox/Firebug. I gave up this line of attack but may look into it later as to how it all works. Some dynamic CSS pseudo classes/jQuery trickery may be involved.
  4. I was not certain as to whether the table was client side or server side/Ajax, even though it should have been client side by default. To diagnose the problem, I changed the value of the sortBy attribute in the column header to be an invalid bean property. The symptoms did not change, but an errors were logged in the Glassfish server log for each header click – “[#|2011-02-02T18:22:14.557+0000|SEVERE|glassfish3.0.1|org.primefaces.model.BeanPropertyComparator|_ThreadID=24;_ThreadName=Thread-1;|Error in sorting|#]”.
  5. This showed that the sort was being attempted but was failing due to the invalid property, which indicates that the sort was attempted server side. According to the Primefaces forum, for client side sorting, the sortBy property is not used as the displayed data is sorted.
  6. Interestingly, I would have expected Primefaces to use a client side table by default, but clearly it was not. Changing the dynamic property on the table tag to false explicitly had no effect and the behaviour was unchanged, so I will need to investigate client side tables further as for small data sets they are faster – I will update this post when I have done this.
  7. I turned on FINEST logging with Eclipselink in persistence.xml. Use <property name="eclipselink.logging.level" value="FINEST" /> to do this, and note that you need to bounce Glassfish to for a logging level change to be picked up. I noticed after this that the JPA query seemed to be rerunning very often, perhaps for every click of the sort header. This lead me to wonder if the backing bean was being recreated each time.

 

Cause and Solution

In the end, it was simply that I had not annotated the JSF backing bean as @SessionScoped (the example used CDI throughout, and did not use JSF managed beans). This meant the bean was request scoped by default, and was indeed being recreated – the sort was trying to do the correct thing, but the data was getting reloaded from the database in the original sort order each time!

Adding the correct annotation as above (and making a couple of the beans correctly implement serialisable to satisfy CDI/Weld) solved the problem.

This is a good example of where a problem cause is not immediately apparent from the symptoms.

Sample JSF page fragment showing the form containing the table

<h:form id="frmTest">   
    <util:themeSwitcher form="frmTest" outerStyle="clear: both; float: left; margin-bottom:20px;" innerStyleClass="ui-widget"/>
    <h:panelGroup layout="block" style="width:300px;">   
        <p:dataTable var="taxonomyNodes" value="#{taxonomyBrowser.taxonomyNodes}" scrollable="true"
             styleClass="clear #{fn:length(taxonomyBrowser.taxonomyNodes) lt 20 ? ‘ss-tableheader-scrolladjust-nobars’ : ‘ss-tableheader-scrolladjust-bars’}"
             height="460" > 
             <f:facet name="header">
                Client Side Sorting
             </f:facet>
             <p:column headerText="Category List"  sortBy="#{taxonomyNodes.text}">
                 <h:outputText value="#{taxonomyNodes.text}" />
             </p:column>           
        </p:dataTable>
    </h:panelGroup>
</h:form>

No Comments »

May 26th, 2010
9:35 pm
Notes on Using CDI/Weld

Posted under Java
Tags , , , ,

CDI stands for Context and Dependency Injection, and is the standard for Java EE 6, being an important part of the Java EE 6 stack. The reference implementation of CDI is JBoss Weld. Full details including documentation downloads for Weld, may be found here.

Here are some initial pointers/gotchas when starting out with CDI:-

  • Any bean which is @SessionScoped or @ConversationScoped must be serializable. If you do not obey this rule you get an error when trying to deploy your application. The easiest way to do this in Eclipse is to implement Serializable. This will give a warning about the need to declare serialVersionUID.Just right click the warning and pick quick fix. You will have the choice of a default serialVersionUID or a generated one. Normally you would want to use a generated one, which Eclipse will do automatically for you when you pick the option. (You can also use a Java command line tool to do it but there is no point as Eclipse is easier). This post here gives more details about SerialVersionUID and serialization.
  • Any bean which uses parameterised types (i.e. generics) in its interface must be declared as @Dependent, i.e. it is only used and referenced from one client bean and its lifetime is dependent on the lifetime of that client bean – it is created when the client bean is created, and destroyed when it is destroyed. If you do not obey this rule you get an error when trying to deploy your application. An example of this situation might be a generic table bean which returns a list of rows of a generic type <E>, e.g. @Dependent public class TableBean<E> implements Serializable. This makes sense if you think about it – if it returns a generic type, it cannot be instantiated in isolation as it is the creating client which determines the actual type returned. Remember in this regard that CDI performs type safe injection in order to pick up as many errors as possible at compile time. Therefore, taking an example of our table bean, a consequence of this is that the table bean cannot be referred to directly from a JSF page. This is not the issue that it might appear. In practice, the table bean will be created by a client backing bean for the page. For example, a UserCredentials.jsf page might contain several tables, each backed by a different TableBean. The page will have its own backing bean, for example UserCredentialsBean, which will hold the backing state for the whole page. When referring to a table on the JSF page, it will always be referred to via the page backing bean, for example userCredentials.rightTable.rows. This is what you would naturally do anyway, and referring to the dependent bean via a property of its ‘owning’ parent if perfectly correct and does not violate any CDI rules. Note that it is also perfectly correct to assign such a reference to a JSF table value attribute for use in the table, and to then use the shorthand name assigned to the var attribute to refer to the bean. This is also fine and does not break any rules.
  • When referencing an EJB from a JSF backing bean, you should always use CDI annotations rather than the older @EJB ones, as the CDI ones are typesafe and allow all the additional flexibility of CDI, such as alternatives for swapping in mock test versions of EJBs by adding settings in beans.xml. An example of injecting a local EJB into a backing bean might be  private @Inject SentryServiceLocal sentryService; assuming that SentryServiceLocal is the local interface for the EJB.
  • Given the choice, you should always use CDI for preference rather than a legacy feature. For example, JSF managed beans are still available for backwards compatibility in JSF (and even have some new features for JSF 2.0). However, you should ignore these and use CDI instead as it offers superior flexibility and type safety. Using CDI across the board gives additional benefits such as when grouping annotations using Stereotypes.

No Comments »

May 8th, 2010
2:32 pm
New Java Stack ideas – articles on CDI, Weld, JSF2.0, Java EE6, Spring

Posted under Java
Tags , , , , ,

This is a collection of useful notes and post/article references on ideas for a suitable new Java stack:-

http://blogs.sun.com/enterprisetechtips/entry/using_cdi_and_dependency_injection

http://stackoverflow.com/questions/2270379/differences-between-java-ee-6-cdi-implementations

http://docs.jboss.org/weld/reference/1.0.0/en-US/html/environments.html#d0e4910

http://stackoverflow.com/questions/2499323/jee6-vs-spring-3-stack

No Comments »