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.