# HG changeset patch # User herrick # Date 1546951034 18000 # Node ID 9a85a7a076ad1254a5d31b7bedf6bc6273933e90 # Parent fd4868c5fca100c39e6cee6803ad74403805908c 8216190: Remove Single Instance Service support from jpackage Reviewed-by: almatvee, kcr diff -r fd4868c5fca1 -r 9a85a7a076ad make/CompileJavaModules.gmk --- a/make/CompileJavaModules.gmk Mon Jan 07 16:43:30 2019 -0500 +++ b/make/CompileJavaModules.gmk Tue Jan 08 07:37:14 2019 -0500 @@ -393,11 +393,6 @@ ################################################################################ -jdk.jpackage.runtime_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS -jdk.jpackage.runtime_COPY += .gif .png .txt - -################################################################################ - jdk.jconsole_COPY += .gif .png jdk.jconsole_CLEAN_FILES += $(wildcard \ diff -r fd4868c5fca1 -r 9a85a7a076ad make/common/Modules.gmk --- a/make/common/Modules.gmk Mon Jan 07 16:43:30 2019 -0500 +++ b/make/common/Modules.gmk Tue Jan 08 07:37:14 2019 -0500 @@ -129,7 +129,6 @@ jdk.jdwp.agent \ jdk.pack \ jdk.jpackage \ - jdk.jpackage.runtime \ jdk.scripting.nashorn.shell \ # @@ -171,7 +170,6 @@ jdk.net \ jdk.pack \ jdk.jpackage \ - jdk.jpackage.runtime \ jdk.rmic \ jdk.scripting.nashorn \ jdk.sctp \ @@ -235,7 +233,6 @@ ifeq ($(filter $(OPENJDK_TARGET_OS), windows macosx linux), ) MODULES_FILTER += jdk.jpackage - MODULES_FILTER += jdk.jpackage.runtime endif ################################################################################ diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/package.html --- a/src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/package.html Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ - - - - - - - - jdk.jpackage.runtime - - -

Defines the runtime API used by applications packaged using the -jpackage tool.

- - diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceImpl.java --- a/src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceImpl.java Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jpackage.runtime.singleton; - -import java.net.ServerSocket; -import java.net.InetAddress; -import java.net.Socket; -import java.io.File; -import java.io.PrintStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.security.PrivilegedAction; -import java.security.AccessController; -import java.security.SecureRandom; - - -class SingleInstanceImpl { - - static final String SI_FILEDIR = getTmpDir() + File.separator - + "si" + File.separator; - static final String SI_MAGICWORD = "jpackage.singleinstance.init"; - static final String SI_ACK = "jpackage.singleinstance.ack"; - static final String SI_STOP = "jpackage.singleinstance.stop"; - static final String SI_EOF = "jpackage.singleinstance.EOF"; - - private final ArrayList siListeners = - new ArrayList<>(); - private SingleInstanceServer siServer; - - private static final SecureRandom random = new SecureRandom(); - private static volatile boolean serverStarted = false; - private static int randomNumber; - - private final Object lock = new Object(); - - static String getSingleInstanceFilePrefix(final String stringId) { - String filePrefix = stringId.replace('/','_'); - filePrefix = filePrefix.replace(':','_'); - return filePrefix; - } - - static String getTmpDir() { - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) { - return System.getProperty("user.home") - + "\\AppData\\Local\\Java\\JPackage\\tmp"; - } else if (os.contains("mac")) { - return System.getProperty("user.home") - + "/Library/Application Support/Java/JPackage/tmp"; - } else { - return System.getProperty("user.home") + "/.java/jpackage/tmp"; - } - } - - void addSingleInstanceListener(SingleInstanceListener sil, String id) { - - if (sil == null || id == null) { - return; - } - - // start a new server thread for this unique id - // first time - synchronized (lock) { - if (!serverStarted) { - SingleInstanceService.trace("unique id: " + id); - try { - siServer = new SingleInstanceServer(id); - siServer.start(); - } catch (Exception e) { - SingleInstanceService.trace( - "addSingleInstanceListener failed"); - SingleInstanceService.trace(e); - return; // didn't start - } - serverStarted = true; - } - } - - synchronized (siListeners) { - // add the sil to the arrayList - if (!siListeners.contains(sil)) { - siListeners.add(sil); - } - } - } - - class SingleInstanceServer { - - private final SingleInstanceServerRunnable runnable; - private final Thread thread; - - SingleInstanceServer(SingleInstanceServerRunnable runnable) - throws IOException { - thread = new Thread(null, runnable, "JPackageSIThread", - 0, false); - thread.setDaemon(true); - this.runnable = runnable; - } - - SingleInstanceServer(String stringId) throws IOException { - this(new SingleInstanceServerRunnable(stringId)); - } - - int getPort() { - return runnable.getPort(); - } - - void start() { - thread.start(); - } - } - - private class SingleInstanceServerRunnable implements Runnable { - - ServerSocket ss; - int port; - String stringId; - String[] arguments; - - int getPort() { - return port; - } - - SingleInstanceServerRunnable(String id) throws IOException { - stringId = id; - - // open a free ServerSocket - ss = null; - - // we should bind the server to the local InetAddress 127.0.0.1 - // port number is automatically allocated for current SI - ss = new ServerSocket(0, 0, InetAddress.getByName("127.0.0.1")); - - // get the port number - port = ss.getLocalPort(); - SingleInstanceService.trace("server port at: " + port); - - // create the single instance file with canonical home and port num - createSingleInstanceFile(stringId, port); - } - - private String getSingleInstanceFilename(final String id, - final int port) { - String name = SI_FILEDIR + getSingleInstanceFilePrefix(id) - + "_" + port; - SingleInstanceService.trace("getSingleInstanceFilename: " + name); - return name; - } - - private void removeSingleInstanceFile(final String id, final int port) { - new File(getSingleInstanceFilename(id, port)).delete(); - SingleInstanceService.trace("removed SingleInstanceFile: " - + getSingleInstanceFilename(id, port)); - } - - private void createSingleInstanceFile(final String id, final int port) { - String filename = getSingleInstanceFilename(id, port); - final File siFile = new File(filename); - final File siDir = new File(SI_FILEDIR); - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - siDir.mkdirs(); - String[] fList = siDir.list(); - if (fList != null) { - String prefix = getSingleInstanceFilePrefix(id); - for (String file : fList) { - // if file with the same prefix exist, remove it - if (file.startsWith(prefix)) { - SingleInstanceService.trace( - "file should be removed: " - + SI_FILEDIR + file); - new File(SI_FILEDIR + file).delete(); - } - } - } - - PrintStream out = null; - try { - siFile.createNewFile(); - siFile.deleteOnExit(); - // write random number to single instance file - out = new PrintStream(new FileOutputStream(siFile)); - randomNumber = random.nextInt(); - out.print(randomNumber); - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } finally { - if (out != null) { - out.close(); - } - } - return null; - } - }); - } - - @Override - public void run() { - // start sil to handle all the incoming request - // from the server port of the current url - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - List recvArgs = new ArrayList<>(); - while (true) { - recvArgs.clear(); - InputStream is = null; - BufferedReader in = null; - InputStreamReader isr = null; - Socket s = null; - String line = null; - boolean sendAck = false; - int port = -1; - String charset = null; - try { - SingleInstanceService.trace("waiting connection"); - s = ss.accept(); - is = s.getInputStream(); - // read first byte for encoding type - int encoding = is.read(); - if (encoding == - SingleInstanceService.ENCODING_PLATFORM) { - charset = Charset.defaultCharset().name(); - } else if (encoding == - SingleInstanceService.ENCODING_UNICODE) { - charset = - SingleInstanceService.ENCODING_UNICODE_NAME; - } else { - SingleInstanceService.trace( - "SingleInstanceImpl - unknown encoding"); - return null; - } - isr = new InputStreamReader(is, charset); - in = new BufferedReader(isr); - // first read the random number - line = in.readLine(); - if (line.equals(String.valueOf(randomNumber)) == - false) { - // random number does not match - // should not happen - // shutdown server socket - removeSingleInstanceFile(stringId, port); - ss.close(); - serverStarted = false; - SingleInstanceService.trace("Unexpected Error, " - + "SingleInstanceService disabled"); - return null; - } else { - line = in.readLine(); - // no need to continue reading if MAGICWORD - // did not come first - SingleInstanceService.trace("recv: " + line); - if (line.equals(SI_MAGICWORD)) { - SingleInstanceService.trace( - "got magic word."); - while (true) { - // Get input string - try { - line = in.readLine(); - if (line != null - && line.equals(SI_EOF)) { - // end of file reached - break; - } else { - recvArgs.add(line); - } - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } - } - arguments = recvArgs.toArray( - new String[recvArgs.size()]); - sendAck = true; - } else if (line.equals(SI_STOP)) { - // remove the SingleInstance file - removeSingleInstanceFile(stringId, port); - break; - } - } - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } finally { - try { - if (sendAck) { - // let the action listener handle the rest - for (String arg : arguments) { - SingleInstanceService.trace( - "Starting new instance with " - + "arguments: arg:" + arg); - } - - performNewActivation(arguments); - - // now the event is handled, we can send - // out the ACK - SingleInstanceService.trace( - "sending out ACK"); - if (s != null) { - try (OutputStream os = - s.getOutputStream(); - PrintStream ps = new PrintStream(os, - true, charset)) { - // send OK (ACK) - ps.println(SI_ACK); - ps.flush(); - } - } - } - - if (in != null) { - in.close(); - } - - if (isr != null) { - isr.close(); - } - - if (is != null) { - is.close(); - } - - if (s != null) { - s.close(); - } - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } - } - } - return null; - } - }); - } - } - - private void performNewActivation(final String[] args) { - // enumerate the sil list and call - // each sil with arguments - @SuppressWarnings("unchecked") - ArrayList silal = - (ArrayList)siListeners.clone(); - silal.forEach(sil -> sil.newActivation(args)); - } - - void removeSingleInstanceListener(SingleInstanceListener sil) { - if (sil == null) { - return; - } - - synchronized (siListeners) { - - if (!siListeners.remove(sil)) { - return; - } - - if (siListeners.isEmpty()) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - // stop server - Socket socket = null; - PrintStream out = null; - OutputStream os = null; - try { - socket = new Socket("127.0.0.1", - siServer.getPort()); - os = socket.getOutputStream(); - byte[] encoding = new byte[1]; - encoding[0] = - SingleInstanceService.ENCODING_PLATFORM; - os.write(encoding); - String charset = Charset.defaultCharset().name(); - out = new PrintStream(os, true, charset); - out.println(randomNumber); - out.println(SingleInstanceImpl.SI_STOP); - out.flush(); - serverStarted = false; - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } finally { - try { - if (out != null) { - out.close(); - } - if (os != null) { - os.close(); - } - if (socket != null) { - socket.close(); - } - } catch (IOException ioe) { - SingleInstanceService.trace(ioe); - } - } - return null; - } - }); - } - } - } -} diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceListener.java --- a/src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceListener.java Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jpackage.runtime.singleton; - -/** - * The {@code SingleInstanceListener} interface is used for implementing - * Single Instance functionality for applications packaged by jpackage. - * - * @since 13 - */ -public interface SingleInstanceListener { - - /** - * {@code newActivation()} should be implemented by the application to - * handle the single instance behavior. - * When a single instance application is running, the launcher of a - * secondary instance of that application will call {@code newActivation()} - * in the first running instance instead of launching another instance of - * the application. - * - * @param args - * Arguments from the instances of the application will be passed - * into the {@code newActivation()} method. An application developer can - * decide how to handle the arguments passed by implementating this method. - */ - public void newActivation(String... args); - -} diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceNewActivation.java --- a/src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceNewActivation.java Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jpackage.runtime.singleton; - -import java.util.Arrays; - -// This class is used for notifying Single Instance for JPackage. - -public class SingleInstanceNewActivation { - - public static void main(String[] args) { - - if (args.length < 1) { - // need to be at least pid - return; - } - - // the first arg is process id of the single instance - String appId = SingleInstanceService.APP_ID_PREFIX + args[0]; - - if (SingleInstanceService.isServerRunning(appId)) { - String[] newArgs; - if (args.length > 1) { - newArgs = Arrays.copyOfRange(args, 1, args.length); - } else { - // no application args - newArgs = new String[0]; - } - SingleInstanceService.connectToServer(newArgs); - } - } -} diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceService.java --- a/src/jdk.jpackage.runtime/share/classes/jdk/jpackage/runtime/singleton/SingleInstanceService.java Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.jpackage.runtime.singleton; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintStream; -import java.net.Socket; -import java.nio.charset.Charset; - -/** - * The {@code SingleInstanceService} class provides public methods for using - * Single Instance functionality in applications packaged by jpackage. - * To use these methods, the option named "--singleton" must - * be specified on the jpackage command line. - * - * @since 13 - */ -public class SingleInstanceService { - - static private boolean DEBUG = false; - static private PrintStream DEBUG_STREAM = null; - - static private int currPort; - static private String stringId = null; - static private String randomNumberString = null; - - static private SingleInstanceImpl instance = null; - - static final int ENCODING_PLATFORM = 1; - static final int ENCODING_UNICODE = 2; - - static final String ENCODING_PLATFORM_NAME = "UTF-8"; - static final String ENCODING_UNICODE_NAME = "UTF-16LE"; - - static final String APP_ID_PREFIX = "jpackage.si."; - - private SingleInstanceService() {} - - static void enableDebug(boolean enable, PrintStream stream) { - DEBUG = enable; - DEBUG_STREAM = stream; - } - - static void trace(String message) { - if (DEBUG && DEBUG_STREAM != null) { - DEBUG_STREAM.println(message); - } - } - - static void trace(Throwable t) { - if (DEBUG && DEBUG_STREAM != null) { - t.printStackTrace(DEBUG_STREAM); - } - } - - /** - * Adds the given slistener for the current process. - * - * If the given slistener object is null or - * has already been added, then nothing is added. - * - * @param slistener the {@code SingleInstanceListener} to add - */ - public static void addSingleInstanceListener( - SingleInstanceListener slistener) { - if (instance == null) { - synchronized(SingleInstanceService.class) { - if (instance == null) { - instance = new SingleInstanceImpl(); - } - } - } - instance.addSingleInstanceListener(slistener, - APP_ID_PREFIX + ProcessHandle.current().pid()); - } - - /** - * removes the given slistener for the current process. - * - * If the given slistener object is null or - * has not already been added, nothing is removed. - * - * @param slistener the {@code SingleInstanceListener} to remove. - */ - public static void removeSingleInstanceListener( - SingleInstanceListener slistener) { - if (instance != null) { - instance.removeSingleInstanceListener(slistener); - } - } - - /** - * Returns true if single instance server is running for the id - */ - static boolean isServerRunning(String id) { - trace("isServerRunning ? : "+ id); - File siDir = new File(SingleInstanceImpl.SI_FILEDIR); - String[] fList = siDir.list(); - if (fList != null) { - String prefix = SingleInstanceImpl.getSingleInstanceFilePrefix(id); - for (String file : fList) { - trace("isServerRunning: " + file); - trace("\t String id: " + id); - trace("\t SingleInstanceFilePrefix: " + prefix); - // if file with the same prefix already exist, server is running - if (file.startsWith(prefix)) { - try { - currPort = Integer.parseInt( - file.substring(file.lastIndexOf('_') + 1)); - trace("isServerRunning: " + file - + ": port: " + currPort); - } catch (NumberFormatException nfe) { - trace("isServerRunning: " + file - + ": port parsing failed"); - trace(nfe); - return false; - } - - trace("Server running at port: " + currPort); - File siFile = new File(SingleInstanceImpl.SI_FILEDIR, file); - - // get random number from single instance file - try (BufferedReader br = new BufferedReader( - new FileReader(siFile))) { - randomNumberString = br.readLine(); - trace("isServerRunning: " + file + ": magic: " - + randomNumberString); - } catch (IOException ioe ) { - trace("isServerRunning: " + file - + ": reading magic failed"); - trace(ioe); - } - trace("isServerRunning: " + file + ": setting id - OK"); - stringId = id; - return true; - } else { - trace("isServerRunning: " + file + ": prefix NOK"); - } - } - } else { - trace("isServerRunning: empty file list"); - } - trace("isServerRunning: false"); - return false; - } - - /** - * Returns true if we connect successfully to the server for the stringId - */ - static boolean connectToServer(String[] args) { - trace("Connect to: " + stringId + " " + currPort); - - if (randomNumberString == null) { - // should not happen - trace("MAGIC number is null, bail out."); - return false; - } - - // Now we open the tcpSocket and the stream - Socket socket = null; - OutputStream os = null; - PrintStream out = null; - InputStreamReader isr = null; - BufferedReader br = null; - try { - socket = new Socket("127.0.0.1", currPort); - os = socket.getOutputStream(); - byte[] encoding = new byte[1]; - encoding[0] = ENCODING_PLATFORM; - os.write(encoding); - String encodingName = Charset.defaultCharset().name(); - - out = new PrintStream(os, true, encodingName); - isr = new InputStreamReader(socket.getInputStream(), encodingName); - br = new BufferedReader(isr); - - // send random number - out.println(randomNumberString); - // send MAGICWORD - out.println(SingleInstanceImpl.SI_MAGICWORD); - - for (String arg : args) { - out.println(arg); - } - - // indicate end of file transmission - out.println(SingleInstanceImpl.SI_EOF); - out.flush(); - - // wait for ACK (OK) response - trace("Waiting for ack"); - final int tries = 5; - - // try to listen for ACK - for (int i=0; i < tries; i++) { - String str = br.readLine(); - if (str != null && str.equals(SingleInstanceImpl.SI_ACK)) { - trace("Got ACK"); - return true; - } - } - } catch (java.net.SocketException se) { - // no server is running - continue launch - trace("No server is running - continue launch."); - trace(se); - } catch (Exception ioe) { - trace(ioe); - } - finally { - try { - if (br != null) { - br.close(); - } - if (isr != null) { - isr.close(); - } - if (out != null) { - out.close(); - } - if (os != null) { - os.close(); - } - if (socket != null) { - socket.close(); - } - } catch (IOException ioe) { - trace(ioe); - } - } - trace("No ACK from server, bail out."); - return false; - } -} diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage.runtime/share/classes/module-info.java --- a/src/jdk.jpackage.runtime/share/classes/module-info.java Mon Jan 07 16:43:30 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * Defines the runtime API used by applications packaged using - * the jpackage tool. - * - * @moduleGraph - * @since 13 - */ -module jdk.jpackage.runtime { - exports jdk.jpackage.runtime.singleton; - -} diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm --- a/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/macosx/native/libapplauncher/MacPlatform.mm Tue Jan 08 07:37:14 2019 -0500 @@ -83,22 +83,6 @@ return TString(MAC_JPACKAGE_TMP_DIR); } -void MacPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - NSRunningApplication* app = - [NSRunningApplication runningApplicationWithProcessIdentifier: - singleInstanceProcessId]; - if (app != nil) { - [app activateWithOptions: NSApplicationActivateIgnoringOtherApps]; - } else { - printf("Unable to reactivate another instance PID: %d", - singleInstanceProcessId); - } -} - TCHAR* MacPlatform::ConvertStringToFileSystemString(TCHAR* Source, bool &release) { TCHAR* result = NULL; diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java Tue Jan 08 07:37:14 2019 -0500 @@ -202,8 +202,6 @@ out.println("app.identifier=" + IDENTIFIER.fetchFrom(params)); out.println("app.classpath=" + String.join(File.pathSeparator, CLASSPATH.fetchFrom(params).split("[ :;]"))); - out.println("app.application.instance=" + - (SINGLETON.fetchFrom(params) ? "single" : "multiple")); // The main app is required to be a jar, modular or unnamed. if (mainModule != null && diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/Arguments.java Tue Jan 08 07:37:14 2019 -0500 @@ -216,10 +216,6 @@ setOptionValue("class", popArg()); }), - SINGLETON ("singleton", OptionCategories.PROPERTY, () -> { - setOptionValue("singleton", true); - }), - NAME ("name", "n", OptionCategories.PROPERTY), IDENTIFIER ("identifier", OptionCategories.PROPERTY), diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/BundleParams.java Tue Jan 08 07:37:14 2019 -0500 @@ -102,9 +102,6 @@ // where the product will be installed. public static final String PARAM_INSTALLDIR_CHOOSER = "installdirChooser"; - // boolean - Prevents from launching multiple instances of application. - public static final String PARAM_SINGLETON = "singleton"; - /** * create a new bundle with all default values */ @@ -233,10 +230,6 @@ putUnlessNull(PARAM_INSTALLDIR_CHOOSER, b); } - public void setSingleton(Boolean b) { - putUnlessNull(PARAM_SINGLETON, b); - } - public String getName() { return fetchParam(APP_NAME); } diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/DeployParams.java Tue Jan 08 07:37:14 2019 -0500 @@ -63,7 +63,6 @@ Boolean serviceHint; Boolean signBundle; Boolean installdirChooser; - Boolean singleton; String applicationClass; @@ -115,10 +114,6 @@ this.installdirChooser = installdirChooser; } - void setSingleton(Boolean singleton) { - this.singleton = singleton; - } - void setSignBundle(Boolean signBundle) { this.signBundle = signBundle; } @@ -535,7 +530,6 @@ bundleParams.setVendor(vendor); bundleParams.setEmail(email); bundleParams.setInstalldirChooser(installdirChooser); - bundleParams.setSingleton(singleton); bundleParams.setCopyright(copyright); bundleParams.setApplicationCategory(category); bundleParams.setDescription(description); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/SecondaryLauncherArguments.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/SecondaryLauncherArguments.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/SecondaryLauncherArguments.java Tue Jan 08 07:37:14 2019 -0500 @@ -107,9 +107,6 @@ Arguments.CLIOptions.WIN_CONSOLE_HINT.getId(), getOptionValue(CLIOptions.WIN_CONSOLE_HINT)); - putUnlessNull(bundleParams, Arguments.CLIOptions.SINGLETON.getId(), - getOptionValue(CLIOptions.SINGLETON)); - String value = getOptionValue(CLIOptions.ICON); putUnlessNull(bundleParams, Arguments.CLIOptions.ICON.getId(), (value == null) ? null : new File(value)); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java Tue Jan 08 07:37:14 2019 -0500 @@ -587,16 +587,6 @@ (s, p) -> Boolean.valueOf(s) ); - static final BundlerParamInfo SINGLETON = - new StandardBundlerParam<> ( - I18N.getString("param.singleton.name"), - I18N.getString("param.singleton.description"), - Arguments.CLIOptions.SINGLETON.getId(), - Boolean.class, - params -> Boolean.FALSE, - (s, p) -> Boolean.valueOf(s) - ); - static File getPredefinedAppImage(Map p) { File applicationImage = null; if (PREDEFINED_APP_IMAGE.fetchFrom(p) != null) { diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/ValidOptions.java Tue Jan 08 07:37:14 2019 -0500 @@ -62,7 +62,6 @@ add(CLIOptions.CREATE_IMAGE, CLIOptions.INPUT); add(CLIOptions.CREATE_IMAGE, CLIOptions.OUTPUT); add(CLIOptions.CREATE_IMAGE, CLIOptions.APPCLASS); - add(CLIOptions.CREATE_IMAGE, CLIOptions.SINGLETON); add(CLIOptions.CREATE_IMAGE, CLIOptions.NAME); add(CLIOptions.CREATE_IMAGE, CLIOptions.IDENTIFIER); add(CLIOptions.CREATE_IMAGE, CLIOptions.VERBOSE); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources.properties Tue Jan 08 07:37:14 2019 -0500 @@ -97,9 +97,6 @@ \ --icon \n\ \ Path of the icon of the application bundle\n\ \ (absolute path or relative to the current directory)\n\ -\ --singleton\n\ -\ Prevents multiple instances of the application from launching\n\ -\ (see SingleInstanceService API for more details)\n\ \ --identifier \n\ \ Machine readable identifier of the application\n\ \ The format must be a DNS name in reverse order,\n\ diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties Tue Jan 08 07:37:14 2019 -0500 @@ -97,9 +97,6 @@ \ --icon \n\ \ Path of the icon of the application bundle\n\ \ (absolute path or relative to the current directory)\n\ -\ --singleton\n\ -\ Prevents multiple instances of the application from launching\n\ -\ (see SingleInstanceService API for more details)\n\ \ --identifier \n\ \ Machine readable identifier of the application\n\ \ The format must be a DNS name in reverse order,\n\ diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties Tue Jan 08 07:37:14 2019 -0500 @@ -97,9 +97,6 @@ \ --icon \n\ \ Path of the icon of the application bundle\n\ \ (absolute path or relative to the current directory)\n\ -\ --singleton\n\ -\ Prevents multiple instances of the application from launching\n\ -\ (see SingleInstanceService API for more details)\n\ \ --identifier \n\ \ Machine readable identifier of the application\n\ \ The format must be a DNS name in reverse order,\n\ diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources.properties Tue Jan 08 07:37:14 2019 -0500 @@ -119,8 +119,6 @@ param.strip-executables.description=Removes native executables from the JImage creation. param.main.module.name=Main Module param.main.module.description=The main module of the application. This module should have the main-class, and is on the module path. -param.singleton.name=Singleton -param.singleton.description=Prevents from launching multiple instances of application. param.install-dir.name=Installation Directory param.install-dir.description=Installation directory of the application. diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties Tue Jan 08 07:37:14 2019 -0500 @@ -119,8 +119,6 @@ param.strip-executables.description=Removes native executables from the JImage creation. param.main.module.name=Main Module param.main.module.description=The main module of the application. This module should have the main-class, and is on the module path. -param.singleton.name=Singleton -param.singleton.description=Prevents from launching multiple instances of application. param.install-dir.name=Installation Directory param.install-dir.description=Installation directory of the application. diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties Tue Jan 08 07:37:14 2019 -0500 @@ -119,8 +119,6 @@ param.strip-executables.description=Removes native executables from the JImage creation. param.main.module.name=Main Module param.main.module.description=The main module of the application. This module should have the main-class, and is on the module path. -param.singleton.name=Singleton -param.singleton.description=Prevents from launching multiple instances of application. param.install-dir.name=Installation Directory param.install-dir.description=Installation directory of the application. diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -41,20 +41,10 @@ #include -bool RunVM(JvmLaunchType type) { - bool result = false; +bool RunVM() { JavaVirtualMachine javavm; - switch (type){ - case USER_APP_LAUNCH: - result = javavm.StartJVM(); - break; - case SINGLE_INSTANCE_NOTIFICATION_LAUNCH: - result = javavm.NotifySingleInstance(); - break; - default: - break; - } + bool result = javavm.StartJVM(); if (!result) { Platform& platform = Platform::GetInstance(); @@ -269,30 +259,7 @@ options.AppendValue(mainModule); } - return launchVM(options, vmargs, false); -} - -bool JavaVirtualMachine::NotifySingleInstance() { - Package& package = Package::GetInstance(); - - std::list vmargs; - vmargs.push_back(package.GetCommandName()); - - JavaOptions options; - options.AppendValue(_T("-Djava.library.path"), - package.GetPackageAppDirectory() + FilePath::PathSeparator() - + package.GetPackageLauncherDirectory()); - options.AppendValue(_T("-Djava.launcher.path"), - package.GetPackageLauncherDirectory()); - // launch SingleInstanceNewActivation.main() to pass arguments to - // another instance - options.AppendValue(_T("-m")); - options.AppendValue( - _T("jdk.jpackage.runtime/jdk.jpackage.runtime.singleton.SingleInstanceNewActivation")); - - configureLibrary(); - - return launchVM(options, vmargs, true); + return launchVM(options, vmargs); } void JavaVirtualMachine::configureLibrary() { @@ -318,7 +285,7 @@ } bool JavaVirtualMachine::launchVM(JavaOptions& options, - std::list& vmargs, bool addSiProcessId) { + std::list& vmargs) { Platform& platform = Platform::GetInstance(); Package& package = Package::GetInstance(); @@ -335,15 +302,6 @@ vmargs.splice(vmargs.end(), loptions, loptions.begin(), loptions.end()); #endif - if (addSiProcessId) { - // add single instance process ID as a first argument - TProcessID pid = platform.GetSingleInstanceProcessId(); - std::ostringstream s; - s << pid; - std::string procIdStr(s.str()); - vmargs.push_back(TString(procIdStr.begin(), procIdStr.end())); - } - std::list largs = package.GetArgs(); vmargs.splice(vmargs.end(), largs, largs.begin(), largs.end()); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h --- a/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/JavaVirtualMachine.h Tue Jan 08 07:37:14 2019 -0500 @@ -30,13 +30,6 @@ #include "jni.h" #include "Platform.h" - -enum JvmLaunchType { - USER_APP_LAUNCH, - SINGLE_INSTANCE_NOTIFICATION_LAUNCH, - JVM_LAUNCH_TYPES_NUM -}; - struct JavaOptionItem { TString name; TString value; @@ -89,16 +82,14 @@ JavaLibrary javaLibrary; void configureLibrary(); - bool launchVM(JavaOptions& options, std::list& vmargs, - bool addSiProcessId); + bool launchVM(JavaOptions& options, std::list& vmargs); public: JavaVirtualMachine(); ~JavaVirtualMachine(void); bool StartJVM(); - bool NotifySingleInstance(); }; -bool RunVM(JvmLaunchType type); +bool RunVM(); #endif // JAVAVIRTUALMACHINE_H diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -166,15 +166,6 @@ return TString(LINUX_JPACKAGE_TMP_DIR); } -void LinuxPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - - const ProcessReactivator reactivator(singleInstanceProcessId); -} - TPlatformNumber LinuxPlatform::GetMemorySize() { long pages = sysconf(_SC_PHYS_PAGES); long page_size = sysconf(_SC_PAGE_SIZE); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h --- a/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/LinuxPlatform.h Tue Jan 08 07:37:14 2019 -0500 @@ -68,7 +68,6 @@ virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); - virtual void reactivateAnotherInstance(); virtual bool IsMainThread(); virtual TPlatformNumber GetMemorySize(); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h --- a/src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/MacPlatform.h Tue Jan 08 07:37:14 2019 -0500 @@ -63,7 +63,6 @@ virtual ISectionalPropertyContainer* GetConfigFile(TString FileName); virtual TString GetModuleFileName(); - virtual void reactivateAnotherInstance(); virtual bool IsMainThread(); virtual TPlatformNumber GetMemorySize(); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/Package.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/Package.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/Package.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -49,37 +49,6 @@ return result; } -bool Package::CheckForSingleInstance() { - Platform& platform = Platform::GetInstance(); -#ifdef MAC - if (platform.IsMainThread()) { - return false; - } -#endif - if (FInitialized == true) { - // everything must be initialised at this point - return false; - } - TString appName; - TString appVersion; - AutoFreePtr config = - platform.GetConfigFile(platform.GetConfigFileName()); - std::map keys = platform.GetKeys(); - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[APP_NAME_KEY], appName); - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_VERSION], appVersion); - TString singleInstance; - config->GetValue(keys[CONFIG_SECTION_APPLICATION], - keys[CONFIG_APPLICATION_INSTANCE], singleInstance); - if (singleInstance == _T("single")) { - TString uniqueID = appName + FBootFields->FAppID + appVersion; - // if another instance is running, later we can try to reactivate it - return platform.CheckForSingleInstance(uniqueID); - } - return false; -} - void Package::Initialize() { if (FInitialized == true) { return; diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/Package.h --- a/src/jdk.jpackage/share/native/libapplauncher/Package.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/Package.h Tue Jan 08 07:37:14 2019 -0500 @@ -92,7 +92,6 @@ void Initialize(); void Clear(); void FreeBootFields(); - bool CheckForSingleInstance(); void SetCommandLineArguments(int argc, TCHAR* argv[]); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/Platform.h --- a/src/jdk.jpackage/share/native/libapplauncher/Platform.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/Platform.h Tue Jan 08 07:37:14 2019 -0500 @@ -386,15 +386,12 @@ AppCDSState FAppCDSState; protected: - TProcessID singleInstanceProcessId; - - Platform(void): FAppCDSState(cdsUninitialized), singleInstanceProcessId(0) { + Platform(void): FAppCDSState(cdsUninitialized) { } public: AppCDSState GetAppCDSState() { return FAppCDSState; } void SetAppCDSState(AppCDSState Value) { FAppCDSState = Value; } - TProcessID GetSingleInstanceProcessId() { return singleInstanceProcessId; } static Platform& GetInstance(); @@ -448,8 +445,6 @@ virtual Process* CreateProcess() = 0; virtual bool IsMainThread() = 0; - virtual bool CheckForSingleInstance(TString Name) = 0; - virtual void reactivateAnotherInstance() = 0; // Returns megabytes. virtual TPlatformNumber GetMemorySize() = 0; diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -54,9 +54,6 @@ } PosixPlatform::~PosixPlatform(void) { - if (!SingleInstanceFile.empty()) { - unlink(SingleInstanceFile.c_str()); - } } TString PosixPlatform::GetTempDirectory() { @@ -82,43 +79,6 @@ return fixedName; } -// returns true if another instance is already running. -// if false, we need to continue regular launch. -bool PosixPlatform::CheckForSingleInstance(TString appName) { - TString tmpDir = GetTempDirectory(); - if (tmpDir.empty()) { - printf("Unable to check for single instance.\n"); - return false; - } - - TString lockFile = tmpDir + "/" + fixName(appName); - SingleInstanceFile = lockFile; - int pid_file = open(lockFile.c_str(), O_CREAT | O_RDWR, 0666); - int rc = flock(pid_file, LOCK_EX | LOCK_NB); - - if (rc) { - if (EWOULDBLOCK == errno) { - // another instance is running - pid_t pid = 0; - read(pid_file, (void*)&pid, sizeof(pid_t)); - printf("Another instance is running PID: %d\n", pid); - if (pid != 0) { - singleInstanceProcessId = pid; - SingleInstanceFile.clear(); - return true; - } - } else { - printf("Unable to check for single instance.\n"); - } - } else { - // It is the first instance. - pid_t pid = getpid(); - write(pid_file, (void*)&pid, sizeof(pid_t)); - } - - return false; -} - MessageResponse PosixPlatform::ShowResponseMessage(TString title, TString description) { MessageResponse result = mrCancel; diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h --- a/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/PosixPlatform.h Tue Jan 08 07:37:14 2019 -0500 @@ -33,7 +33,6 @@ class PosixPlatform : virtual public Platform { protected: - TString SingleInstanceFile; TString fixName(const TString& name); @@ -49,7 +48,6 @@ virtual void SetCurrentDirectory(TString Value); - virtual bool CheckForSingleInstance(TString Name); virtual Module LoadLibrary(TString FileName); virtual void FreeLibrary(Module AModule); virtual Procedure GetProcAddress(Module AModule, std::string MethodName); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -292,114 +292,6 @@ return TRUE; } -void WindowsPlatform::reactivateAnotherInstance() { - if (singleInstanceProcessId == 0) { - printf("Unable to reactivate another instance, PID is undefined"); - return; - } - EnumWindows(&enumWindows, (LPARAM)singleInstanceProcessId); -} - -// returns true if another instance is already running. -// if false, we need to continue regular launch. -bool WindowsPlatform::CheckForSingleInstance(TString name) { - if (SingleInstance::getInstance(name)->IsAnotherInstanceRunning()) { - // read PID - DWORD pid = SingleInstance::getInstance(name)->readPid(); - if (pid != 0) { - singleInstanceProcessId = pid; - return true; - } - } else { - // it is the first intance - // write pid and continue regular launch - SingleInstance::getInstance(name)->writePid(GetCurrentProcessId()); - } - return false; -} - -SingleInstance::SingleInstance(TString& name_): BUF_SIZE(256), _name(name_), - _hMapFile(NULL), _pBuf(NULL) { - _mutex = CreateMutex(NULL, TRUE, name_.data()); - _lastError = GetLastError(); - _sharedMemoryName = _T("Local\\jpackage-") + _name; -} - -SingleInstance::~SingleInstance() { - if (_pBuf != NULL) { - UnmapViewOfFile(_pBuf); - _pBuf = NULL; - } - - if (_hMapFile != NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - } - - if (_mutex != NULL) { - CloseHandle(_mutex); - _mutex = NULL; - } -} - -bool SingleInstance::writePid(DWORD pid) { - _hMapFile = CreateFileMapping( - INVALID_HANDLE_VALUE, - NULL, - PAGE_READWRITE, - 0, - BUF_SIZE, - _sharedMemoryName.data()); - - if (_hMapFile == NULL) { - return false; - } - - _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, - FILE_MAP_ALL_ACCESS, - 0, - 0, - BUF_SIZE); - - if (_pBuf == NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - return false; - } - - CopyMemory((PVOID)_pBuf, &pid, sizeof(DWORD)); - - return true; -} - -DWORD SingleInstance::readPid() { - _hMapFile = OpenFileMapping( - FILE_MAP_ALL_ACCESS, - FALSE, - _sharedMemoryName.data()); - - if (_hMapFile == NULL) { - return 0; - } - - _pBuf = (LPTSTR) MapViewOfFile(_hMapFile, - FILE_MAP_ALL_ACCESS, - 0, - 0, - BUF_SIZE); - - if (_pBuf == NULL) { - CloseHandle(_hMapFile); - _hMapFile = NULL; - return 0; - } - - DWORD pid = 0; - CopyMemory(&pid, (PVOID)_pBuf, sizeof(DWORD)); - - return pid; -} - TPlatformNumber WindowsPlatform::GetMemorySize() { SYSTEM_INFO si; GetSystemInfo(&si); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h --- a/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/WindowsPlatform.h Tue Jan 08 07:37:14 2019 -0500 @@ -34,44 +34,6 @@ #include - -// the class is used to create and detect single instance of user application -class SingleInstance { -private: - const int BUF_SIZE; - - DWORD _lastError; - HANDLE _mutex; - TString _name; - TString _sharedMemoryName; - HANDLE _hMapFile; - LPCTSTR _pBuf; - - SingleInstance(): BUF_SIZE(0) {} - - SingleInstance(TString& name_); - -public: - static SingleInstance* getInstance(TString& name) { - static SingleInstance* result = NULL; - - if (result == NULL) { - result = new SingleInstance(name); - } - - return result; - } - - ~SingleInstance(); - - bool IsAnotherInstanceRunning() { - return (ERROR_ALREADY_EXISTS == _lastError); - } - - bool writePid(DWORD pid); - DWORD readPid(); -}; - #pragma warning( push ) // C4250 - 'class1' : inherits 'class2::member' #pragma warning( disable : 4250 ) @@ -111,9 +73,7 @@ virtual Process* CreateProcess(); - virtual void reactivateAnotherInstance(); virtual bool IsMainThread(); - virtual bool CheckForSingleInstance(TString Name); virtual TPlatformNumber GetMemorySize(); virtual TString GetTempDirectory(); diff -r fd4868c5fca1 -r 9a85a7a076ad src/jdk.jpackage/share/native/libapplauncher/main.cpp --- a/src/jdk.jpackage/share/native/libapplauncher/main.cpp Mon Jan 07 16:43:30 2019 -0500 +++ b/src/jdk.jpackage/share/native/libapplauncher/main.cpp Tue Jan 08 07:37:14 2019 -0500 @@ -116,15 +116,6 @@ package.SetCommandLineArguments(argc, argv); platform.SetCurrentDirectory(package.GetPackageAppDirectory()); - if (package.CheckForSingleInstance()) { - // reactivate the first instance if the process Id is valid - platform.reactivateAnotherInstance(); - if (platform.GetSingleInstanceProcessId() != 0) { - return RunVM(SINGLE_INSTANCE_NOTIFICATION_LAUNCH); - } - return true; - } - switch (platform.GetAppCDSState()) { case cdsDisabled: case cdsUninitialized: @@ -204,7 +195,7 @@ } // Run App - result = RunVM(USER_APP_LAUNCH); + result = RunVM(); } catch (FileNotFoundException &e) { platform.ShowMessage(e.GetMessage()); }