Archive for the 'CDI' Category

August 5th, 2017
11:22 am
Using Java EE/JSR-330 annotations like @Inject in Spring

Posted under CDI & Spring
Tags

I came across a Spring Boot app which clearly used Spring for its IOC (@Configuration classes defining Spring Beans with  @Bean)

The app also used @Inject/javax.inject which initially led me to think it was using CDI/Weld, i.e. was using 2 IOC frameworks.

However, Spring also supports the basic Java EE annotations via JSR-330. JS-299 is the full CDI/Weld spec, but there was robust debate about Spring taking on board the full JSR-330 spec, and in the end they just went for a small subset which became JSR-299.

This includes among other things @Inject, so this can be used as a synonym for @Autowired.

Adam Bien describes the difference between JSR-299 and JSR-330 very well in this post here.

This blog post by David Kessler describes and investigates the use of both in code very well.

No Comments »

February 21st, 2012
3:57 pm
CDI Interceptors not called on local call to service layer EJB method

Posted under CDI
Tags , ,

When a service layer EJB method is called locally from within the same class, any CDI interceptors on the method are not invoked. This is standard CDI behaviour, as interceptors are only designed to be called when a method is called from an external client.

I hit this issue when my OptimisticLockInterceptor (which converts OptimisticLockException to ChangeCollisionException) was not being called, and OptimisticLockExceptions where being propagated all the way up to the view layer -  Mantis issue 120 details this.

The solution to this is to ensure that any required interceptors are annotated on methods at the point of call from an external client. If they then call another EJB method locally, any interceptors on the second method will not be called, but this is not a problem if the first method is correctly annotated. If the second method is also used externally, then its interceptors will be correctly invoked.

No Comments »

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 31st, 2011
6:42 pm
Iterating CDI Bean Types

Posted under CDI
Tags , , ,

When developing plugin architectures with IOC, it is useful to be able to iterate over the available beans of a given type which are known to the IO container.

In CDI, this is easy to do, but it is not obvious how from the Weld documentation unless you do a bit of digging and searching.

This post here gives a sample application which does it. The crucial code snippet which does the business is here:-

private @Named @Produces ArrayList<String> wilsons = new ArrayList<String>();
@Inject
void initWilsonRacquets(@Any Instance<WilsonType> racquets) {
    for (WilsonType racquet : racquets) {
        wilsons.add(racquet.getWilsonRacquetType());
    }
}

The intance keyword (used with @Any) exposes an iterator which lets you iterate the available beans. In the above sample they are added to a collection, but you could equally call methods on them as you iterate if you don’t need to keep them.

The Weld documentation describes this on page 25, with the following sample fragment:-

@Inject
void initServices(@Any Instance<Service> services) {
    for (Service service: services) {
        service.init();
    }
}

No Comments »

May 31st, 2011
4:13 pm
Using CDI Conversation Scope

Posted under CDI
Tags , ,

This is an interesting  2 part article by Andy Gibson on how to use CDI conversations. Part 1 is here and Part 2 is here. Of particular interest is his discussion in part 2 about how to manage a collection of conversations and index them/return to them etc.

Another post here discusses the use of conversations and some custom reflection trickery to implement a generic CRUD application that only uses JSF view coding to implement a particular application.

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 »