karaf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guillaume Nodet <gno...@apache.org>
Subject Re: [DISCUSS] Java DSL for writing commands
Date Fri, 14 Feb 2014 19:31:15 GMT
2014-02-14 18:29 GMT+01:00 Christian Schneider <chris@die-schneider.net>:

> The DSL will make it easier to write the command. So it is quite
> convenient in the start.
> The downside I see is that it will create quite strong coupling between
> someone creating the service and the karaf impl. So it might be difficult
> when we do karaf 4 which might introduce a lot of changes in the
> implementation.

Mmh, I'm not sure how this make things more coupled really.  The blueprint
DSL is karaf specific anyway so that commands are now tied to the blueprint

> I think it would be better if we find a way that allows the implementer of
> a command to simply implement an interface, use some annotations and export
> the command as a service. Basically we are almost there already. The user
> code already only depends on the interface Action and some annotations.
> I know we currently have the problem that e.g. in BlueprintCommand we
> create a new instance of the Action. Perhaps we could avoid that.

Well, it's not specific to blueprint, it's a separate decision.   Commands
are now stateless and recreated each time.  This has a benefit which is
that users don't have to deal with thread safety issues.  We could change
that, but that would definitely be a big incompatible change.

> How about this:
> The user simply exports his Action object as a service.

> We pick it up in the shell bundle and simply use it in a synchronized
> fashion on command execution at a time. We can then prepare the command
> (fill in the arguments and execute it) and execute it without creating a
> new instance.

Synchronizing on commands would be a really bad idea.  Some commands do run
for quite a long time (log:tail, etc...).   Re-preparing the same command
is more difficult because you need to know the default values as they have
been lost.

Anyway, if you look at the DSL, declaring a command in the most simple use
case is as simple as:

We could avoid that by adding annotations, but the commands usually need to
be injected with a service.  What could eventually be done, is to add a new
set of annotations for auto-registration and service injection.  If we do
that, we should not rely on another extender such as CDI or DS, as the
benefit would be lost, so it has to be pure karaf.
I guess this would cover 90% of the commands if we were able to inject OSGI
services by looking for a service matching the field type.

public class MyCommand extends OsgiCommandSupport {

   private JndiService jndiService;

   public Object doExecute() throws Exception {


So with 2 new annotations, it should remove most of the blueprint stuff
needed I think.

I really don't think changing the model action/command model is a good
idea.  I'd much rather write a new one if we want to not instantiate new
commands each time.

> Best regards
> Christian
> On 14.02.2014 17:47, Guillaume Nodet wrote:
>> See https://issues.apache.org/jira/browse/KARAF-2761
>> The idea is to simplify writing commands as much as possible.
>> With the recent @Completer annotation, things are already much easier to
>> deal with, but writing commands without blueprint is a real pain.
>> I've committed a simple java DSL to help around that, so you have an
>> example at
>> https://git-wip-us.apache.org/repos/asf?p=karaf.git;a=blob;
>> f=scr/command/src/main/java/org/apache/karaf/scr/command/Commands.java;h=
>> 70533e5640e5ab0492b67df71a9a028a7895135e;hb=
>> 40140e4f0c0745a41c1a4579f529f07e5819d785#l39
>> So far the SCR commands, it's a clear win.
>> I'm also considering using it for blueprint based commands, but I haven't
>> had any time to experiment yet.   One limitation of blueprint is that
>> there's no "abstract" definitions, so no way to make things common to all
>> commands definitions in a given bundle.
>> Let's look at a common use case:
>> https://git-wip-us.apache.org/repos/asf?p=karaf.git;a=blob;
>> f=jndi/command/src/main/resources/OSGI-INF/blueprint/jndi-command.xml;h=
>> d9b9f148ca2bc3be6e6dcd574840ed19576f11da;hb=HEAD
>> The only real interesting things in the above xml is the class names of
>> commands and completers.  I think reusing the above DSL, the blueprint
>> would look like
>> <reference id="jndiService" interface="org.apache.karaf.jndi.JndiService"
>> />
>> <bean class="org.apache.karaf.jndi.command.Commands" init-method="init"
>> destroy-method="unregister">
>>    <property name="context" ref="blueprintBundleConext" />
>>   <property name="jndiService" ref="jndiService" />
>> </bean>
>> and then, the java code:
>> public class Commands extends org.apache.karaf.shell.commands.Commands {
>>    private JndiService jndiService;
>>    public void init() {
>>      completer(new ContextsCompleter(jndiService));
>>      completer(new NamesCompleter(jndiService));
>>      completer(new ServiceIdsCompleter(getContext()));
>>      command(AliasCommand.class);
>>      command(BindCommand.class);
>>      command(ContextsCommand.class);
>>      command(CreateCommand.class);
>>      command(DeleteCommand.class);
>>      command(NamesCommand.class);
>>      command(UnbindCommand.class);
>>      register();
>>    }
>>    public CommandBuilder command(Class<? extends Action> actionClass) {
>>      return super.command(actionClass)
>>                .properties(jndiService);
>>    }
>>    public void setJndiService(JndiService jndiService) {
>>      this.jndiService = jndiService;
>>    }
>> }
>> I haven't tried the above code yet, so there may be slight typos, but that
>> gives you an idea of what it would look like.
>> Thoughts ?
>> Guillaume
> --
> Christian Schneider
> http://www.liquid-reality.de
> Open Source Architect
> http://www.talend.com

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message