Felix GoGo aka OSGi RFC-147 is a
standard-based way to
implement modular CLI (command-line interface / console / shell) commands in
Java.
Apache Karaf supports
Felix GoGo console out-of-the box, along with
MINA SSH server integration. This blog post's focus would be
Eclipse Virgo Web Server (Eclipse Virgo Kernel), and how we can leverage the same CLI support, along with SSH, in Eclipse Virgo. Now this article would be very short if I were using Apache Karaf, because it already had the right ingredients built-in and well-integrated: Felix GoGo, SSH server, Apache Aries as OSGi Blueprint implementation. I hope these features will also be in Eclipse Virgo soon (here's hoping)! :-)
Modular Java programming uses OSGi technology, if you aren't yet familiar with OSGi I recommend reading
OSGi in Action: Creating Modular Applications in Java.
Enhancing Eclipse Virgo with Felix GoGo and SSHI hope Virgo will soon have built-in support for Felix GoGo and SSH server, but for now, we must do this ourselves.
Hristo Iliev from SAP has written an excellent tutorial on
how to enable Felix GoGo and SSH support in Eclipse Virgo, so I'll pretty much just paste it here :-)
Step 1: Download Gogo shell
To run the Gogo you will need three bundles from Apache Felix downloads:
Step 2: Equinox and RFC-147
To enable RFC-147 integration in Equinox you will need some console supportability features that are provided by the Console supportability project in Equinox Incubator.
20110611 build is fine for me. Download the Incubator build that includes the bundle we'll need. Extract only the supportability JAR (org.eclipse.equinox.console.supportability) from plugins folder.
Step 3: Enabling SSH Support
First download Apache Mina's binary distribution for SSHD, and then from the lib directory of the archive extract these two bundles:
Step 4: Setting up Virgo
Copy the console supportability bundle (org.eclipse.equinox.console.supportability) in lib directory
Place the rest of the bundles (3xGogo, SSHD and Mina) in lib/kernel directory
Edit config/org.eclipse.virgo.kernel.userregion.properties file and add the bundles to base bundles list:
baseBundles = \
file:lib/kernel/org.eclipse.virgo.kernel.userregion-3.0.0.M05.jar@start,\
file:lib/kernel/org.eclipse.virgo.kernel.osgicommand-3.0.0.M05.jar@start,\
file:lib/kernel/mina-core-2.0.1.jar@start,\
file:lib/kernel/org.apache.felix.gogo.command-0.8.0.jar@start,\
file:lib/kernel/org.apache.felix.gogo.runtime-0.8.0.jar@start,\
file:lib/kernel/org.apache.felix.gogo.shell-0.8.0.jar@start,\
file:lib/org.eclipse.equinox.console.supportability_1.0.0.N20110608-2000.jar@start,\
file:lib/kernel/sshd-core-0.5.0.jar@start
Step 5: Configuring Virgo
#osgi.console=2401
osgi.console.ssh=2422
osgi.console.enable.builtin=false
osgi.console.ssh.useDefaultSecureStorage=true
equinox_console {
org.eclipse.equinox.console.jaas.SecureStorageLoginModule REQUIRED;
};
set KERNEL_JAVA_PARMS=%KERNEL_JAVA_PARMS% -Dorg.eclipse.virgo.kernel.authentication.file="%CONFIG_DIR%\org.eclipse.virgo.kernel.users.properties"
set KERNEL_JAVA_PARMS=%KERNEL_JAVA_PARMS% -Dorg.eclipse.equinox.console.jaas.file="%CONFIG_DIR%/store"
set KERNEL_JAVA_PARMS=%KERNEL_JAVA_PARMS% -Dssh.server.keystore="%CONFIG_DIR%/hostkey.ser"set KERNEL_JAVA_PARMS=%KERNEL_JAVA_PARMS% -Djava.io.tmpdir="%TMP_DIR%"
diff --git a/bin/dmk.sh b/bin/dmk.sh index 5f8112b..4122d55 100755 --- a/bin/dmk.sh +++ b/bin/dmk.sh @@ -174,6 +174,8 @@ then -XX:HeapDumpPath=$KERNEL_HOME/serviceability/heap_dump.hprof \ -Djava.security.auth.login.config=$CONFIG_DIR/org.eclipse.virgo.ker -Dorg.eclipse.virgo.kernel.authentication.file=$CONFIG_DIR/org.ecli + -Dorg.eclipse.equinox.console.jaas.file=$CONFIG_DIR/store \ + -Dssh.server.keystore=$CONFIG_DIR/hostkey.ser \ -Djava.io.tmpdir=$TMP_DIR \ -Dorg.eclipse.virgo.kernel.home=$KERNEL_HOME \ -classpath $CLASSPATH \
Step 6: Connecting to Virgo
Fire your favourite SSH client on the specified port (2422 for instance).
$ ssh -p2422 equinox@localhost
Step 7: Fun with Gogo
Check the features provided by GoGo and Equinox Console Supportability:
Tab Completion (...doesn't yet work for me... any suggestions?) / Line editing
Built-in commands like lb, ls, cat to name a few
Create some scripts
Create some commands using RFC-147
Step 8: Disconnecting
Do not use "exit" since this will exit Virgo/OSGi framework. To end the session you'll have to close the console/SSH window. There is no command to close the session currently.
Create the Felix GoGo Command Implementation ProjectYou'll need
Eclipse IDE for RCP Development distribution or PDE plug-in for this. Create a new Eclipse PDE Plug-in project with the following class:
package gogosimple1;public class SimpleCommand { public void walk() { System.out.println("walking"); } public void talk() { System.out.println("talking"); } }Simple isn't it? And no external dependency on Felix GoGo API whatsoever (at this point).
I will use OSGi Blueprint to publish that class as a service and register a command scope to Felix GoGo. Create
src/OSGI-INF/blueprint/gogosimple1.xml file with the following:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <bean id="simpleCommand" class="gogosimple1.SimpleCommand" /> <service ref="simpleCommand" auto-export="all-classes"> <service-properties> <entry key="osgi.command.scope"><value>simple</value></entry> <entry key="osgi.command.function"> <array value-type="java.lang.String"> <value>walk</value> <value>talk</value> </array> </entry> </service-properties> </service></blueprint> For your convenience, the
gogosimple1 example project is available on GitHub.
Installing Eclipse Gemini Blueprint on Virgo Web Server
Virgo 3.0 milestones shipped with (and
unfortunately, will still ship) the ancient Spring-DM 1.2.1, so to enable OSGi Blueprint we need to install a OSGi Blueprint implementation by ourselves.
Fortunately Eclipse Gemini Blueprint seems to work just fine.
Download Eclipse Gemini Blueprint.
Copy the following files to Virgo's pickup/ folder: (in order)
gemini-blueprint-core-1.0.0.M1.jar
gemini-blueprint-extender-1.0.0.M1.jar
gemini-blueprint-io-1.0.0.M1.jar
Alternative: Apache Aries BlueprintActually, I originally used
Apache Aries Blueprint implementation for this experiment.
Download Apache Aries Blueprint.
Put these bundles in pickup/ folder: (in order)
com.springsource.org.objectweb.asm-3.1.0.jar
com.springsource.org.objectweb.asm.commons-3.1.0.jar
com.springsource.org.objectweb.asm.tree-3.1.0.jar
org.apache.aries.util-0.3.jar
org.apache.aries.proxy-0.3.jar
org.apache.aries.blueprint-0.3.jar
Trying the CommandsBuild the simplegogo1 project (right click the project > Export... > Deployable plug-ins and fragments), and copy the resulting bundle JAR to Virgo's pickup/ folder.
If you don't feel like compiling, you can
download prebuilt gogosimple1 JAR here (hint: it's very small, just 12 KB).
Virgo should install it, and Blueprint should register SimpleCommand bean as
OSGi service:
g! lb | grep -i gogo 44|Active | 1|Apache Felix Gogo Command (0.8.0) 45|Active | 1|Apache Felix Gogo Runtime (0.8.0) 46|Active | 1|Apache Felix Gogo Shell (0.8.0) 128|Active | 1|Gogosimple1 (1.0.0.qualifier)true
g! b 128gogosimple1_1.0.0.qualifier [128] Id=128, Status=ACTIVE Data Root=/home/ceefour/project/Soluvas/web-as/virgo-tomcat-server-3.0.0.M05/work/osgi/configuration/org.eclipse.osgi/bundles/128/data "Registered Services" {gogosimple1.SimpleCommand}={osgi.command.scope=simple, osgi.command.function=[walk,talk], org.eclipse.gemini.blueprint.bean.name=simpleCommand, osgi.service.blueprint.compname=simpleCommand, Bundle-SymbolicName=gogosimple1, Bundle-Version=1.0.0.qualifier, service.id=269}
{org.osgi.service.blueprint.container.BlueprintContainer}={Bundle-SymbolicName=gogosimple1, Bundle-Version=1.0.0.qualifier, osgi.blueprint.container.version=1.0.0.qualifier, osgi.blueprint.container.symbolicname=gogosimple1, service.id=270} {org.eclipse.gemini.blueprint.context.DelegatedExecutionOsgiBundleApplicationContext, org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}={org.springframework.context.service.name=gogosimple1, Bundle-SymbolicName=gogosimple1, Bundle-Version=1.0.0.qualifier, service.id=271} Services in use: {org.xml.sax.EntityResolver}={spring.osgi.core.bundle.id=130, spring.osgi.core.bundle.timestamp=1308232521056, service.id=249} {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={spring.osgi.core.bundle.id=130, spring.osgi.core.bundle.timestamp=1308232521056, service.id=248} {org.osgi.service.packageadmin.PackageAdmin}={service.ranking=2147483647, service.pid=0.org.eclipse.osgi.framework.internal.core.PackageAdminImpl, service.vendor=Eclipse.org - Equinox, service.id=1} No exported packages Imported packages org.osgi.framework; version="1.6.0"<org.eclipse.osgi_3.7.0.v20110224 [0]> No fragment bundles Named class space gogosimple1; bundle-version="1.0.0.qualifier"[provided] No required bundlesYou can try GoGo commands you just installed:
g!
simple:walkwalking
g!
simple:talk talking
"help" command is also available to list all available commands:
g!
helpequinox:addRoles
equinox:addUser
equinox:b
equinox:bundle
equinox:bundles
equinox:classSpaces
equinox:close
equinox:deleteUser
equinox:exec
equinox:exit
equinox:fork
equinox:gc
equinox:getPackages
equinox:getprop
equinox:h
equinox:headers
equinox:help
equinox:i
equinox:init
equinox:install
equinox:listUsers
equinox:p
equinox:packages
equinox:pr
equinox:profilelog
equinox:props
equinox:r
equinox:refresh
equinox:removeRoles
equinox:requiredBundles
equinox:resetPassword
equinox:s
equinox:se
equinox:services
equinox:setPassword
equinox:setbsl
equinox:setfwsl
equinox:setibsl
equinox:setp
equinox:setprop
equinox:shutdown
equinox:sl
equinox:ss
equinox:ssh
equinox:sta
equinox:start
equinox:status
equinox:sto
equinox:stop
equinox:t
equinox:telnet
equinox:threads
equinox:un
equinox:uninstall
equinox:up
equinox:update
felix:bundlelevel
felix:cd
felix:frameworklevel
felix:headers
felix:help
felix:inspect
felix:install
felix:lb
felix:log
felix:ls
felix:refresh
felix:resolve
felix:start
felix:stop
felix:uninstall
felix:update
felix:which
gogo:cat
gogo:each
gogo:echo
gogo:format
gogo:getopt
gogo:gosh
gogo:grep
gogo:not
gogo:set
gogo:sh
gogo:source
gogo:tac
gogo:telnetd
gogo:type
gogo:until
obr:deploy
obr:info
obr:javadoc
obr:list
obr:repos
obr:source
simple:talk
simple:walk
Using Virgo Tools Eclipse IDE Plugin to Launch Eclipse Virgo Web ServerBuilding project and manually copying the JAR is boring, not to mention it's not helpful during development/debugging.
Thankfully there is
Virgo Tools, which has been part of
SpringSource Tool Suite. You can install it in your Eclipse IDE using one of the following update sites (depending on your preference of stability, I use the "milestone" one, and I am not having problems):
Choose: Core / dm Server Tools (as of Virgo Tools 2.7.0-M2)
Open the Servers view (Shift+Alt+Q Q, choose Servers), then add a new server, pick Eclipse Virgo Web Server.
Before launching, you need to edit the launch configuration to enable SSH server.
Double-click Eclipse Virgo Web Server in the Servers view, then click "Edit launch configuration".
On Arguments > VM arguments, add the following:
-Dorg.eclipse.equinox.console.jaas.file="$CONFIG_DIR/store" -Dssh.server.keystore="$CONFIG_DIR/hostkey.ser"
You need to manually replace $CONFIG_DIR above with the Virgo Web Server's config folder.
Now you can launch Eclipse Virgo Web Server from Eclipse IDE, develop & debug, inspect its configuration, deploy artifacts, etc. right inside the Eclipse IDE.
Deploying PDE Plug-in Projects into Eclipse Virgo Web Server Currently Virgo Tools is integrated with WTP, but not with PDE. Which means:
Eclipse plugin projects cannot be deployed straightforwardly into Virgo Web Server using Virgo Tools plugin
What can be deployed are VWS-specific OSGi Plan project and OSGi Bundle project. You can right click a "plain" Eclipse plugin project > Spring Tools > Add OSGi Bundle project nature to convert it to VWS OSGi Bundle project.
OSGi Bundle nature has its own way of generating MANIFEST.MF, it doesn't use Eclipse PDE's META-INF/MANIFEST.MF file.
State as of 13 June 2011: (source)
Unfortunately there is no integration of STS and PDE. The Libra project is doing a great job at integrating WTP and PDE and looks like a great way of developing OSGi standard bundles, although it doesn't yet have a way to launch Virgo. The Virgo tooling, contributed to Eclipse from STS, is also developing, is able to launch Virgo (of course), and we hope to align it with Libra in due course.For now, why not ditch the PDE manifest and run with STS and Maven? That's the approach we took in the Greenpages sample application which you may like to refer to. See also "Creating an Application with Virgo" which goes through the Greenpages sample in some detail.
Better tooling for OSGi, Eclipse Virgo, Eclipse Gemini, and integration with PDE are goals of
Eclipse Libra project. Maybe you can help? :-)
To deploy gogosimple1 using Virgo Tools, first you need to enable the OSGi bundle project nature: right-click on the project, click Spring Tools > Add OSGi Bundle project nature.
Then right-click on the Virgo Web Server in Servers view, click Add and Remove, now you can choose gogosimple1 to deploy the project as artifact to Virgo.
By doing the steps above, the development cycle with Virgo and Eclipse IDE becomes
very convenient, anytime you change the project's source code, resource files, etc. Virgo will immediately pick it up. You can also launch Eclipse Virgo in debug mode and have all Eclipse IDE debugging tools at your fingertips!
Recommended ResourcesFor more in-depth explanation on OSGi, I highly recommend
OSGi in Action: Creating Modular Applications in Java.