How to start another instance of my app within the app?

As title. I have the needs to start other instances of my running app from my app.

I have a button on my snap app’s UI that invoce this command: snap run myappid If I run it in devmode it works well, my app can successfully spawn another instance of the app.

If I put it in stric mode it doesn’t work anymore even if I add the
desktop-launch plug-

Is there a way to start other instances of my app within my app itself when running in stric mode? This is even possible with flatpak, I can’t believe that it’s not possible with snap.

Any help will be appreciated :slight_smile: Thanks

Use dbus to do so. snap run <snap_name> is not really meant to be used that way. Can you kindly share the source-code with us if possible?

Is there any reason you can not just make the button execute the command: directly? It would run in the same sandbox and should be executable the same way as the main instance of your app …

thanks for the answer. sure the code of the project is open source, here it is:

this is the java method that runs the snap run myappid command, it uses the java Runtime.getRuntime().exec() method.

Do I really need to use DBUS just to restart my app? Isn’t there an easyer way? If dbus is the only option I’ll try to understand how to do it with dbus, thanks.

Have you considered creating something like flatpak-spawn? https://docs.flatpak.org/en/latest/flatpak-command-reference.html#flatpak-spawn

what do you mean exactly? what command should I execute?

You mean, why I want to spawn other instances of my app? Because it is an ambient light app, it can control lot of devices and having a separate instance for device can be convenient.

thanks for the answer, I appreciate it.

I’m sorry if this a naiive question, but if your application is running inside the sandbox, do you want simply start another instance if your process within the existing sandbox, or a new process with a new sandbox?

If it’s the the former, there’s nothing more you need to do. Just run the process like it’s described within meta/snap.yaml (snapcraft.yaml).

However, if it’s the latter, I’m afraid you will need to go through the portal, assuming it provides an API for that. I’m assuming that if it works with flatpak, then there is one in place already, otherwise I can’t imagine flatpak would allow a process within a sandbox spawn another process outside the sandbox. I any case I don’t know the details of how it works with flatpak (maybe it’s really doing the first scenario I described), but in any case it’s worth investigating what’s under the hood.

A crazy though, but maybe you could use portals OpenURI for this OpenURI - XDG Desktop Portal documentation assuming your app sets up with a uri handler.

1 Like

Flatpak spawning does exactly this… process outside sandbox. You can spawn inside sandbox too… but there is nothing stopping you from doing the first.

I’m sure there’s more to it. Why would one bother with a sandbox if it was that simple?

You don’t need snap run myappid… just normally executing myappid will do the job.

Like here

I executed this from within the snap’s sandbox.

1 Like

that is exactly what I was searching for. I just need to spawn another instance of my app in the sandbox.

I’m trying to do my homework on Snap and Snapcraft but I’m still a newby.

thanks for the answer guys, this is much appreciated.

can’t wait to publish my apps on the Snap store.

2 Likes

Just thought I’d ass this to cover both bases, for the purpose of spawning your app in a completely new instance of the sandbox, equivilent of running snap run $snap, the trick for this is to have a .desktop file that registers a custom protocol handler, something like my-snap-open://, your snap can then run xdg-open my-snap-open://, which is ferried back to snapd or the portals, which will then open it from the outside. I’m not sure if this works headlessly, but it should be able to work with CLI apps running in a GUI session by setting Terminal=True if needed

(Said desktop file can be set to Hidden=True if you don’t really want one visible.)

1 Like

I correct myself, this works well if running the command manually once entered the sandbox with snap run --shell myappid

but if I run that from my app does not start another instance of my app. it doesn’t return an error. it simply do nothing.

I would not like to overturn my app just for the snap store, is there an easy way to simply restart my app once running on snap?

I don’t care if restarting the app outisde, inside the sandbox, I don’t care how, I want to do it simple :slight_smile:

Can you share the code that you’re doing? With some debug logs may be? So, that I can debug what’s happening? Not a java expert :sweat:

the code is here:

but the very simple command I run to try to start another instance of the software is this: Runtime.getRuntime().exec(“FireflyLuciferin”)

and here the yaml:

Just ran snap run --shell ohmygiraffe and can run as many ‘ohmygiraffe’ instances as I like. I’m finding it hard to guess that the problem could be. There’s nothing stopping your application from running any executable within your snap., including another instance of your application.

Can you share the error you’re getting?

snap run can be runned only on non stric confinement. with strict confinement snap command can’t be accessed within the app.

obviously I don’t wan to remove the strict confinement just because I want to spawn other instances of my app, this does not have sense.

I made a comment on this before. You do not need to invoke snap run at all. If your app is already running, simply exec another instance of $SNAP/bin/FireflyLuciferin.

@mborzecki1 your suggestion does not work here. If I run snap run --shell myappid from a bash console and then run $SNAP/bin/FireflyLuciferin it works well…

if I try to run $SNAP/bin/FireflyLuciferin directly from my app, it does not work. the commands returns with no error but no app is spawned.

does this works for your app? are you sure that it works? :slight_smile:

run a --shell, start 2 instances of $SNAP/bin/FireflyLuciferin:

maciek@galeon:work$ snap run --shell fireflyluciferin
[maciek@galeon work]$ $SNAP/bin/FireflyLuciferin &
[1] 88601
[maciek@galeon work]$ WARNING: Using incubator modules: jdk.incubator.vector
WARNING: Unknown module: org.dpsoftware specified to --enable-native-access
11:32:51,081 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic version ?
11:32:51,081 |-INFO in ch.qos.logback.classic.util.ContextInitializer@576d5deb - No custom configurators were discovered as a service.
11:32:51,081 |-INFO in ch.qos.logback.classic.util.ContextInitializer@576d5deb - Trying to configure with ch.qos.logback.classic.joran.SerializedModelConfigurator
11:32:51,082 |-INFO in ch.qos.logback.classic.util.ContextInitializer@576d5deb - Constructed
...
CLEAN EXIT
Exception in Application constructor
Exception in thread "main" java.lang.RuntimeException: Unable to construct Application instance: class org.dpsoftware.FireflyLuciferin
        at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:883)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
        at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:795)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:483)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456)
        at java.base/java.security.AccessController.doPrivileged(Unknown Source)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
        at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
        at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$10(GtkApplication.java:264)
        ... 1 more
Caused by: java.lang.NullPointerException: Cannot invoke "org.dpsoftware.config.Configuration.setLanguage(String)" because "org.dpsoftware.MainSingleton.getInstance().config" is null
        at org.dpsoftware.FireflyLuciferin.manageLocale(FireflyLuciferin.java:418)
        at org.dpsoftware.FireflyLuciferin.<init>(FireflyLuciferin.java:108)
        ... 12 more

[maciek@galeon work]$
[maciek@galeon work]$ $SNAP/bin/FireflyLuciferin &
[2] 88755
[maciek@galeon work]$ WARNING: Using incubator modules: jdk.incubator.vector
WARNING: Unknown module: org.dpsoftware specified to --enable-native-access
11:32:54,527 |-INFO in ch.qos.logback.classic.LoggerContext[default] - This is logback-classic ....

[maciek@galeon work]$
[maciek@galeon work]$

and I have 2 processes running, started from shell, within since sandbox:

[maciek@galeon work]$ ps
    PID TTY          TIME CMD
  87203 ?        00:00:00 zsh
  88463 ?        00:00:00 bash
  88601 ?        00:00:02 FireflyLuciferi
  88755 ?        00:00:02 FireflyLuciferi
  88910 ?        00:00:00 ps

@mborzecki1 can you try to read what I have wrote before please?

if I manually run the $SNAP/bin/FireflyLuciferin command in a shell once entered the sandbox with snap run --shell fireflyluciferin it works.

if I run the $SNAP/bin/FireflyLuciferin command within my app it does not work.