Category Archives: Maven

Components and Environments

I am playing around with the concepts of components and environments in my microbean experiments.

The fundamental idea behind microbean is that with CDI 2.0 every last piece of your application can be its own self-contained artifact (including the main class with its main() method).  Each such artifact is a CDI bean archive.  When you put them all together on the classpath and run java org.microbean.main.Main, then your application works.  This might include running servers, deploying things, and so on, but it’s all loosely coupled and tiny. It is the act of bringing these archives together—drawing a lasso around them with a CLASSPATH—that constitutes deployment.

As we’ve seen, CDI has the notion of a bean archive, but it doesn’t really have a notion of a group of bean archives.  I am going to use the wonderfully overloaded term component to describe this concept.

These components might need some other facilities provided by various portable extensions.  There is a hazy way in which a group of portable extensions providing services is different from a group of bean archives providing business logic.  I’ll call this aggregation an environment.

With these provisional terms in place, we can thus say that components run in environments.  We can also say that environments support components.

Then the act of deploying a microbean application becomes: pick one or more environments and one or more components and put them on the classpath, and then run java org.microbean.main.Main (or any other main class that simply starts up a CDI SE container and shuts it down; this just happens to be a convenient prefabricated one).

How could we represent these components?  On disk, we don’t really want to represent them at all.  A component as used here is a notional construct, after all: it’s a bunch of jars that belong together in some way.  For management purposes, however, representing them in Maven pom.xml files of a particular kind looks like a good way to go.

This also seems to be a good way to represent environments as well.

Maven’s pom.xml file and the dependency graph it implies is one of the most misunderstood artifacts in all of Java software engineering.  Most developers know that it describes a project and its dependencies, but did you know you can include a non-jar project pom.xml file (an artifact of type pom) as a dependency itself, thus effectively pulling in (transitively) its dependencies?  This can lead to version surprises, but did you know that a pom.xml‘s section can be used to lock down the version of a given artifact, whether it appears directly or transitively as a dependency? Finally, to complete the puzzle, did you know that a pom.xml can, itself, appear in its own <dependencyManagement> section, thus offering a way to lock its own version down as well as those of its dependencies?

These features mean that we can define both components and environments as artifacts of type pom.  I’ll be exploring these concepts over the next few blog posts.

MicroBean Launcher

This is the eleventh of a series of posts on some of the personal projects I’ve been working on.  As I hope you’ll see, they all fit together.  The previous post covered MicroBean Commons CLI.

This post covers MicroBean Launcher.  Its website is here, its source code is here and its binaries are available from Maven Central.

MicroBean Launcher lets you run a Java SE CDI 2.0 application from the command line by specifying Maven artifact coordinates to other bean archives, transitively resolving them and their dependencies, using MicroBean Maven CDI, to your local Maven repository.

To install MicroBean Launcher, place it (and its minimal dependencies) on your classpath.

Here is an example of its usage, assuming it and its dependencies are on your classpath already:

java org.microbean.launcher.main.Main --artifactPath com.foobar:frobnicator:1.0,com.foobar:caturgiator:2.0

This command will download, if necessary, com.foobar‘s frobnicator jar artifact at version 1.0 and com.foobar‘s caturgiator jar artifact at version 2.0.  These files and their transitive compile- and runtime-scoped dependencies will be placed in the current user’s local Maven repository (~/.m2/repository by default, but the user’s ~/.m2/settings.xml file, which can dictate where the local repository is, is honored).  (If the artifacts already exist, then no download happens.)  A classpath will be built out of all of these artifacts and effectively appended to the current classpath, and MicroBean Main will be invoked.

Why is this useful?  For one, specifying a classpath can now be done in terms of Maven artifact coordinates instead of local filesystem references.  Because MicroBean Maven CDI is in charge of dependency resolution using Maven’s own resolution machinery under the covers, you don’t need to be aware of whether the artifacts in question were downloaded or already present.

But more than this, note that in the last ten blog posts the installation instructions have been the same: you place whatever bean archive is being described on your classpath.  This is one of the nice things about CDI: CDI archives are loosely coupled modules that can be discovered.

This means you can compose a Java SE CDI 2.0 application together by simply referring to Maven artifacts.

Specifically, assuming you have MicroBean Launcher and its dependencies on your CLASSPATH, if you write, say, a JAX-RS Application and a root resource class that it exposes, and place them on your classpath, then you can run that application immediately, downloading only what you need and only what you don’t already have, by running a command line similar to the following:

java org.microbean.launcher.main.Main --artifactPath org.microbean:microbean-jersey-container-grizzly2-http-cdi-extension,org.microbean:microbean-jersey-container-grizzly2-http-cdi,org.microbean:microbean-grizzly-http-server-cdi

Note in particular that your application remains standards-compliant, and you selected the server you wanted to use to run it dynamically from the command line.  You wrote only the code you needed to and none other.

Note that the second time you run this all of the artifacts will already be present on your system.

These are early days for these personal projects and I’ll have plenty more to say about them in the future.  Thanks for reading!

MicroBean Maven CDI

This is the ninth of a series of posts on some of the personal projects I’ve been working on.  As I hope you’ll see, they all fit together.  The previous post covered MicroBean Jersey Container Grizzly2 HTTP CDI Extension.  The next post covers MicroBean Commons CLI.

This post covers MicroBean Maven CDI.  Its website is here, its source code is here and its binaries are available from Maven Central.

MicroBean Maven CDI adapts the inner workings of the Maven Artifact Resolver project so that it can be exposed in a CDI 2.0 environment.

To install MicroBean Maven CDI, place it on your classpath.

The Maven Artifact Resolver project is the Maven-as-build-tool-independent “guts” inside of Maven responsible for transitive dependency resolution and management.  (I’ve written before on this topic.)  MicroBean Maven CDI makes this tooling available inside a CDI 2.0 environment (including Java SE CDI 2.0 applications), along with the common Maven conventions of user-specific settings.xml files and local Maven repositories.  Any interesting magic that it performs is really confined to the translation of Plexus annotations such as Component and Requirement to CDI injection points, which it does by virtue of the power of the CDI portable extension SPI.

There are many ways this could be useful.  Consider—from within your CDI bean—taking in a Maven-style groupId:artifactId:version String identifier and having it resolve to a local file automatically if that file is not already present in exactly the same way that Maven resolves it (jokes about “downloading the Internet” are hereby routed to /dev/null, as usually these indicate an ignorance of the (well-documented) updatePolicy element).  As we’ll see, there are even more powerful things you can do with these capabilities.  I’ve touched on some of them earlier.

In the next post, we’ll touch on the integration of the Apache Commons CLI project with CDI 2.0 by way of MicroBean Commons CLI.

A Blog Post A Day

I’ve got some interesting things cooking in the personal projects department related to Java, CDI 2.0, configuration and Maven and I am going to blog about them with (I hope!) a post (or several!) a day for a little bit.

We’ll start with configuration.

You may recall my earlier posts on the subject.

Now my ramblings have code behind them!  See MicroBean Configuration API, MicroBean Configuration and MicroBean Configuration CDI.

MicroBean Configuration API is the Java API that defines an API around my notion of configuration coordinates.

MicroBean Configuration is a Java SE implementation of that API.

MicroBean Configuration CDI is a CDI extension that uses MicroBean Configuration to expose configuration values to CDI environments.

I’ll have more to say about these (early days!) projects and others over the coming days.  Thanks for reading.

Calling Maven Artifact Resolver From Within CDI 2.0

So I’ve been continuing to play with my CDI-and-linking idea, and central to it is the ability to locate CDI “modules” Out There In The World™.  The world, in this case, is Maven Central.  Well, or perhaps a local mirror of it.  Or maybe your employer’s private Nexus repository fronting it.  Oh jeez, we’re going to have to really use Maven’s innards to do this, aren’t we?

As noted earlier, even just figuring out what innards to use is hard.  So I figured out that the project formerly known as Æther, Maven Artifact Resolver, whose artifact identifier is maven-resolver, is the one to grab.

Then, upon receiving it and opening it up, I realized that the whole thing is driven by Guice—or, if you aren’t into that sort of thing, by a homegrown service locator (which itself is a service, which leads to all sorts of other Jamie Zawinski-esque questions).

The only recipes left over are from the old Æther days and require a bit of squinting to make work.  They are also staggeringly complicated.  Here’s a gist that downloads the (arbitrarily selected) org.microbean:microbean-configuration-cdi:0.1.0 artifact and its transitive, compile-scoped dependencies, taking into account local repositories, the user’s Maven ~/.m2/settings.xml file, active Maven profiles and other things that we all take for granted:

That seems like an awful lot of work to have to do just to get some stuff over the wire.  It also uses the cheesy homegrown service locator which as we all know is not The Future™.

For my purposes, I wanted to junk the service locator and run this from within a CDI 2.0 environment, both because it would be cool and dangerous and unexpected, and because the whole library was written assuming dependency injection in the first place.

So I wrote a portable extension that basically does the job that the cheesy homegrown service locator does, but deferring all the wiring and validation work to CDI, where it belongs.

As if this whole thing weren’t hairy enough already, a good number of the components involved are Plexus components.  Plexus was a dependency injection framework and container from a ways back now that also had a notion of what constituted beans and injection points.  They called them components and requirements.

So a good portion of some of the internal Maven objects are annotated with Component and Requirement.  These correspond roughly—very, very roughly—to bean-defining annotations and injection points, respectively.

So I wrote two portable extension methods.  One uses the role element from Component to figure out what kind of Typed annotation to add to Plexus components.  The other turns a Requirement annotation with a hint into a valid CDI injection point with an additional qualifier.

(Along the way, these uncovered MNG-6190, which indicates that not very many people are even using the Maven Artifact Resolver project in any way, or at least not from within a dependency injection container, which is, of course, how it is designed to be used.  That’s a shame, because although it is overengineered and fiddly to the point of being virtually inscrutable, it is, as a result, perhaps, quite powerful.)

Then the rest of the effort was split between finding the right types to add into the CDI container, and figuring out how to adapt certain Guice-ish conventions to the CDI world.

The end result is that the huge snarling gist above gets whittled down to five or so lines of code, with CDI doing the scope management and wiring for you.

This should mean that you can now relatively easily incorporate the guts of Maven into your CDI applications for the purposes of downloading and resolving artifacts on demand.  See the microbean-maven-cdi project for more information.  Thanks for reading.

Maven and the Project Formerly Known As Æther

I am hacking and exploring my ideas around CDI and linking and part of whatever that might become will be Maven artifact resolution.

If, like me, you’ve been working with Maven since the 1.0 days (!), you may be amused by the long, tortured path the dependency resolution machine at its core has taken over the years.

First, there was Maven artifact resolution baked into the core.

Then Jason decided that it might be better if this were broken off into its own project.  So it became Sonatype Æther and rapidly grew to incorporate every feature under the sun except an email client.  It got transferred to Sonatype which was the company he was running at the time.

Then people got very enamored of Eclipse in general, and so Æther, without any changes, got moved to the Eclipse Foundation.  Then the package names changed and a million trillion confused developers tried to figure things out on StackOverflow.

Then it turned out that no one other than Maven and maybe some of Jason’s companies’ work was using Æther in either Sonatype or Eclipse form, so Eclipse Æther has just recently been—wait for it—folded back into Maven.  Of course, the Eclipse Æther page doesn’t (seem to?) mention this, and if you try to go to its documentation page then at least as of this writing you get a 500 error.  If you hunt a little bit harder, you find another related page that finally tells you the whole thing has been archived.

So anytime you see the word Æther you should now think Maven Artifact Resolver.

But make sure that you don’t therefore think that the name of the actual Maven artifact representing this project is maven-artifact-resolver, because that is the old artifact embodying the 2009 version of Maven’s dependency resolution code!  The new artifact name for the Maven Artifact Resolver project is simply maven-resolver.  Still with me?

Fine. So you’ve navigated all this and now you want to work with Maven Artifact Resolver (maven-resolver), the project formerly known as Some Kind of Æther.

If, like me, you want to use the machinery outside of Maven proper, then you are probably conditioned, like me, to look for some sort of API artifact. Sure enough, there is one.  (Note that for all the history I’ve covered above, the package names confusingly still start with org.eclipse.aether.)

Now you need to know what implementation to back this with. This is not as straightforward as it seems. The Maven project page teases you with a few hints, but it turns out that merely using these various other Maven projects probably won’t get you where you want to go, which in most cases is probably a Maven-like experience (reading from .m2/settings.xml files, being able to work with local repositories, etc. etc.).  (Recall that the project formerly known as Some Kind of Æther and now known as Maven Artifact Resolver expanded to become very, very flexible at the expense of being simple to use, so it can read from repositories that aren’t just Maven repositories, so it inherently doesn’t know anything about Maven, even though now it has been folded back into the Maven codebase.)

Fortunately, in the history of all this, there was a class called MavenRepositorySystemUtils.  If you search for this, you’ll find its javadocs, but these are not the javadocs you’re looking for.  Let’s pretend for a moment they were: you would, if you used this class, be able to get a RepositorySystem rather easily:

final ServiceLocator serviceLocator = MavenRepositorySystemUtils.newServiceLocator();
assert serviceLocator != null;
final RepositorySystem repositorySystem = serviceLocator.getService(RepositorySystem.class);
assert repositorySystem != null;

But these javadocs are for a class that uses Eclipse Æther, so no soup for you.

So now what?  It turns out that that class still exists and has been refactored to use Maven Artifact Resolver (maven-resolver), but its project page and javadocs and whatnot don’t exist (yet?).  The artifact you’re looking for, then, turns out to be maven-resolver-provider, and as of this writing exists only in its 3.5.0-alpha-1 version.

So if you make sure that artifact is available then you’ll be able to use the Maven Artifact Resolver APIs to interact with Maven repositories and download and resolve dependencies.