Hi Guillaume,

you asked about my goals. I think these are my main goals:

1. The user should be able to expose commands without the boilerplate code. So basically we agree that ideally the user should just define the Action + annotations in his code
2. The user should only be exposed to the API (again actions + annotations)
3. The solution should ideally be framework agnostic. For example a blueprint namespace based solution will not work with gemini blueprint 4. The user should be able to do as much of his injections with his standard framework as possible

So I assume we just differ in goal 3 and you additionally have the goal of using services only for calling code over a published interface.

So basically if we just look at the user java code our solutions look very similar. The user defines an action with annotations.

In my whiteboard approach the user only exposes the Action as a service. The whole work of interpreting the meta data is done in the command exporter. Unfortunately this is on the other side of an OSGi service. So we kind of abuse the service to publish a template object. See below why I agree this is not good but also not that problematic.

In your proposal the work is done in a framework specific extension. I like your new proposal much more than the first one already as we reuse the DI of the framework. So your proposal mainly differs from my goals in the 3rd goal. The disadvantage I see in your solution is that we have to create an extension for each framework. If we assume that we only support aries blueprint and DS then this is surely doable. Still it would be a lot more effort short term as well as long term.

See some more comments inline....

On 17.02.2014 16:30, Guillaume Nodet wrote:
2014-02-17 16:01 GMT+01:00 Christian Schneider <[email protected]>:

I can very well imagine that this would work. I am not sure if it is a
good idea thought.
We would recreate parts of the dependency injection framework.

Well, which parts ? I don't understand.  My first attempt was indeed
creating a very small DI framework, but here, my goal is to delegate
everything to the real DI.  The namespace handler would simply be enhanced
to discover the actions and the injection points and create blueprint
metadata out of it.  This would obviously require a bit of reflection on
the classes, but nothing different from your proposal.


In any case it would require that we implement a solution for each DI
framework out there. Additionally we would have to keep our extensions up
to date with the framework evolution.
While I can understand that my approach has its own fallacies I think it
would create less issues and less work even in the long term.

What I could imagine as a kind of middle ground is to simply have a
special processing for the @Command annotation.

For example in blueprint we could have:

<bean class="MyAction">
.... do some injections ---
</bean>

We then let blueprint do its injections but also create the
BlueprintCommand for it and export the service. So this would be very
similar to the namespace but not requiring it. Not sure if this is possible
in blueprint though. The nice thing with this approach is that it might
also work with blueprint annotations. In any case I propose we let the
framework do its injections and only work with the fully injected Action.

Ok, so I misunderstood as it seems we don't have the same goals.  My point
is to make typical things easy for the user and not having to write this
boilerplate code. I.e. in 95% of the use cases, the user should not have to
deal with blueprint xml or DS specific annotations.

If the user wants to fully reuse its DI, he can do so, but our current
model is quite verbose.  We have such an example for blueprint:

https://github.com/apache/karaf/blob/master/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml#L56

and for DS:

https://github.com/apache/karaf/blob/karaf-3.0.0/scr/command/src/main/java/org/apache/karaf/scr/command/DetailsCommandComponent.java

So I'm not trying to change the above model, rather keep this model (Action
/ Command), but make things easier for the user to register commands.   I
first got rid of the completers and used annotations to wire them through
OSGi services, now I want to get rid of exposing the command in the OSGi
registry manually, even if we delegate to the underlying DI framework.

IIUC, what you're proposing is a new simplified model so that users don't
have to deal with commands but only with actions.  While I don't have any
problems with discussing a new model, I'd like to avoid misusing our
current model (and breaking a few OSGi contracts).  More importantly, your
proposal does not help a single bit solving my problem.
In my model there is still command and action. The only difference is that the Action is exposed as a service while in your model the Action is only exposed to the framework extension. The other steps are quite the same I think.

Though, if my goal can be achieved somehow, there's no real value left in
your proposal, as it would only help in 1% of the cases that can't be
covered by my proposal, and I think those will be the same that can't be
covered by the blueprint xml handler now (i.e. exit and help commands).
I see it quite the other way round. My solution is much simpler and covers 100% of the problem space. The downside is an unusual usage of OSGi services. I think my approach does not really violate any contracts the OSGi spec poses on services. The fact that we typically use services only with their interface is not mandated by the spec as far as I can tell. Still I see that using a service to expose a template object is quite unusual. So I would really be interested in a solution that avoids this while also
being framework agnostic.

As both solutions do work I think it is a question of weighing the pros and cons. I am still searching for a better way though. So lets continue experimenting for some more time. Perhaps we really find something better.

Christian




--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply via email to