Bob

Vision of Bob ?

(from various beer talks (without beer) with marcel o.)

Bob is a build system that encourages dump simple project setups most java developers know
and treats OSGi as the final output format only.

1.
Most java developers do not have problems hacking together apps in their favourite IDE using simple Java semantics like:

  • you have a single big classpath
  • there you toss in all your jars and compiled sources
  • organize modules lazily in separate java projects (the maven approach) or just in a big project just dividing them with packagenames.

2.
Bob just accepts this behaviour as a status-quo developer view.
However, transforming this to OSGi needs sophisticated know-how or willingness to accept some pain.
Until now, this transformation has affected the way people do the first steps (see 1.)

Bob accepts a big classpath as input and provides some more or less simple "Builders" that transform this information
directly into concrete bundles that are (if possible) also consistent.
So, Bob has the top level view of you application / use case you have in mind when hacking together the app.

It is now up to the builder of choice to configure instructions.
Those instructions can be BND instructions to "pull" certain classes and resources out of the big classpath into single bundles.

2.1
So why transforming the big Classpath to OSGi components if you do not really "see" them ?
Because we see OSGi has (obviously) its strengths as a runtime model.
In the enterprise world, the dynamic bundle exchange behaviour is usually not the first goal on why people adopt OSGi.
Its the shielding aspect that osgi provides. It makes sure components have the right / restricted visibility.
This is nothing the compiler (usually) tells you. It is a runtime thing. And weaving your code up to a running platform (OSGi in this case)
as soon and as simple as possible is crucial to verify you (desired) setup.

Bob makes it simple to exchange the partitioning and look of runtime components without affecting your project setup on sourcecode level.

3.
Because bob has this top level view, it is also capable of providing meaningful assistance and provide corrections to you
project structure.

4.
Thanks to URL handlers from Pax URL, bob directly supports not just the (known from Apache ACE) monotholic single sourcetree
organization (where the idea of Bob originates) but also the "maven way" where you usually deal with many smaller artifacts.
So, in ace a classpath setup for bob could look like so:
classpath=target/classes;libs/ant-contrib.jar;libs/osgi.jar

In a maven project this can look like so:
classpath=mvn:org.acme/gui/1.0.0;mvn.acme/service/1.0.0;mvn:commons-logging/commons-logging

5.
Where does the bob principle not apply ?
Bob very much builds on the fact that you separate different thing into different packages.
The resource path of any item it fetches from its "classpath" is crucial to split things apart into bundles.

Also, if you do not have such a thing as "application" that pretty much makes up the desired system, bob might be not for you.
If you just create bundles for other parties/vendors, you better end up packing them up with bnd/maven-bundle-plugin directly.

Whats currently there

the current stuff in laboratory/tonit/bob is routh proof of concept/workinprogress to clarify the ideas and see
if it makes sense at all.

Look at Runner.build(..) to see the high level lifecycle we currently have.
Runner
Main entry point. Start of anything.

Recipe
a recipe is the instruction (recipe is just shorter and more crisp to me..) that the user provides.
It is similar to the pom in maven or build.xml in ant.
Currently, there is no parser for a fileformat (but there is a skeleton for someone to do this at LocalRecipeLocator.java)
Finally, Recipe is the object view of any fancy format one could provide.

Project
Created by analyzing recipe's classpath. All resources mentioned there have been resolved and are accessable through methods of Project.
The Project instance is something, that could be (later) persisted and reused to speed up rebuilding "just the changed things".
This is also a reason why, once Project has been created, all resources must be available locally and with a max. of reliability.

For caching resources (inputstreams), the current implementation uses Tinybundles.Store, a very simple but effective way to "save" InputStreams and keep an abstract handle
for later retreaveal.

Hosted Resource
Bob has the notion of a monotholic classpath as input.
Still, it needs to separate project artifacts from external dependencies.

To allow this, we have the notion of "hostpackage" (see Recipe.getHostpackage) which specifies the root package of the project.
All resources below this path are considered hosted resources. All others are external resources.
It is up to the Builder implementation on what to package where and why.

Builder
This turns a Project into concrete artifacts on disk.
Because Project already provides a flattened, consistent view on the project and its resources, a builder just needs to decide what bundles it needs
to create + finally do it.
Builder uses the Tinybundles library (core part) (from Pax Swissbox) to easily create bundles with a minimum of technical code.

TODO:

  • currently we have 2 builders that are not of so much practical use: one that tosses all hosted resources into one bundle and create manifest with bnd wrap.
    The other is a pretty much automatic split demo which is more a demo than practical in real world.
    What we want: something that uses the information described in bob.xml (src/test/resources) --> demo descriptor.
  • Maven Plugin as a starter:
    Next to the fact that we might launch it standalone, i think it would be good to have a simple maven plugin
    (that just invokes bob with information gathered by maven reactor) to kickstart testing the whole idea with a
    wider range of projects.


by Marcel Offermans via Email:
First of all, I'd say the point is not as much to create a "dumb, simple project setup most java developers know". To me that is kind of a "negative" explanation that does not do justice to what we're trying to achieve.

The point, in my view, is that when you're developing an application out of components/bundles, in the end you're still developing an application. Applications tend to, by design, have a consistent class path, so one important thing is that we take this as a given instead of creating numerous independent bundles and fiddle with the metadata until we get that consistent classpath again.

Of course you could argue we're fiddling with the componentization until we've succesfully broken up the application into the components we want, and that would be correct. Of course you usually have a well thought out architecture that helps you do this in a good way. In fact, a popular way of describing the architecture of a system is this "4+1" view, where the development view then nicely maps onto application as its laid out the IDE with packages and classes, and the deployment view maps onto the OSGi framework and the componentization into OSGi bundles. So it's not only that you use OSGi as "the final output format" because you design the componentization in your IDE.

About 4: The danger of putting external, non-OSGi artifacts on the classpath is that you get access to everything in such artifacts. Of course this is what you want when somehow embedding external resources and bundlizing them. However, one should use OSGi bundles as much as possible, in which case I would like to propose we only expose the public "bits" of these bundles to the classpath. When working with ACE, which stores its bundles in an OBR (or in theory any other repository that can be accessed through a URL), or when working with Pax URL as you describe, we could make a special handler that filters out only the exported packages before putting them on the classpath.

A side question, btw, is there any IDE that can work directly with remote resources? I think most require a local copy, right? In that case you can also use Pax URL to download the right resource and then embed it in your project (unless you really want to keep developing against moving SNAPSHOT releases of course). You actually mention that later in "Project" (resources must be available locally).

About 5: The extreme case for Bob is where the application is the bundle. In that case, Bob is the same as using an Eclipse PDE project or Maven bundle plugin.

As a starter for Eclipse I'd like to find a way to include it as part of the "normal" Eclipse build. Eclipse also has a notion of builders, so here I see our builder as a "post compile step" that gets invoked automatically. If we can make our builder smart enough to only repackage bundles whose classes have changed (that should be doable) then this package step can be pretty instant, meaning your bundles will stay up to date with the current IDE state. As another step after that, having a list of changed, generated bundles for automatic deployment would be nice too. I could imagine writing an automatic importer for ACE which would mean that these bundle updates automatically go all the way to all configured targets, meaning you can very quickly see the consequences of your changes in all these targets (typically developer and test machines in this case).

(haha, this is not "as a starter" anymore, it's more where I want to end up)