Changing Annotations at Startup in CDI 2.0

Today’s CDI 2.0 topic is actually about features that have been in there for a long while, but that I don’t see much evidence of out in the wild.

A lot of people are used to injection as provided by Jersey.  This is implemented under the covers by the excellent little underappreciated HK2 project, not by CDI.

HK2 can do really neat things with annotations.  In today’s blog, I want to show you how I took an annotation that was being used by an HK2-based system to provide configuration injection and, using the sledgehammer of the CDI portable extension API, made it usable in a CDI project.

The annotation looks like this, more or less:

As you can see, it is a simple Qualifier annotation that can be applied to fields and parameters only.  It has a value element, which ends up being the name of a particular piece of configuration you want.

So you could see it being used like this:

private int frobnicationInterval;

Or like this:

public Frobnicator(@Config.Key("frobnicationInterval") final int frobnicationInterval) {
  this.frobnicationInterval = frobnicationInterval;

HK2 has a concept somewhat analogous to CDI’s producer.  While a CDI producer can be a method or a field, it can’t be a class.  HK2, on the other hand, defines only one kind of thing-that-can-make-other-things, and calls it a Factory.  Factory‘s provide method returns the thing it can make, and you annotate the provide method in much the same way as you do a CDI producer method.

Unless, of course, you’re working with this particular annotation, as its Target meta-annotation does not allow it to be placed on methods of any kind.

In the HK2 project I was looking at, then, the Factory in question behind this Config.Key annotation simply declared that it provides Object.  No qualifiers.  Hmm.

Now, to get a Factory to be treated as a Factory by HK2, you have to mark it as such, or otherwise instruct HK2 to treat it as a Factory.  Otherwise it’s just another object that happens to implement the Factory interface.  None of those markings or instructions were immediately apparent.

The other thing you can do, though, is define something called an InjectionResolver.  If you do that, then inside that class you can do whatever you like to resolve the given injection point.  As I looked at this project, I found one for Config.Key.  It delegated its work off to the Factory I found, and other various internal configuration engines and whatnot, and the end result is that any class inside this project could do something like the examples I showed above.

I thought I’d cobble together some CDI constructs to do the same thing.

I knew that I couldn’t make any use of managed beans, because of course int and String are not managed beans.  Short of really convoluted potential other solutions, obviously I’d need a producer method.  I would just need to make a producer method that returned Object and that is qualified by Confi

Oops.  The annotation doesn’t have ElementType.METHOD as one of the places listed where it can be used. So my producer method code won’t compile, because I can’t put the Config.Key annotation on it.

Off to the portable extension toolbox.

First, I wrote a private annotation (I named it Property) that looks like this:

This private annotation (an inner annotation) is solely for my bean-housing-the-producer-method’s use, and the use of the extension that installs it.

You’ll note it looks almost the same as Config.Key, but this time it has ElementType.METHOD in its Target annotation.  It also features the Nonbinding annotation applied to its value element, and the value element now has a default value of "".  We’ll talk about those things in a bit.

Then, for reasons to be clear in a bit, I wrote an AnnotationLiteral implementation for it:

The new Property annotation will let me write a producer method like this:

…now that I can use @Property on methods and not just on parameters and fields.

But who cares? No user code can use my new, private inner Property annotation!  So who the heck is ever going to cause this method to be invoked?

Enter portable extensions.  Now we need a portable extension that will search for injection points that feature @Config.Key and make them behave as though they were written with @Property instead.  Once we do that, then we have a linkage: the user’s code says that it wants a particular kind of Object to be injected—namely a @Config.Key-ish one—but we know that for our purposes this should be translated into a desire for a @Property-ish one, and that will be satisfied by the CDI typesafe resolution algorithm and this producer method will be invoked.

There is a container event for just this sort of thing.  It’s called ProcessInjectionPoint, and you can do things with it like this:

This (private!) method will be called on every injection point found by the container (or created by other portable extensions!).  You can restrict the types of points you’re interested in by using something other than wildcards, but this will do for our purposes.

Here, you can see that we ask the InjectionPoint directly for its qualifiers, and we effectively remove the Config.Key qualifier and replace it with an equivalent Property qualifier.

So under the covers it now looks like all client code is using Property, not Config.Key in its injection points.  Cool!

Let’s circle back to the producer method, now that we know it will be invoked.

In CDI, a producer method can take parameters.  If it does, then the parameters are supplied to it by the container as if the method had been marked with @Inject.  So our producer method is handed an InjectionPoint object and a BigCoConfigurationEngine object.  (Let’s pretend for the sake of this article that an instance of BigCoConfigurationEngine has already been found by the container.  We’ll just assume it’s there so will be successfully injected here.)

The InjectionPoint unsurprisingly represents the site of the injection that the producer method will be called upon to implement as needed (as determined by the scope, in our case Dependent).  You can get lots of useful things from it: the parameter or field being injected “into”, the class housing the injection point, and so on.

So we should be able to get the actual Property instance that caused our producer method to fire, and, using the value of its value element, ask the BigCoConfigurationEngine to get us the right configuration value.

There is one very important thing to note here.

There are a couple of “paths” to the information we would like.  Only one of them is valid.

The first path looks like an easy one: we could just call injectionPoint.getAnnotated(), and then call getAnnotation(Class) on it and pass it our Property class.

But we’ll get back no such annotation!  How can that be?  Didn’t our portable extension munge things at startup so that all Config.Key qualifiers got effectively replaced by Property qualifiers?

Yes, but on the injection point itself, not on the objects reachable from the injection point.

That gives us path #2, which is the right one, though it is more cumbersome.  We need to call injectionPoint.getQualifiers(), and then find the Property annotation in there.  That is, our portable extension affected the contents of the return value of the InjectionPoint::getQualifiers method, not the contents of the return value of injectionPoint.getAnnotated().getAnnotations().  Sit and think about that for a moment.  I’ll wait.

So our producer method ends up looking like this:

The takeaway for me here was: in your producer method, if you want to be maximally flexible and a good citizen of the CDI multiverse, make sure you investigate the InjectionPoint metadata itself as much as possible for information, not the Annotated instances reachable from it.

Starting CDI beans eagerly and portably

There are several web resources out there that describe how to get a CDI bean (usually ApplicationScoped) to be instantiated when the CDI container comes up.  Here’s an arbitrarily selected one from Dan Allen:

Let’s look at the extension immediately above.

The AfterDeploymentValidation event is the only event a portable extension can observe in a portable manner that indicates that the container is open for business. It is guaranteed to fire last in the dance that the container performs as it starts up.

In the extension above, then, you can see that it has saved off the beans it has discovered that have been annotated with a Startup annotation (which isn’t defined in the gist, so it could be javax.ejb.Startup or a Startup annotation that Dan has defined himself). Then, for these beans, it uses the BeanManager‘s getReference() method to get an actual Java object representing those beans.

So what’s the toString() call for?

The short answer is: this is the only method that could conceivably cause the container-managed client proxy that is the object reference here to call the actual constructor of the actual underlying object that the user and everyone else is actually interested in.

For more detail, let’s look at the specification, section 6.5.3, which concerns contextual references—the return value of the getReference() method above—and which reads in part:

If the bean has a normal scope [e.g. not Dependent or Singleton], then the contextual reference for the bean is a client proxy, as defined in Client proxies, created by the container, that implements the given bean type and all bean types of the bean which are Java interfaces.

OK, so whatever the getReference() method returns is a client proxy. That means it’s going to forward any method invocation it receives to the object that it’s proxying (known as the bean’s contextual instance. CDI containers try to be efficient, so that object may not have been created yet—the proxy, in other words, might be lazy. So here, the contextual reference returned is a contextual reference (a client proxy) of type Object, and the toString() invocation causes the contextual reference (client proxy) to realize that oh, hey, the underlying contextual instance of whatever bean this is doesn’t yet exist, and to therefore invoke the “real” constructor, so that the “real” object (the contextual instance) can return something from its toString() method.

As a happy side effect, the container is of course the one causing the instantiation of the “real” object, so it is going to perform dependency injection, invoke initializer methods, invoke any PostConstruct-annotated methods, and so on.  Presto: you have a portable way for your bean to be instantiated when the container comes up.

(Side note: toString() in particular is used because there is a little nugget at the bottom of the Client Proxies section of the specification that says, innocuously (emphasis mine):

The behavior of all methods declared by java.lang.Object, except for toString(), is undefined for a client proxy. Portable applications should not invoke any method declared by java.lang.Object, except for toString(), on a client proxy.

File that one away: among other things that might mean don’t put your CDI-managed objects in Maps or Collections, since doing so will use client proxy equals(Object) and hashCode() methods!)

So.  If you’re feeling like this whole thing is a bit of a steaming hack—you call toString(), and a whole lot of very sophisticated magic happens (!)—I can’t disagree.

Fortunately, there’s a better way.

Instead of the toString() hack above, you can do the same thing in the extension in a more sanctioned, more explicit manner.

The first thing to understand is: who is doing the actual creation?  If we can understand that, then we can understand how to do it eagerly and idiomatically.

The ultimate answer is: the bean itself, via the create() method it implements from the Contextual interface. So if you ever get a Bean in your hand (or any other Contextual), you can call create() on it all day long and get new instances (this should sound scary, because it is).  For example, suppose you have an ApplicationScoped-annotated bean in your hand in the form of a Bean object.  If you call create() on it three times, you will create three instances of this object, hopefully surprising and gently horrifying you. Those instances may be wrapped in proxies (for interception and such), but they won’t be wrapped in client proxies.  Don’t do this!

Still, scary or not, we’ve found the method that some part of the container somewhere at some point will invoke when a contextual instance is needed (to further wrap in a contextual reference). But obviously when you inject an ApplicationScoped-annotated bean into, say, three different locations in your code somewhere, everything behaves as though there’s only one instance, not three. So clearly the container is not running around rampantly calling create() every time it needs an object.  It’s acquiring them from somewhere, and having them created if necessary.

The container is actually calling a particular get() method on the bean’s associated Context, the machinery that implements its scope. This method’s contract basically says that the Context implementation should decide whether to return an existing contextual instance, or a new one. So you can see that the Context underlying application scope will (hopefully!) return the One True Instance™ of the bean in question, whereas the Context implementation underlying some other scope may create new instances each time.

OK, so what do we know?  Let’s step back.

So to eagerly instantiate beans at startup while respecting their scopes, we should follow this approach in the extension as well—we’ll do basically what a lazy contextual reference (client proxy) does, in other words, when a toString() method is invoked on it.  We’ll need to effectively ask the right Context for a contextual instance of the bean in question, creating it if necessary.  This also would allow for custom-scoped beans to be instantiated eagerly, provided of course that the Context backing the custom scope is actually active.

If you have a BeanManager handy, and a Bean object of a particular type (say Bean<Object>), then you can get the relevant Context quite easily:

final Context context = beanManager.getContext(bean.getScope());

Then you need a CreationalContext, the somewhat opaque object that assists the Context with creation, should the Context decide that creation is necessary:

final CreationalContext<Object> cc = beanManager.createCreationalContext(bean);

Finally, we can ask the Context for a contextual instance directly:

final Object contextualInstanceNotContextualReference = context.get(bean, cc);

Note, as the variable name makes clear, this is a contextual instance, not a contextual reference!  This is not a client proxy!  So you really don’t want to use it after this point.

So if you replace Dan’s line 19 above with these code snippets, you will eagerly instantiate beans at startup without relying on magic side effects.

CDI 2.0: Fun With Composition, Part 3

(Disclaimer: I work for Oracle doing Java EE architecture and other things, but none of my writings here or anywhere else on this site have anything to do with my day job there.  In short, as always, these are just the writings of a Java EE hacker using publicly available stuff.)

In the last post, we saw how you could write a portable extension that starts up a JAX-RS runtime after the CDI container is open for business.  (I recommend reading all the posts in this series, starting with the first one.)

Here’s the extension again:

For this extension to work, though, line 34 has to return a non-null HttpServer.  As you can see, there’s nothing in this extension that makes such a thing.  The extension is, fortunately, relatively fault-tolerant (or at least that’s the idea 😀), so if no such HttpServer is around, then the extension should just silently do nothing.

In CDI in general, you write things so that the supplying of an object you need is SEP (someone else’s problem).  That is, quite apart from the mechanics of injection and so on, the important part of dependency injection is that if you need something, you just presume that it will be handed to you.  So here we presume that somehow, some way, an HttpServer will be available in the CDI container.  If it turns out that no such object exists, well, OK, we just do no harm.

So how could an HttpServer get in to the container so that it would be picked up by this extension?  Well, it could be a bean itself.  Maybe we’ll get lucky?  But probably not, as the Javadoc shows.  Sure enough, although HttpServer has a zero argument constructor, and hence could be a CDI bean, there are no further injection points on it, and furthermore the Grizzly module of which it is a part does not feature a META-INF/beans.xml descriptor, suggesting, though not proving, that we’re not going to get lucky.  So HttpServer is technically speaking a valid CDI bean, but a pretty limited one if discovered or added programmatically to a CDI container as-is.

How else could it get in there?  Well, there could be a producer method.  This seems like a good way to go.  A producer method makes bean instances out of raw materials available in the CDI container.  That sounds like exactly what we want.  So let’s say that ServerCo, writes one to make an HttpServer using the features of the GrizzlyHttpServerFactory class present in Jersey.  Let’s say it looks like this, and, just for kicks, lives in a different jar file than the one that houses the portable extension:

Let’s look at line 46 above.  This is a producer method that creates an HttpServer if one is needed.  To do so, it requires a GrizzlyHttpContainer, but such a thing might not exist.  To express this kind of optional behavior, it requests that an Instance<GrizzlyHttpContainer> be supplied to it.  The CDI container will make such a thing available whether its underlying “payload” exists or not, so we can test things about it here.  See line 48: if the Instance is unsatisfied—that is, if there isn’t a GrizzlyHttpContainer in the CDI container anywhere, nor a means for one to be synthesized or manufactured—then we can return null here, and the portable extension we saw earlier will effectively quietly become one big no-op.

On the other hand, starting at line 51, if there is a GrizzlyHttpContainer we can work with, well, then, it’s a pretty simple matter to use it to construct a new HttpServer (line 57).

Very cool.  OK, so where does the GrizzlyHttpContainer come from?

That’s the purpose of the first producer method, that you can see at line 34.  That method says how a GrizzlyHttpContainer can be created, provided that someone supplies a object.  Obviously, if no such object is available in the CDI container then the method should effectively quietly do nothing, so you can see at lines 36 and 37 that’s what happens.

OK, so clearly the first producer method makes something that the second producer method needs.  And the first producer method works if there’s an Application.  And the portable extension consumes the output of the second producer method and uses it to start a server when the container comes up.

So where does the Application come from?

Let us turn back to our poor developer, who, you recall from my last post, was done.  She had written a JAX-RS application and a root resource class and—right at that point—wanted to be finished.  She simply wanted some magic to happen that would let her application start.  She didn’t want to write a main method.  She didn’t want to go start an application server and run some complicated deployment recipe.

Recall also that if you’re keeping track we have several notional jar files (or directory locations—classpath roots, really) that we’ve stuck in fictional corners.  We have:

  • A CDI 2.0 EDR2 implementation (like weld-se-core version 3.0.0.Alpha17 or later)
  • the developer’s classpath root, containing nothing but her Application subclass and her root resource class
  • ServerCo’s portable extension jar file described in Part 2
  • A classpath root that contains the boilerplate main class that brings a CDI container up and shuts it down, described in my first post
  • ServerCo’s jar file containing the producer methods noted above

What’s really neat is if you run this:

java -classpath /path/to/weld-se-core-3.0.0.Alpha17.jar:/path/to/weld-se-core/dependencies:/path/to/developer/code:/path/to/serverco/portable-extension-1.0.jar:/path/to/boilerplate/code:/path/to/serverco/producers-1.0.jar:/path/to/serverco/dependencies com.foobar.Main

…then I hope to have shown that you will get an HTTP endpoint up and running on localhost port 80 that runs our developer’s JAX-RS application.


CDI 2.0: Fun With Composition, Part 2

In my last post I laid the groundwork for a compositional approach to deploying applications in CDI 2.0.  The main method doesn’t need to do anything.  Portable extensions don’t need to know anything about the main method.  User code doesn’t need to know anything about portable extensions.

Recall that our developer has written the following standards-compliant JAX-RS application:

…and just wants to run it.  But she also wants to be done here, and doesn’t want to write a main method or depend in code on vendor-specific classes.  Also, because we are living in The Future™, she wants to avoid deploying to some application server by hand.

Enter portable extensions and composition.

First, recall our generic main method, parked over in a corner in a jar of its own:

Now let’s say ServerCo authors this nice little extension:

Ignoring the utility methods for a moment, at line 32 the extension is notified that the CDI container it’s a part of is now open for business.

At line 34, using the get() utility method (see line 65), it asks the container for an HttpServer instance, if there is one.

If indeed there is one, then it starts the server.

Control flows back to the main method.  Specifically, the main method now has an SeContainer in its hands.  It promptly, of course, does nothing, and so the container starts to shut down.

At line 54 above, the portable extension is notified that unless something else happens, the container is going to shut down.  It arranges for the server to stay up with the join() call on line 57, and until the server is interrupted or killed or otherwise stopped we will block here.

Look, a JAX-RS server that comes up as a side effect of a CDI container starting up!

But wait…at line 35…will that HttpServer ever be non-null?  Who put an HttpServer into the CDI container?  Did anyone?

No.  Not yet.

We’ll address that in the next post!

CDI 2.0: Fun With Composition, Part 1

(Disclaimer: I work for Oracle doing Java EE architecture and other things, but none of my writings here or anywhere else on this site have anything to do with my day job there.  In short, as always, these are just the writings of a Java EE hacker using publicly available stuff.)

So in my last post I was musing on the fact that a CDI SE application that appears to do nothing may do a great deal indeed.

Recall that you start a CDI container from Java SE like this:

Now let’s write a portable extension that is notified after the container is open for business:

This extension is not a CDI bean exactly.  It doesn’t have a scope (that’s a bit of a white lie, but substantially true).  It is created by the java.util.ServiceLoader mechanism once as part of container initialization.  That means it needs a no-argument constructor (see line 11) and an entry in its containing archive’s META-INF/services/javax.enterprise.inject.spi.Extension file that, in this case, looks like this:


So let’s mentally park com.serverco’s extension over in the corner in its own jar file, and the main method we outlined above over in the other corner in another jar file.

If we were to run that main method with a classpath consisting of both jar files, we would see:

*** container is open for business!

…on the console, even though neither the main method nor the extension inherently knew about each other.

That’s pretty neat.

Now, just for fun, let’s say our developer creates a simple, standard JAX-RS application (no Jersey, no RestEasy, just standards):

Let’s say now our developer wants to be done, right here, and in the abstract in some sense wants to just run this application right here, right now.

Well, she’s going to need some kind of container to do so.  She could package this thing up in a .war file and deploy it somewhere, but that is not The Future™, so instead she just wants to run this application.

Jersey, of course, is one implementation of the JAX-RS standard.  Our developer could embed Jersey’s recipe for starting an embedded Grizzly server in a main() method she writes, and…but she wanted to be done!  She doesn’t want to write a main method with this recipe in it:

Well, OK, someone else could write this main method, and accept her application as a command line argument…which is sort of like deploying, and that’s not The Future™ either.

It would be kind of cool if our developer’s application, when placed on a classpath with potentially other jar files, one of which contains a main method, another of which contains a server implementation, etc., just ran.

It would also be kind of cool if our developer could easily try switching from using Jersey to using RestEasy without really doing much.

CDI 2.0 as you’ve probably guessed makes this pretty simple.  Stay tuned for the next post.

CDI 2.0

(Disclaimer: I work for Oracle doing Java EE architecture and other things, but none of my writings here or anywhere else on this site have anything to do with my day job there.  In short, as always, these are just the writings of a Java EE hacker using publicly available stuff.)

Have you taken a look at CDI 2.0 (Early Draft 2) yet?

You really should.

If you weren’t paying attention, CDI added a few interesting things that are on their way to being part of the official standard.

Perhaps the most notable is that CDI is no longer a parasite.

A parasite is a being that lives inside a host.  Just so, CDI in versions prior to 2.0 could be instantiated only in non-standardized manners.  That is, you would have to invoke Weld classes, or OpenWebBeans classes, to get a CDI environment up and running that your code could play in.

But no longer.  Now you can discover and instantiate a CDI container from Java SE in a vendor independent fashion.  Here’s what it looks like, and 80% of the following snippet is license text and documentation:

See line 61 above?  That gets an SeContainerInitializer.  From there, you call initialize(), and that gets you an SeContainer.  From there, you can get its BeanManager, and from there you can do anything you like.

But what’s really interesting is what is not going on on line 65 above.

On line 65 above, nothing is happening!  That means the container comes up (line 63), and when it has come up, it goes down again (the implicit close() called by the try-with-resources block, also at line 63).  Hmm; I guess this application doesn’t do anything.

Actually, you don’t know that.

In between coming up and going down, the container has found and created all the portable extensions on the classpath, if there were any, run through its startup lifecycle (which portable extensions can be involved in and affect), discovered all the bean archives on the classpath whether by itself or with the assistance of portable extensions and alerted (potentially) every bean that its ApplicationScoped scope has initialized.  Then depending on what injection any observing bean might perform, it may notify other beans about the availability of other scopes.

Lastly, it notifies the beans about the scopes going away, and then it notifies extensions that the container is about to go down.

In the meantime all the beans and portable extensions involved can fire events of any kind on the local event bus to notify each other of interesting things.

That’s an awful lot of valuable stuff for an application that doesn’t do anything.

It also means that you could have an executable that doesn’t presume anything about the work to be done, but still frees the developer from having to supply a main method, and provides an integration backplane for a whole host of technologies.

For example, the act of placing a JAX-RS application in a jar file could—depending on the portable extensions in play in any given CDI container environment—result in that JAX-RS application being deployed on an embedded server.

I’ll leave you with that before my next post.