felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Felix > 6.1. Extending the console
Date Fri, 23 Oct 2009 11:47:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=FELIX&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/FELIX/6.1.+Extending+the+console">6.1.
Extending the console</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~gnodet">Guillaume
Nodet</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <style type='text/css'>/*<![CDATA[*/
table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color:
#f0f0f0}
table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}

/*]]>*/</style><div class="Scrollbar"><table class='ScrollbarTable'><tr><td
width='33%' class='ScrollbarPrevName'>&nbsp;</td><td width='33%' class='ScrollbarParent'><sup><a
href="/confluence/display/FELIX/6.+Advanced+uses"><img border='0' align='middle' src='/confluence/images/icons/up_16.gif'
width='8' height='8'></a></sup><a href="/confluence/display/FELIX/6.+Advanced+uses">6.
Advanced uses</a></td><td width='33%' class='ScrollbarNextName'>&nbsp;<a
href="/confluence/display/FELIX/6.2.+Building+custom+distributions">6.2. Building custom
distributions</a></td><td class='ScrollbarNextIcon'><a href="/confluence/display/FELIX/6.2.+Building+custom+distributions"><img
border='0' align='middle' src='/confluence/images/icons/forwd_16.gif' width='16' height='16'></a></td></tr></table></div>
<p><a name="6.1.Extendingtheconsole-top"></a></p>

<h1><a name="6.1.Extendingtheconsole-6.1.Extendingtheconsole"></a>6.1. Extending
the console</h1>

<p>This chapter will guide you through the steps needed to extend the console and create
a new shell.  We will leverage Maven, Blueprint and OSGi, so you will need some knowledge
of those products.</p>

<h2><a name="6.1.Extendingtheconsole-Createtheprojectusingmaven"></a>Create
the project using maven</h2>

<p>We first need to create the project using maven.  Let's leverage maven archetypes
for that.</p>

<h3><a name="6.1.Extendingtheconsole-Commandline"></a>Command line</h3>

<p>Using the command line, we can create our project:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn archetype:create \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DgroupId=org.apache.felix.karaf.shell.samples \
  -DartifactId=shell-sample-commands \
  -Dversion=1.0-SNAPSHOT
</pre>
</div></div>

<p>This generate the main <tt>pom.xml</tt> and some additional packages.</p>

<h3><a name="6.1.Extendingtheconsole-Interactiveshell"></a>Interactive shell</h3>

<p>You can also use the interactive mode for creating the skeleton project:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn archetype:generate
</pre>
</div></div>
<p>Use the following values when prompted:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
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 <span class="code-keyword">for</span> groupId: : org.apache.felix.karaf.shell.samples
Define value <span class="code-keyword">for</span> artifactId: : shell-sample-commands
Define value <span class="code-keyword">for</span> version:  1.0-SNAPSHOT: : 
Define value <span class="code-keyword">for</span> <span class="code-keyword">package</span>:
: org.apache.felix.karaf.shell.samples
</pre>
</div></div>

<h3><a name="6.1.Extendingtheconsole-Manualcreation"></a>Manual creation</h3>

<p>Alternatively, you can simply create the directory <tt>shell-sample-commands</tt>
and create the <tt>pom.xml</tt> file inside it:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>pom.xml</b></div><div class="codeContent
panelContent">
<pre class="code-xml">
&lt;project xmlns=<span class="code-quote">"http://maven.apache.org/POM/4.0.0"</span>
<span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
  xsi:schemaLocation=<span class="code-quote">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span>&gt;
  <span class="code-tag">&lt;modelVersion&gt;</span>4.0.0<span class="code-tag">&lt;/modelVersion&gt;</span>
  <span class="code-tag">&lt;groupId&gt;</span>org.apache.felix.karaf.shell.samples<span
class="code-tag">&lt;/groupId&gt;</span>
  <span class="code-tag">&lt;artifactId&gt;</span>shell-sample-commands<span
class="code-tag">&lt;artifactId&gt;</span>
  <span class="code-tag">&lt;packaging&gt;</span>jar<span class="code-tag">&lt;/packaging&gt;</span>
  <span class="code-tag">&lt;version&gt;</span>1.0-SNAPSHOT<span class="code-tag">&lt;/version&gt;</span>
  <span class="code-tag">&lt;name&gt;</span>shell-sample-commmands<span
class="code-tag">&lt;/name&gt;</span>
  <span class="code-tag">&lt;url&gt;</span>http://maven.apache.org<span
class="code-tag">&lt;/url&gt;</span>
  <span class="code-tag">&lt;dependencies&gt;</span>
    <span class="code-tag">&lt;dependency&gt;</span>
      <span class="code-tag">&lt;groupId&gt;</span>junit<span class="code-tag">&lt;/groupId&gt;</span>
      <span class="code-tag">&lt;artifactId&gt;</span>junit<span class="code-tag">&lt;/artifactId&gt;</span>
      <span class="code-tag">&lt;version&gt;</span>3.8.1<span class="code-tag">&lt;/version&gt;</span>
      <span class="code-tag">&lt;scope&gt;</span>test<span class="code-tag">&lt;/scope&gt;</span>
    <span class="code-tag">&lt;/dependency&gt;</span>
  <span class="code-tag">&lt;/dependencies&gt;</span>
<span class="code-tag">&lt;/project&gt;</span>
</pre>
</div></div>

<h2><a name="6.1.Extendingtheconsole-Dependencies"></a>Dependencies</h2>

<p>We need to tell maven which libraries our project depends on.  In the <tt>dependencies</tt>
section of the pom, add the following one:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  <span class="code-tag">&lt;dependency&gt;</span>
    <span class="code-tag">&lt;groupId&gt;</span>org.apache.felix.karaf.shell<span
class="code-tag">&lt;/groupId&gt;</span>
    <span class="code-tag">&lt;artifactId&gt;</span>org.apache.felix.karaf.shell.console<span
class="code-tag">&lt;/artifactId&gt;</span>
    <span class="code-tag">&lt;version&gt;</span>1.0.0<span class="code-tag">&lt;/version&gt;</span>
  <span class="code-tag">&lt;/dependency&gt;</span>
</pre>
</div></div>

<p>This dependency is needed to have access to the base classes that are used to define
commands.</p>

<h2><a name="6.1.Extendingtheconsole-ConfiguringforJava5"></a>Configuring
for Java 5</h2>

<p>We are using annotations to define commands, so we need to ensure maven will actually
use JDK 1.5 to compile the jar.<br/>
Just add the following snippet after the <tt>dependencies</tt> section.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;build&gt;</span>
  <span class="code-tag">&lt;plugins&gt;</span>
    <span class="code-tag">&lt;plugin&gt;</span>
      <span class="code-tag">&lt;groupId&gt;</span>org.apache.maven.plugins<span
class="code-tag">&lt;/groupId&gt;</span>
      <span class="code-tag">&lt;artifactId&gt;</span>maven-compiler-plugin<span
class="code-tag">&lt;/artifactId&gt;</span>
      <span class="code-tag">&lt;configuration&gt;</span>
        <span class="code-tag">&lt;target&gt;</span>1.5<span class="code-tag">&lt;/target&gt;</span>
        <span class="code-tag">&lt;source&gt;</span>1.5<span class="code-tag">&lt;/source&gt;</span>
      <span class="code-tag">&lt;/configuration&gt;</span>
    <span class="code-tag">&lt;/plugin&gt;</span>
  <span class="code-tag">&lt;/plugins&gt;</span>
<span class="code-tag">&lt;/build&gt;</span>
</pre>
</div></div>

<h2><a name="6.1.Extendingtheconsole-LoadingtheprojectinyourIDE"></a>Loading
the project in your IDE</h2>

<p>We can use maven to generate the needed files for your IDE:</p>

<p>Inside the project, run the following command</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn eclipse:eclipse
</pre>
</div></div>
<p>or</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn idea:idea
</pre>
</div></div>

<p>The project files for your IDE should now be created.  Just open the IDE and load
the project.</p>

<h2><a name="6.1.Extendingtheconsole-Creatingabasiccommandclass"></a>Creating
a basic command class</h2>

<p>We can now create the command class <tt>HelloShellCommand.java</tt></p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>HelloShellCommand.java</b></div><div
class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.felix.karaf.shell.samples;

<span class="code-keyword">import</span> org.apache.felix.gogo.commands.Command;
<span class="code-keyword">import</span> org.apache.felix.gogo.commands.Option;
<span class="code-keyword">import</span> org.apache.felix.gogo.commands.Argument;
<span class="code-keyword">import</span> org.apache.felix.karaf.shell.console.OsgiCommandSupport;

@Command(scope = <span class="code-quote">"test"</span>, name = <span class="code-quote">"hello"</span>,
description=<span class="code-quote">"Says hello"</span>)
<span class="code-keyword">public</span> class HelloShellCommand <span class="code-keyword">extends</span>
OsgiCommandSupport {

    @Override
    <span class="code-keyword">protected</span> <span class="code-object">Object</span>
doExecute() <span class="code-keyword">throws</span> Exception {
        <span class="code-object">System</span>.out.println(<span class="code-quote">"Executing
Hello command"</span>);
        <span class="code-keyword">return</span> <span class="code-keyword">null</span>;
    }
}
</pre>
</div></div>

<h2><a name="6.1.Extendingtheconsole-Creatingtheassociatedblueprintconfigurationfiles"></a>Creating
the associated blueprint configuration files</h2>

<p>The blueprint configuration file will be used to create the command and register
it in the OSGi registry, which is the way to make the command available to Karaf console.
 This blueprint file must be located in the <tt>OSGI-INF/blueprint/</tt> directory
inside the bundle.</p>

<p>If you don't have the <tt>src/main/resources</tt> directory yet, create
it.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mkdir src/main/resources
</pre>
</div></div>

<p>Then, re-generate the IDE project files and reload it so that this folder is now
recognized as a source folder.</p>

<p>Inside this directory, create the <tt>OSGI-INF/blueprint/</tt> directory
and put the following file inside (the name of this file has no impact at all):</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>shell-config.xml</b></div><div
class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;blueprint xmlns=<span class="code-quote">"http://www.osgi.org/xmlns/blueprint/v1.0.0"</span>&gt;</span>

    <span class="code-tag">&lt;command-bundle xmlns=<span class="code-quote">"http://felix.apache.org/karaf/xmlns/shell/v1.0.0"</span>&gt;</span>
        <span class="code-tag">&lt;command name=<span class="code-quote">"test/hello"</span>&gt;</span>
            <span class="code-tag">&lt;action class=<span class="code-quote">"org.apache.felix.karaf.shell.samples.HelloShellCommand"</span>/&gt;</span>
        <span class="code-tag">&lt;/command&gt;</span>
    <span class="code-tag">&lt;/command-bundle&gt;</span>

<span class="code-tag">&lt;/blueprint&gt;</span>
</pre>
</div></div>

<h2><a name="6.1.Extendingtheconsole-Compilingthejar"></a>Compiling the
jar</h2>

<p>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:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
mvn install
</pre>
</div></div>

<p>The end of the maven output should look like:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
[SMX4KNL:INFO] ------------------------------------------------------------------------
[SMX4KNL:INFO] BUILD SUCCESSFUL
[SMX4KNL:INFO] ------------------------------------------------------------------------
</pre>
</div></div>

<h2><a name="6.1.Extendingtheconsole-TurningthejarintoanOSGibundle"></a>Turning
the jar into an OSGi bundle</h2>

<p>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.  </p>

<p>Lets turn it into a bundle: modify the line in the <tt>pom.xml</tt> to
adjust the packaging:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
  <span class="code-tag">&lt;packaging&gt;</span>bundle<span class="code-tag">&lt;/packaging&gt;</span>
</pre>
</div></div>

<p>Add the following section at the bottom of the <tt>pom.xml</tt>, in the
existing <tt>build/plugins</tt> section:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
      <span class="code-tag">&lt;plugin&gt;</span>
        <span class="code-tag">&lt;groupId&gt;</span>org.apache.felix<span
class="code-tag">&lt;/groupId&gt;</span>
        <span class="code-tag">&lt;artifactId&gt;</span>maven-bundle-plugin<span
class="code-tag">&lt;/artifactId&gt;</span>
        <span class="code-tag">&lt;version&gt;</span>2.0.1<span class="code-tag">&lt;/version&gt;</span>
        <span class="code-tag">&lt;extensions&gt;</span>true<span class="code-tag">&lt;/extensions&gt;</span>
        <span class="code-tag">&lt;configuration&gt;</span>
            <span class="code-tag">&lt;instructions&gt;</span>
                <span class="code-tag">&lt;Import-Package&gt;</span>org.osgi.service.command,*<span
class="code-tag">&lt;/Import-Package&gt;</span>
            <span class="code-tag">&lt;/instructions&gt;</span>
        <span class="code-tag">&lt;/configuration&gt;</span>
      <span class="code-tag">&lt;/plugin&gt;</span>
</pre>
</div></div>

<p>The <tt>Import-Package</tt> is required to make sure our bundle will
import the <tt>org.osgi.service.command</tt> package so that the service will
be correctly seen in Felix.</p>

<p>Let's compiled it again using the <tt>mvn install</tt> command.</p>

<h2><a name="6.1.Extendingtheconsole-TestinKaraf"></a>Test in Karaf</h2>

<p>Launch a Karaf instance and run the following command to install the newly created
bundle:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
karaf@root&gt; osgi:install -s mvn:org.apache.felix.karaf.shell.samples/shell-sample-commands/1.0-SNAPSHOT
</pre>
</div></div>

<p>Let's try running the command:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
karaf@root&gt; test:hello
Executing Hello command
</pre>
</div></div>

<p>and for the link:</p>

<p>Yeah <img class="emoticon" src="/confluence/images/icons/emoticons/smile.gif"
height="20" width="20" align="absmiddle" alt="" border="0"/></p>

<p><a href="#6.1.Extendingtheconsole-top">top</a></p>
<style type='text/css'>/*<![CDATA[*/
table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color:
#f0f0f0}
table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
table.ScrollbarTable td.ScrollbarParent {text-align: center;border: none;}
table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}

/*]]>*/</style><div class="Scrollbar"><table class='ScrollbarTable'><tr><td
width='33%' class='ScrollbarPrevName'>&nbsp;</td><td width='33%' class='ScrollbarParent'><sup><a
href="/confluence/display/FELIX/6.+Advanced+uses"><img border='0' align='middle' src='/confluence/images/icons/up_16.gif'
width='8' height='8'></a></sup><a href="/confluence/display/FELIX/6.+Advanced+uses">6.
Advanced uses</a></td><td width='33%' class='ScrollbarNextName'>&nbsp;<a
href="/confluence/display/FELIX/6.2.+Building+custom+distributions">6.2. Building custom
distributions</a></td><td class='ScrollbarNextIcon'><a href="/confluence/display/FELIX/6.2.+Building+custom+distributions"><img
border='0' align='middle' src='/confluence/images/icons/forwd_16.gif' width='16' height='16'></a></td></tr></table></div>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/FELIX/6.1.+Extending+the+console">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=81475&revisedVersion=18&originalVersion=17">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/FELIX/6.1.+Extending+the+console?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message