Sunday, July 15, 2012

Using Javassist to Create a Karaf/GoGo Shell Command Dynamically

Karaf OSGi runtime provides an excellent shell console functionality called Felix GoGo that can be extended easily using Blueprint XML :

<command-bundle xmlns="">
    <command name="process/run">
        <action class="">
            <argument ref="processContainer"/>
            <argument ref="ksession"/>
            <argument ref="dependencyLookup"/>
    <command name="process/ls">
        <action class="">
            <argument ref="processContainer"/>
    <command name="process/class">
        <action class="">
            <argument ref="blueprintBundleContext"/>

A Karaf Shell Blueprint command element is equivalent to:

<bean id="processLsCommand" scope="prototype"


<argument ref="processContainer"/>


<service auto-export="interfaces">


<entry key="osgi.command.scope" value="test"/>

<entry key="osgi.command.function" value="ls"/>


<bean class="">

<property name="blueprintContainer" ref="blueprintContainer"/>

<property name="blueprintConverter" ref="blueprintConverter"/>

<property name="actionId"><idref component-id="processLsCommand"/></property>



Using the bytecode tooling library Javassist, it's possible (and almost quite practical) to create GoGo commands dynamically at runtime :

ClassPool pool = new ClassPool();
pool.appendClassPath(new LoaderClassPath(getClass().getClassLoader()));

CtClass helloClass = pool.makeClass("cc.HelloCommand");

ClassFile cf = helloClass.getClassFile();
AnnotationsAttribute attr = new AnnotationsAttribute(cf.getConstPool(), AnnotationsAttribute.visibleTag);
Annotation annotation = new Annotation("org.apache.felix.gogo.commands.Command", cf.getConstPool());
annotation.addMemberValue("scope", new StringMemberValue("test", cf.getConstPool()));
annotation.addMemberValue("name", new StringMemberValue("hello", cf.getConstPool()));
annotation.addMemberValue("description", new StringMemberValue("Hello!", cf.getConstPool()));

CtMethod doExecuteMethod = CtMethod.make("protected Object doExecute() throws Exception { System.out.println(\"OMG!\"); return \"Hello!\"; }", helloClass);

System.out.println("Class: " + helloClass);
Class clazz = helloClass.toClass(getClass().getClassLoader(), getClass().getProtectionDomain());
System.out.println("Created " + clazz);
final Object obj = clazz.newInstance();

BlueprintCommand cmd = new BlueprintCommand() {
    public Action createNewAction() {
        return (Action)obj;
Hashtable<String, String> props = new Hashtable<String, String>();
props.put(CommandProcessor.COMMAND_SCOPE, "test");
props.put(CommandProcessor.COMMAND_FUNCTION, "hello");
bundleContext.registerService(new String[] { CompletableFunction.class.getName(),
                Function.class.getName() }, cmd, props);

return null;


Laurie Sanders said...

This is a smart blog. said...

I like this code. NIce work. Thanks for sharing.

Anonymous said...

This article has me looking from the past and only now I found it. Improve the quality of your articles and continue to create a more | | | | | | | | | | | | | | |

Anonymous said...

"Really awesome work with the blog. I do like your hard work on and will wait for more post as from you as post gave me pleasure and gives some helps to do same work right here. Thanks a lot……………" | | | | |

Anonymous said...

Keep sharing such ideas in the future as well. This was actually what I was looking for, and I am glad to came here! Thanks for sharing the such information with us. | | | | | | | | | |

Post a Comment

Copyright 2009 Spring vs Java EE Web Dev. Powered by Blogger Blogger Templates create by Deluxe Templates. WP by Masterplan