Forward CDI 2.0

CDI is probably one of most overlooked specification in Java EE, yet when version 1.0 was released 4 years ago it was presented as “Java EE extension point”. Technically it’s the case, but for all kind of reason some JSR didn’t adopt CDI totally to provide a more consistent experience in Java EE. Today the IT world is moving fast and after long years of heavy memory and process solution we’re going back to resource optimization with mobile or embedded platform. As CDI can leave outside Java EE, it could play an interesting role in this new approach. But before that it should evolve to be ready for this new challenge (and continue to pursue its growing role in Java EE as well) In this post I’ll try to share my ideas on how  CDI should evolve to meet it future rendez-vous. So I’ll start by exposing the new feature I’d like to see in CDI before exploring a more modular architecture for the spec to make it scalable from Raspberry  Pi to Huge cluster solutions.

Disclaimer : Since I’ll be leading CDI 2.0 specification (with Pete Muir) it’s important to stress that this post is not an official announcement about the content of the CDI 2.0 specification. It’s only my thought and doesn’t engage CDI Expert Group or Red Hat.

New features I’d like to have

Some of these features are already in the Expert Group pipeline, some were deferred during CDI 1.1 for CDI 2.0, some are standardisation of third party development (mainly Apache Deltaspike) and some are totally new. Anyway, most of these point are important to help third party project or JSR to get the best of CDI.

Java SE Bootstrapping

I don’t need to insist on this point. Today each implementation provide a way to bootstrap CDI in Java SE or in a poor server (Servlet only) environnement. Apache Deltaspike has a generic solution to do it. So it’s time that the CDI spec integrates this to be officially available in Java SE.

Container hot swap

Strong typed injection is great, but CDI is too strict on this in my opinion. To support dynamic JVM language, we should be able to trigger a BeanManager restart with runtime added bean. this could be done for instance by providing API for bootstrapping a new CDI container with augmented content. If the boot went well have more step to duplicate status and existing instance in the new container and garbage the old one. In case of error we could keep the existing BeanManager. A costly but very useful feature for advanced tools or app that could provide specific enhancement system (CMS, e-commerce platform, etc…).

CDI lite

As said in my introduction, there’s a shared wish to bring CDI to embedded devices like Raspberry pi, Arduino, Lego Mindstorms or Android. Today the massive uses of proxies in implementations prevent us to go in that direction.

Java Proxies were very useful in the 2000’s, but now they begin to be old fashioned and brings a lot of problem (huge stack trace, JVM optimization, High resource consumption, etc…). Right now CDI spec take for granted that proxies will be used in implementations.

For this reason, it could be a good solution to provide a subset of CDI specification with less magic and less weight. Let’s call it “CDI Lite” (like EJB Lite that were introduced in Java EE 6). This CDI subset would keep all the DI stuff but would probably get rid of all the Context part as well as Interceptor and Decorator.

But there are others tracks that could be explored to make CDI lighter without removing some of its features.

Bye bye Proxy, hello Annotation Processing and InvokeDynamic

This other way is to find solution to replace proxies by something else in CDI implementations. Right now we have two candidates :

  • Annotation Processing : process Annotation at compile time to produce the “magic” injection/injected/decorated code in a static way like it’s done in Dagger.
  • InvokeDynamic : Runtime linking could provide a proxy-like behavior with less drawbacks and probably more performances. Regarding this second approach I started to do some researches and hope provide a proof of concept soon.

XML config file

It’s time to provide this feature in the spec. There use to be extensions out there that provide this feature, but this is a core feature allowing bean registering and annotation overloading at deploy time and it should be in the spec. If CDI could become more and more present in the other spec, it could also be the beginning of a universal Java EE config file format !

Today, some framework like Apache Camel cannot use CDI because there is no config solution. Providing a solution on that point would ease CDI adoption.

Asynchronous event / action

At the vert.x and node.js era we definitely should support asynchronous treatment (and let’s dream : call back). This could be done By using concurrency spec. We would provide a way to support asynchronous call without using EJB and asynchronous event by adding a boolean asynchronous field in @Observes and, optionally, a handle on a callback

Support of @Startup

An easy feature to add : provide a way to have a CDI bean automatically instantiated after the initialization phase like we already have in EJB.

It’s a very common request by developers and it’s not very hard to provide.

Portable Extension SPI promotion / usage simplification

CDI Lifecycle

CDI 1.1 container initialization and Lifecycle. legend :
Grey –> events without hook
Green –> events occurring once
Blue –> events occurring for each element in a collection

Portable Extension is, in my opinion, the best feature in CDI. Off course IoC, events or context management are great but they weren’t new when introduced in CDI 1.0.

Portable extension is a complete CDI innovation, that added to Java EE DNA the possibility to be naturally extended without using proprietary tricks.

In my opinion it’s a pity that Portable Extension were not more promoted (CDI acronym doesn’t include any idea of their existence for instance) and were placed at the end of our specification document since a lot of projects or other specification could benefit from it.

My analyze is that this lack of communication is linked to the bunch of more or less complexe concepts (like the container initialization events shown in the right side schema) to understand before being able to deep dive into extension development. We should probably provide a higher simplified layer to get started with basic task on extension. Don’t misunderstand me, the existing mechanism is great and should be kept (with probably some enhancement) but we should provide helpers to ease extension creation. These helper could be :

  •  Standardization of Deltaspike AnnotatedTypeBuilder and BeanBuilder to ease new Beans creation
  • Helpers on introspection tools regarding types or annotation manipulation
  • Easier way to create new scopes or extend existing ones. We encourage other spec to extend lifecycle of existing scopes (like @RequestScoped for Websocket) but it’s nearly impossible to do it without going at the implementation level.

We should also bring a special attention to the first events (until AfterTypeDiscovery) in this initialization process, since they are CDI agnostic dealing only with type and annotation metadata modification. These could become part of a future Java EE configuration system.

Ordering event execution

So in CDI 1.1 decorator and interceptor are ordered thanks to @Priority. What about ordering events ? Using @Priority on @Observes doesn’t seem a good idea since this annotation comes from the interceptor package, but we could add an int priority field in @Observes.

No more segregation for Producers and Custom beans

Why produced bean or custom bean should be CDI second class citizen? I want to be able to decorate or use interceptor on my produced beans or at least have APIs that allow me to add this features to my produced beans.

Event scoping from package to server wide

Having the CDI event bus at a higher level in Java EE would allow scoping our event. Soone could decide if the event should stay in the current application, be restricted to the current module (in an EAR) even the current package or on the other side be broadcasted to all app listening to it.

Transient injection

When injecting dependent bean in a longer living bean, this injection is done once when the longer bean is instantiated. There are use cases (I’ve got one in Agorava) where I want my dependent bean to be re-injected each times it’s accessed. Today I have to write :


@Inject Instance<MyBean> myBeanInstances;
public Mybean getMyBean() { return myBeanInstances.get(); }

Tomorrow I’d like to write this :


@Inject @Transient MyBean myBean;

It’s mainly syntaxic sugar but make the code more easy to write and readable. We probably could find other example here of code simplification.

Have a more fluent programmatic lookup

The Instance<T> interface and the programmatic lookup are incredibly useful, but it could be very cumbersome to use especially when we have to deal with Qualifiers.

This could be eased by providing tools to generate qualifier literals  with Java 8 Type Annotations for instance.  And why not a query DSL ?

myBeanInstance.restrictedTo(BeanImp.class).withQualifier(new @MyQualifier("Binding") AnnotationLiteral<>(), new @MyOtherQualifier AnnotationLiteral<>()).select();

Wouldn’t it be more user friendly ?

Monitoring facility

Remember the great debug page in Seam 2 ? I’d like to have the same things or tools to easily build the same feature to monitor my beans and my scope. CDI does a lot of Magic and it could be nice to have tools to see all its trick and the cost of beans, context and other interceptor we deployed

Give me more modularity : a new architecture for CDI (and Java EE ?)

CDI Next ArchitectureA lot of JSR complained that CDI spec is too monolithic and that implementations are too heavy comparing to theirs (they don’t want to depend on something bigger). This and the lack of standard Java SE bootstrapping, are probably the 2 mains objection to go for a deep CDI integration in some spec. So we should provide a more modular approach while keeping the possibility to gather all the modules and have a consistent stack that we could use outside Java EE. In my ideal world the different JSR / Modules would be :

Container

This module store all the beans defined in the application. Providing as a standalone module brings the following features :

  • Provides a minimum api/impl for a client app that rely on JNDI to get Beans
  • Provides the possibility to add plugins to the container to support new kind of components (Servlet, JPA Entity, Guice or Spring beans for instance)
  • Prepare the CDI container to be the future universal Java EE container that we’re waiting for

Event bus

Events and observer pattern are great features of CDI spec. But they would be more useful if spec could use them without having to depend on all CDI.

We could imagine a new Java EE specification or a CDI module based on CDI event API to provide Java EE wide eventing model. We could imagine an API only relying on half a dozen classes (more if we add asynchronous treatment, ordering and event scoping) hat would do the Job.

Component Scanning & Extension engine

Today each specification does class scanning at boot time. In general the app server provides a way to group this scanning process in a proprietary way. By standardizing the scanning phase events and the meta-data manipulated during this scanning phase we could provide a consistent experience and a standard way to extend Java EE. CDI already provides most of this feature with its initialization mechanism which allow to “observe” all wished existing classes in deployment and modify meta-data of these classes (i.e. annotations) .

Imagine what you could do if the ProcessAnnotatedType event could be catch at the server level and allow you to put a “veto” on a given servlet or on a group of JPA entities? This feature lead us on the single container and the single configuration file path. A feature dreamt by a lot of developers.

Basic DI

This module would include all API related to simple injection (only pseudo-scope). So all @Inject, @Qualifier, Instance<>, @Producer, InjectionPoint and other Reflection stuff will be gathered in a light API. Probably what I called “CDI lite” in my previous part.

Context Management

Context is a nice feature of CDI but as everybody don’t need it, it should be put in a optional API package. This part will deal with all the normal scope context and complex life cycles.

Interceptor & Decorator

Today interceptors already have their own JSR. Adding decorator to the JSR would complete the interceptor JSR.

Conclusion : CDI needs you!

So, here’s my personal CDI wish list. You probably have yours (we collected your 3 CDI 2 wishes in december / january, and we intend to use them. If you didn’t send them, feel free to add them in comment of this article). I don’t know if all these point are good ideas (just read the comment to make your opinion). I don’t know if they are all doable (probably not). What I know is that we’ll need all help we can have to work on the future CDI 2.0. So if you want to be part of this adventure, stay tuned on CDI official website@cdispec twitter account (or mine) and this blog and give us your feedback on CDI ML or CDI IRC channel (#jsr346 on freenode). The coming months will be decisive regarding CDI (and Java EE) future.

  • Alberto Gori

    CDI lite: remember that a lite version of CDI already exists and is the JSR 330 specification (that provide @Inject and other annotations).
    AFAIK JSR 330 does not try to say anything about the context (scope) of a bean. Having another specification for DI, after CDI, JSR330, @EJB is not an option in my opinion.

    • http://www.next-presso.fr Antoine Sabot-Durand

      Hi Alberto. JSR 330 is not a lite version of CDI. For instance It doesn’t provide any mean to access the container/manager (that would allow to retrieve a Bean outside CDI / JSR 330). JSR 330 is a minimum spec, and if you check implementations (Spring, Guice, Dagger, Weld, OpenWebBeans) you’ll see that the JSR 330 part represents less than 10% of the whole framework.
      Now you’re right, a good solution for CDI lite would be to make JSR 330 evolve in a new version. I’ve been exploring this lead for the last 4 months but there’s little hope that this happens. Unfortunately people owning JSR 330 are not very pro Java EE and CDI (to be honest my first contact made me think that they don’t care about all this. That can give you an idea of the true value of JSR 330).
      Now my proposal is not to create another DI spec. It is to provide a subset of CDI in CDI spec like EJB provides a subset called EJB lite in EJB spec. So don’t be afraid, no new DI spec at the horizon ;).

  • Adil

    Great Ideas!! Love the Java SE Bootstraping idea, it definitely should be standardized.

    • http://www.next-presso.fr Antoine Sabot-Durand

      Thanks Adil. We missed that in CDI 1.1. The success of CDI used outside Java EE took us by surprise. It’s one of the first thing will correct in CDI 2.0

      • http://javaeeconfig.blogspot.ch/ Anatole Tresch

        Surprise? Automatic component wiring, no more XML, interceptors, decorators, stereotypes…. CDI rocks, and if you understand how it works (including portable extensions and more advanced concepts), it really rocks!

  • William Draï

    The CDI event bus has been almost ignored by everyone and could be the foundation of a very powerful node/vertx like programming model.
    A new separate spec would certainly make sense.

    • http://www.next-presso.fr Antoine Sabot-Durand

      Probably but without more resources I’m afraid it won’t be a new spec. Now who knows…

  • Lincoln Baxter III

    CDI Lite FTW!! Really interested to see what can be done with InvokeDynamic instead of Proxies. That could provide some very powerful performance optimizations.

    • http://www.next-presso.fr Antoine Sabot-Durand

      Thanks Lincoln for your feedback. On the performance side I’m not quite sure (it could but when you have JPA in your app, winning 2ms in CDI isn’t visible). The optimization will be more on the memory and CPU consumption side : leaving greedy proxy behind will allow us to use CDI in more constrained environnement. Now there’s a lot of work to do (half of it being convincing people to explore this idea unfortunately…)

  • Gunnar Morling

    Nice list, Antoine! Could you elaborate a bit on how you envision InvokeDynamic to be used? That seems very interesting (at least for those projects which can make the move to Java 7). Compile-time annotation processing a la dagger is also an interesting option, but naturally it doesn’t work for certain use cases (e.g. when you want to plug in “unknown” modules with event listeners etc. at deploy time).

    • http://www.next-presso.fr Antoine Sabot-Durand

      Thanks Gunnar. I plan to post more on the subject but not right now being caught by closing CDI 1.2 and start CDI 2.0. As you know Java EE 7 requires JDK 7 so implicitly CDI 1.1 (even if it runs on Java 6 AFAIK). Regarding CDI 2.0, I’d be surprise that we won’t switch to Java 8 in the implementation. So Indy is usable today. Have a look at my POC on the subject (even if it’s quite small for the moment) : https://github.com/antoinesd/weld-invokedynamic

  • sparty02

    Along the lines of xml based configuration, I often find myself (for better or worse) wanting to manually define interface/implementation bindings for CDI. Sometimes this just makes things a lot more transparent and predictable. On a related note, ambiguous dependencies are often frustrating too. I should be able to package up an artifact with 1-to-many implementations of an interface without having to tediously qualify each one. I know “alternatives” are a deploy time solution for this, but I would like a runtime solution. Maybe I have the ability to annotate my producer method to declare that it overrides/takes precedence over any other potential bindings? Similarly, I sometimes find myself wanting a “module” system with a fluent binding API like Guice has so that I can create different sets of bindings (that maybe I can also choose between at runtime). Compile time processing like Dagger has could make this very performant.

    Related to the CDI lite item, it may be nice to see that evolved out of JSR 330. It seems awkward that JSR 330 only defines annotations for DI. As mentioned in a previous comment, there really needs to be an accompanying API to complete a lightweight DI engine…..and can we get those annotations baked into the “standard annotations” that come with Java SE? It’s annoying to have to rely on a separate jar for something standardized and so trivial as a few annotations!

    • http://javaeeconfig.blogspot.ch/ Anatole Tresch

      +1 for being able to do runtime resolution of beans being injected. In the bank we have use cases where certain components are reimplemented in different flavors various times. Solutions that inherit from the more lower levels will then not see the more enriched variants from higher level APIs built based on the lower ones. Alternatives basically work, but it requires that these are configured explicitly, whereas in our case an implicit priority resolution mechanism (using the @Priority annotation) would be great. We had solved this issue by an according portable extension (+1 for extensions, its one of the best and most flexible features in CDI), but it would be nice if there is support from the spec out of the box. Along that it would also be nive to have an @Optional annotation, so I can depend on a component, that may be not satisfied. Today I have to inject Instance to achieve this. Without @Optional the injection point is defined to be required (as before).

  • http://javaeeconfig.blogspot.ch/ Anatole Tresch

    Hi Antoine, the list matches quite good with mine ;-) Also we have implemented some kind of feature reduced (no proxies, only wiring) small CDI container within Credit Suisse as part of the central frameworks. About 1500 LOC only overall ;-), so looking forward to your work. In that area it would be important that we can combine a CDI container, e.g. running within the system context of an application server, with the “normal CDI containers running on ear/war level. With current weblogic this was not possible (and this was the reason, we leveraged our own container with CDI)…

    • http://www.next-presso.fr Antoine Sabot-Durand

      Thank you Anatole. The question is : would you be interested in a CDI “part” providing only type and annotation manipulation to build Java Config on top of it by using what is described in our spec here: http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#alternative_metadata_sources.
      Why I’m asking this ? Because I was thinking mainly at Java Config when I imagined this and I’ll have to work hard to make it real. So if you’re not interested, the issues are not the same for me but if you are your support is most welcome.

      • http://javaeeconfig.blogspot.ch/ Anatole Tresch

        Hi Antoine. I tend to say the config JSR will not define how its implementation will be built, but rather define the Java usage and accessor API. Also since time will be short, such a dependency may imply risk also for the config JSR). Nevertheless using a small context-free container would greatly simplify the development of the configuration JSR’s RI, but I am not sure it will be a precondition, which the config JSR API/spec will be built on top.
        So from the configuration JSR point’s of view, it would be more important, to have some sort of SPI to control portable extensions to be loaded/not loaded and everything else that can be configured within beans.xml). With the additional SPIs already in place this results already in full control about CDI ;-). This SPI/extension functionality then can be implemented/weired by the configuration JSR. This would keep CDI 2.0 independent oh the config JSR, but enables it to be adaptable/configurable by the config JSR, but also by something else.
        Nevertheless having a small reduced CDI container subset would be nice, especially, when it can easily started and used independent of the CDI container instances running within ear/war contexts.
        WDYT?

        • http://www.next-presso.fr Antoine Sabot-Durand

          My opinion is not totally objective here, but I think we should really think about integrating spec in Java EE 8. In CDI we have all we need to configure component using CDI, there was a CDI extension (Seam Config) that was a real proof of concept of this mechanism.
          From what I understand you have 2 choices :

          1) work independently on Java config plus ask all spec to expose SPI to ease your job. CDI is one of the spec that has the best SPI around and yet we don’t have what you need (and to be honest it’s not in our top 10 priorities). So My guess is that you’ll have a lot of work to ask each spec to do this exposure.

          2) rely on a small CDI API subset (that can be implemented in a simple manner for environment without full CDI) to do the same plus join us to convince other spec to use CDI for integration (we already have some candidate in EE 7) or at least this small API set for their type and meta-data discovery.

          Again not totally objective here, but 2 looks easier, avoid adding a new layer in Java EE, promote the containers unification expected by a lot of people (yea CDI is the best candidate to unify these containers.
          I may miss something here, but I really think it’s worth thinking about it…

          • http://javaeeconfig.blogspot.ch/ Anatole Tresch

            If we would be able to establish CDI/EE in a way, so we would use this mechnism as a base for doing the basic component wiring in the EE context (including shared aspects, administrative resources, security, …), I am definitive with you. Fully agree, this would be the most elegant way doing integration. Java configuration would then seemlessly integrate into this CDI based EE runtime environment ;-)
            Wheather variant 1 or 2 is easier to achieve – well – I am not that sure, In both cases “something” must be defined by the other JSRs (either a new SPI, or an alternate mechanism for locating their configuration, where config services would provide (already existing) deployment descriptors). My personal feeling is that also the EE8 umbrella JSR group should be involved for coordination, and I am also glad, that with Laird Nelson, a well known Glassfish engineer from Oracle will join me in getting these things done ;-)

          • http://www.next-presso.fr Antoine Sabot-Durand

            I totally agree, especially on EE 8 role. I’d just add that it would be a good idea to have community feedback on this point : we could be both wrong on users expectation ;).

          • http://javaeeconfig.blogspot.ch/ Anatole Tresch

            Definitively. I also currently have some discussions ongoing with Oracle about the scope of EE configuration. I hope we can also here continue that discussions with the community soon…

  • http://javaeeconfig.blogspot.ch/ Anatole Tresch

    Transient injection would also be very interesting for Java Configuration. E.g. I want always have the latest Configuration instance visible. Configuration itself may be defined as immutable type. The same would also be true, for injecting configuration values as Strings…
    And if one would have the possibility to observe such a reinjection (and detect changes), we would also have a nice hook for implementing configuration change events tailored especially for the beans affected by a change ;-)

  • Eleftheria Kiourtzoglou

    Hello Mr Durand,

    Nice blog! Is there an email address I can contact you in private?

    Thanks,

    Eleftheria Kiourtzoglou

    Head of Editorial Team @ Java Code Geeks

    email: eleftheria[dot]kiourtzoglou[at]javacodegeeks[dot]com