JDK-8175574 : Singleton App
  • Type: New Feature
  • Component: deploy
  • Sub-Component: packager
  • Affected Version: 10
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • Fix Versions: 10
  • Submitted: 2017-02-23
  • Updated: 2017-05-30
  • Resolved: 2017-05-30
Related Reports
Blocks :  
Duplicate :  
Relates :  
Sub Tasks
JDK-8179955 :  
Description
Windows and Linux by default launch another instance of the application. This request is that there be only one instance. That instance must be brought to be the front window. If launched with file associations those arguments need to be passed to the already running application. A Java Packager API must be provided to access those arguments. The same API will be available for Mac since Mac already does this but the current API is tough to use and we want one API. The API will allow the application to register to receive notifications of file associations.
Comments
New webrev: http://cr.openjdk.java.net/~vdrozdov/JDK-8175574/webrev.04/ Added some new comments, optimisations, renamed some variables. Added getTmpDir() for SingleInstanceImpl, because System.getProperty("java.io.tmpdir") is not appropriate solution as user may change TMP var.
12-04-2017

New webrev: http://cr.openjdk.java.net/~vdrozdov/JDK-8175574/webrev.03 added flag "boolean setFileHandler" for SingleInstanceService.registerSingleInstance(SingleInstanceListener si). There are two methods now: 79 public static void registerSingleInstance(SingleInstanceListener slistener) { 80 registerSingleInstance(slistener, true); 81 } 82 83 public static void registerSingleInstance(SingleInstanceListener slistener, 84 boolean setFileHandler) { 85 String appId = APP_ID_PREFIX + ProcessHandle.current().getPid(); 86 registerSingleInstanceForId(slistener, appId, setFileHandler); 87 }
11-04-2017

New webrev: http://cr.openjdk.java.net/~vdrozdov/JDK-8175574/webrev.02/ For the latest implementation: 1) User must always specify "-singleton" if need single instance. 2) If user wants to pass args to the existing instance, in addition to specifying "-singleton" they need to: a) implement SingleInstanceListener (override newActivation(..)) b) add "SingleInstanceService.registerSingleInstance(SingleInstanceListener si)" and "SingleInstanceService.unregisterSingleInstance(SingleInstanceListener si)" in the java code
10-04-2017

New webrev: http://cr.openjdk.java.net/~vdrozdov/JDK-8175574/webrev.01/ Added new option "-singleInstance". So currently we have two ways of single intance implementation: 1) Light version, that does not require modificatoin of user's java code. We just add "-singleInstance" (should we rather use "-simpleSingleInstance" ??). This way, we reactivate first instance and just perform exit(0) in second(new) instance. Easy to use, but no way to pass args to existings java process. 2) Usage of jdk.packager.services.singleton from jdk.packager.service module. This way we can override "public void newActivation(String[] params);" from SingleInstanceListener, add code for registering/unregistering/checking for single isntance in user's code (preferrable, method main()). User can specify any actions they want in newActivation(), like reactiovation of the main window, reactivation of another tab of app, some kind of silent actions, etc. But it will require user's code modification and recompilation. In case if users selects 2), then "-singleInstance" should NOT be used (because we just prevent from starting new java process in the launcher).
03-04-2017

I wanted this in the native code so it happens as quick as possible and the developer doesn't have to write any code, they simply specify a javapackager option -singleinstance (or something) that would add: [Application] app.singleinstance=true to the .cfg file. I think I sent you a patch with a prototype of this that wasn't complete yet? This property should be read in Package::Initialize. Then very early on once the other instance is found, we pass all CLI arguments to the other process via native code, focus the other app and bring it to front and terminate. If the developer wants to get the arguments then they need to use the SingleInstanceService and write some code and the SingleInstanceService will read the data from through JLI.
14-03-2017

We can add new class to jdk.packager.services, for example, SingleInstanceService. User will need to register the app in main() using special string id (we can use app name as well), something like SingleInstanceService.addSingleInstanceListener(this, STRING_ID). Every launch, before registering, user should check SingleInstanceService.isAppRunning(STRING_ID) (if true, we can System.exit(0) in our java code). There could be something like "void newActivation(String[] params)" for overriding to specify action if relaunching with new args. All of this can be described in docs.
14-03-2017