Universal Robots Forum

How do I start a daemon without InstallationNode?

Hello,

I have a python script, that is supposed to run in background. I want it to start always. Mydaemon sample uses Installation Node to start the daemon with a button. I want to do it during bundle activation. Is that too soon?

myUrcapDaemonService daemonService = new myUrcapDaemonService();
bundleContext.registerService(DaemonService.class, myUrcapDaemonService, null);
daemonService.getDaemonContribution().start();

Everything is fine until I put the last line in the bundle start() function.

If it is there, then this error comes up:

ERROR: Bundle com.mycompany.myurcap [192] Error starting file:/home/ur/ursim-current/.urcaps/com.mycompany.myurcap.jar (org.osgi.framework.BundleException: Activator start error in bundle com.mycompany.myurcap [192].)
java.lang.NullPointerException
    at com.mycompany.myurcap.impl.Activator.start(Activator.java:19)
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:697)
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2220)
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2138)
    at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1365)
    at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:308)
    at java.lang.Thread.run(Thread.java:701)

I defined only DaemonService, but no DaemonContribution, because MyDaemon sample also didn’t do that. I don’t see anything else done to MyDaemonService in the sample, that I don’t do to my service. Where does the DaemonContribution come from in the sample?

Please advise, anybody?

It looks to me that the InstallationNodeContribution comes from line 20 in the InstallationNodeService:

public InstallationNodeContribution createInstallationNode(URCapAPI api, DataModel model) {
    return new MyDaemonInstallationNodeContribution(daemonService, model);
}

I could be wrong, I’m still fairly new to Java.

Yes, you are right, but I am looking for Daemon contribution.

Woops, sorry I misread. I also only have a service.
However, on second look, it looks like the Daemon Contribution is defined in the service:

@Override
    public void init(DaemonContribution daemonContribution) {
        this.daemonContribution = daemonContribution;
        try {
            daemonContribution.installResource(new URL("file:com/ur/urcap/examples/mydaemon/impl/daemon/"));
        } catch (MalformedURLException e) {    }
    }

Javadoc says, that init is called when service is registered, but from what I see, first bundle activation function is complete, then init gets called.

This is output from my plugin:

MyURCap started.
init called.
getExecutable called.
getExecutable called.

I’m a bit out of my depth, but have you tried starting the daemon service instead of the contribution?

What do you mean by that? Service doesn’t have a member function start(). Contribution is member of Service.

public class Activator implements BundleActivator {
    @Override
    public void start(BundleContext bundleContext) throws Exception {
	
        ScriptLibraryDaemonService slDaemonService = new MyURCapDaemonService();
        bundleContext.registerService(DaemonService.class, slDaemonService, null);
        System.out.println("Starting MyURCap deamon");
        //slDaemonService.getDaemonContribution().start();
        System.out.println("MyURCap started.");
    }

   @Override
       public void stop(BundleContext bundleContext) throws Exception {
           System.out.println("MyURCap stopped.");
       }
}

If I uncomment the commented line, NullReference exception comes up.

Well, looks like I should have Read The Fantastic Manual, where it says explicitly:

The initial state for a daemon is STOPPED, however if it is desired, auto-start can be achieved by calling
start() in the init(DaemonContribution) method right after the daemon has had its resources installed.

2 Likes