7. Extending the console
This chapter will guide you through the steps needed to extend the console and create a new shell. We will leverage Maven, Spring, Spring-DM and OSGi, so you will need some knowledge of those products.
As an example, we will create a command that will leverage the OSGi ConfigAdmin to display the existing configurations.
Create the project using maven
We first need to create the project using maven. Let's leverage maven archetypes for that.
Command line
Using the command line, we can create our project:
mvn archetype:create \ -DarchetypeArtifactId=maven-archetype-quickstart \ -DgroupId=org.apache.servicemix.kernel.gshell \ -DartifactId=org.apache.servicemix.kernel.gshell.config \ -Dversion=1.0-SNAPSHOT
This generate the main pom.xml
and some additional packages.
Interactive shell
You can also use the interactive mode for creating the skeleton project:
mvn archetype:generate
Use the following values when prompted:
Choose a number: (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36) 15: : 15 Define value for groupId: : org.apache.servicemix.kernel.gshell Define value for artifactId: : org.apache.servicemix.kernel.gshell.config Define value for version: 1.0-SNAPSHOT: : Define value for package: : org.apache.servicemix.kernel.gshell.config
Manual creation
Alternatively, you can simply create the directory org.apache.servicemix.kernel.gshell.config
and create the pom.xml
file inside it:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.servicemix.kernel.gshell</groupId> <artifactId>org.apache.servicemix.kernel.gshell.config</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>org.apache.servicemix.kernel.gshell.config</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
Dependencies
We need to tell maven which libraries our project depends on. In the dependencies
section of the pom, add the following ones:
<dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.core</artifactId> <version>1.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.servicemix.kernel.gshell</groupId> <artifactId>org.apache.servicemix.kernel.gshell.core</artifactId> <version>1.0-m2</version> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-core</artifactId> <version>1.0</version> </dependency>
These are needed respectively for OSGi, ServiceMix Kernel commands support and Spring-DM.
Additionally, we need the ConfigAdmin service, which is in the OSGi Compendium jar:
<dependency> <groupId>org.apache.felix</groupId> <artifactId>org.osgi.compendium</artifactId> <version>1.0.0</version> <scope>provided</scope> </dependency>
Loading the project in your IDE
We can use maven to generate the needed files for your IDE:
Inside the project, run the following command
mvn eclipse:eclipse
or
mvn idea:idea
The project files for your IDE should now be created. Just open the IDE and load the project.
Creating a basic command class
We can now create the command class ListCommand.java
package org.apache.servicemix.kernel.gshell.config; import org.apache.geronimo.gshell.support.OsgiCommandSupport; import org.apache.geronimo.gshell.command.annotation.CommandComponent; @CommandComponent(id="config:list", description="List the available configurations") public class ListCommand extends OsgiCommandSupport { protected Object doExecute() throws Exception { io.out.println("Executing List command"); return null; } }
Creating the associated spring configuration files
The spring configuration files will be used to create the command and register it in the OSGi registry, which is the way to make the command available to the ServiceMix Kernel console. This spring file must be located in the META-INF/spring/
directory inside the bundle.
If you don't have the src/main/resources
directory yet, create it.
mkdir src/main/resources
Then, re-generate the IDE project files and reload it so that this folder is now recognized as a source folder.
Inside this directory, create the META-INF/spring/
directory and put the following file inside (the name of this file has no impact at all):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd"> <bean id="list" class="org.apache.servicemix.kernel.gshell.config.ListCommand" /> <osgi:service ref="list" interface="org.apache.geronimo.gshell.command.Command"> <osgi:service-properties> <entry key="shell" value="config"/> <entry key="alias" value="list"/> </osgi:service-properties> </osgi:service> </beans>
Compiling the jar
Let's try to build the jar. Remove the test classes and sample classes if you used the artifact, then from the command line, run:
mvn install
The end of the maven output should look like:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
Using Java 5
If you see something like that:
[ERROR] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Compilation failure xxx/src/main/java/org/apache/servicemix/kernel/gshell/config/ListCommand.java:[6,1] annotations are not supported in -source 1.3 (try -source 1.5 to enable annotations) @CommandComponent(id="config:list", description="List the available configurations")
that's because we forgot to enable Java 5. So let's add that to the pom:
<build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </pluginManagement> </build>
Turning the jar into an OSGi bundle
OSGi bundles are jars but they require some manifest headers to be correctly recognized. We will leverage Felix's manven plugin to easily generate those.
Lets turn it into a bundle: modify the line in the pom.xml
to adjust the packaging:
<packaging>bundle</packaging>
Add the following section at the bottom of the pom.xml
<build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>1.4.0</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>Config</Bundle-SymbolicName> <Import-Package>org.apache.geronimo.gshell.command,*</Import-Package> <Spring-Context>*;publish-context:=false;create-asynchronously:=false</Spring-Context> </instructions> </configuration> <dependencies> <dependency> <groupId> </dependency> </dependencies> </plugin> </plugins> </build>
Let's compiled it again using the mvn install
command.
Test in ServiceMix Kernel
Launch a ServiceMix Kernel instance and run the following command to install are newly created bundle:
osgi install -s mvn:org.apache.servicemix.kernel.gshell/org.apache.servicemix.kernel.gshell.config/1.0-SNAPSHOT
If you run the help
command, you should now see our new shell config
.
Let's try running the command:
servicemix> config list Executing List command
Yeah