If we were to introduce a new model, we could just reuse what gogo has, I don't think we have to re-invent a different one:
https://github.com/apache/felix/blob/trunk/gogo/command/src/main/java/org/apache/felix/gogo/command/Basic.java Guillaume 2014-02-14 20:31 GMT+01:00 Guillaume Nodet <[email protected]>: > > > > 2014-02-14 18:29 GMT+01:00 Christian Schneider <[email protected]>: > > 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 > DSL. > > >> >> 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: > command(MyAction.class) > > 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. > > @Command(...) > @Register > public class MyCommand extends OsgiCommandSupport { > > @Inject > 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 >> >> >
