Remote launching OSGi applications with bnd (updated)

Recently, I wanted to build an OSGi application that should run on my RaspberryPi. So I wanted an easy way to test this application on the Pi. After some research I found the possibility to use a remote laucher in bnd.

There are two parts necessary for that:

  • the remote agent
  • the local launcher

Configure the remote agent

The remote-agent for an existing framework can be configured with a bndrun-file like this:

-runprovidedcapabilities: ${native_capability}
-runfw: org.apache.felix.framework;version='[7.0.3,7.0.3]'
-runee: JavaSE-1.8

-resolve.effective: active;skip:="osgi.service"

-runpath: \
    biz.aQute.remote.agent

-runproperties: \
   aQute.agent.server.port=0.0.0.0:29998, \
   gosh.args=--noshutdown, \
   osgi.shell.telnet.port=4003
-runtrace: true

With this there is just a OSGi framework running including the remote agent, that listens on port 29998, opens port 4003 for the OSGi console via telnet. Just export this setup to a single jar and copy it to your remote system.

On the Raspberry Pi

A shell script is recommended for a reliable start (e.g. /opt/osgi/remoteagent):

#!/bin/bash
DEBUG="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=0.0.0.0:8999,server=y,suspend=n"
SHELL="-Dosgi.shell.telnet.ip=0.0.0.0 -Dosgi.shell.telnet.port=4003"
/usr/bin/java -Xms128m -Xmx512m -Dgosh.args=--nointeractive ${SHELL} ${DEBUG} -jar remoteagent.jar

Linux systemd service (optional)

To start and stop the remote agent on system up and down we can use the Linux Systemd and create a Unit at /etc/systemd/system/osgibndremote.service

[Unit]
Description=Start OSGi BND remote agent
  
[Service]
WorkingDirectory=/opt/osgi 
ExecStart=/opt/osgi/remoteagent
User=ubuntu 
Type=simple 
Restart=on-failure 
RestartSec=10 

[Install]
WantedBy=multi-user.target

Maybe you have to reload the daemon systemctl daemon-reload

After starting the service you can look at the output with the systemd journal

journalctl -u osgibndremote.service -b -e -f

and find this line

Host 0.0.0.0 29998

Remember giving 0.0.0.0 as publishing address, because default is localhost/127.0.0.1. The default does not work for remote communication between different hosts.

Firewall

For UFW

sudo ufw allow proto tcp from 10.8.0.0/24 to any port 29998,8999,4003

Configure your local launcher

The bndrun-file for you IDE should extended in the following way.

pi01 = \
	remote; \
	jdb = 8999;\
	shell = 4003;\
    host = your-host

-runremote: ${pi01}

-runpath: \
	biz.aQute.remote.launcher

Now you run this bndrun as Run as -> Bnd Native Launcher. If the connection is established you can see it in the console as headline remote - yourhost:29998 and the gogo shell should be available.

You also should notice that something happens on you remote machine journal output.

send
send
sent
rx isEnvoy
send
sent
rx redirect
send
sent
send
sent
start delay 300000
rx update
rx
resolved
end delay 299695

With Debug as -> Bnd Native Launcher you get a remote debugging session, where you can set breakpoints and walk through the execution as usual.

In the documentation you can find further possibilities to configure the remote agent.

FAQ

If the bndrun file is launched using the default launcher, you will receive a message like this:

Error: Could not find or load main class ...

Make sure you use Run as -> Bnd Native Launcher to avoid this mistake!

by Guido Grune