Print
Booter

NanoContainer Booter Overview

NanoContainer Booter is a mechanism for launching a tree of NanoContainer components and containers.

NanoContainer Core offers simple standalone functionality.

NanoContainer Booter is for more complex trees of components.

Example usage

Directory structure

Executing the maven goal booter:demo in nanocontainer-booter project creates the following

NanoContainer distribution (under target/nanodist):

Launching it

The composition script is optional if using groovy as this is the default script.

nanocontainer.sh provides a convenience script for the above command. It also sets the Java security permission -

as will be explain below. Let's take one step at a time.

Composition Script

Description of the above

Component3ThatNeedsSayComponent2 (Comp3) though it has a Component2 instance handed to it, it cannot leverage the implementation at all. It can't cast it-

  • It can't invoke public methods on the Component2 implementation (Component2Impl).
  • It can't see the classloader that Component2Impl is in at all.

The Classloaders for Comp2.jar and Comp3.jar cannot see each other. They do see their parent Comp2.jar. The parent classloader of Comp1.jar contains PicoContainer. The parent of that is rt.jar (J2SE ot J2EE as appl).

No part of the component framework can see NanoContainer at all*. Nor Groovy or the things it needs to run (Antlr, ASM) etc.

  • If one of the components wants to launch its own tree of Pico or NanoContainer components, then it can do so, but it will need a new version of NanoContainer mounted in the component ClassLoader tree. That will be a different NanoContainer to that the Boot used to make the component tree.

What is actually happening pictorially

Variations on the example

Just after launching NanoContainer via booter. Booter is in a classloader that has a parent classloader containing the classes of the JDK:

Booter creates two other classloaders. The first has PicoContainer in it and has a parent of containing the classes of the JDK. The second contains Groovy (and its deps) and NanoContainer and has parent which is the classloader containing PicoContainer. Note that both of those classloaders cannot see the classloader that contains booter, in any way shape or form:

Booter (the class) hands control to NanoContainer. It is then effectively removed from the picture:

NanoContainer, leveraging Groovy, loads the three component classloaders in a hierarchy, all routing back to the PicoContainer classloader:

That done, NanoContainer (and Groovy etc) effectively remove themselves from the picture.

As above with permissions.

The Component3ThatNeedsSayComponent2 component is allowed to access google.com's website. Implicitly all other permissions are as you'd expect in a sandbox, including all for Component2Impl. No permissions are going to be enforced at all without a custom java invocation:

Still implementation hiding, but all in the same classloader.

Component3ThatNeedsSayComponent2 can see the classes for Component2Impl, but can't instantiate any or invoke their methods statically as it is in a sandbox.

No classloader juggling.

Still the same application, but this time the classes sit in the same classloader as Groovy and NanoContainer. Clearly the two components share the same permissions. As the classes are already visible to the Groovy script, the registration can be by class rather than class name.

Two implementations of the same thing

Here we are showing that Pico/NanoContainer can handle multiple versions of the same thing. In this case it is a class that has been bumped a revision and shipped in a new jar. For some reason we need to support both, so each is mounted in its own child container with a string key. Both of the Component3ThatNeedsSayComponent2 instances can leveage the same Component2Impl via the same Component2Key interface.

Two implementations of the same thing (simplified)

There really was no reason to have the two child containers. At least for the purposes of our example.

Powered by Atlassian Confluence