Restrict multiple instances of an application in java
Asked Answered
C

8

8

I want to prevent multiple instances of application being launched in java. I know 2 methods for this:

  1. locking file
  2. locking socket

But which is one is more efficient and good to use? Which one should I use?

Any other solution to do the same are also welcome.

Circulate answered 26/5, 2011 at 6:42 Comment(3)
which file? which socket? what makes the most sense for the app?Maighdlin
@jcomeau_ictx: can use any file/any socket which is available.Circulate
Does this answer your question? Prevent launching multiple instances of a java applicationVisualize
K
1

EDIT: I tried that with Win200864b(version isn't important) and alive JFrame and move toFront() or Iconified in SystemTray with JFrame.DO_NOTHING_ON_CLOSE

    public interface ApplicationStartedListener {

        void applicationStarted();

        void foreignApplicationStarted(String name);

        void messageArrived(Object obj);
    }

//

    import java.io.Serializable;

    public class ClassCheck implements Serializable {

        private static final long serialVersionUID = 1L;
        private String className = null;

        public ClassCheck() {
        }

        public ClassCheck(String className) {
            setClassName(className);
        }

        @Override
        public String toString() {
            return this.className;
        }

        public String getClassName() {
            return this.className;
        }

        public void setClassName(String className) {
            this.className = className;
        }
    }
//

    import java.awt.AWTException;
    import java.awt.BorderLayout;
    import java.awt.Frame;
    import java.awt.MouseInfo;
    import java.awt.Point;
    import java.awt.Robot;
    import java.awt.event.InputEvent;
    import java.io.File;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class RunOnceFromFile {

        private SingleInstanceController sic = null;
        private JFrame frame;
        private Robot r;
        private JTextField tf;

        public RunOnceFromFile() {
            try {
                r = new Robot();
            } catch (AWTException ex) {
                ex.printStackTrace();
            }
            sic = new SingleInstanceController(new File(System.getProperty("java.io.tmpdir") + "Example.file"), "sic_example_application");
            if (sic.isOtherInstanceRunning()) {
                sic.sendMessageToRunningApplication("toFront");
                System.exit(0);
            } else {
                frame = new JFrame("TEST");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 300);
                tf = new JTextField("JTextFiled");
                frame.add(tf, BorderLayout.NORTH);
                frame.setExtendedState(Frame.ICONIFIED);
                frame.setExtendedState(Frame.NORMAL);
                frame.setExtendedState(frame.getExtendedState() | JFrame.ICONIFIED);
                frame.setExtendedState(frame.getExtendedState() & (~JFrame.ICONIFIED));
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                sic.registerApplication();
                sic.addApplicationStartedListener(new ApplicationStartedListener() {

                    public void applicationStarted() {
                        Runnable doRun = new Runnable() {

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    public void foreignApplicationStarted(final String name) {
                        Runnable doRun = new Runnable() {

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    public void messageArrived(final Object obj) {
                        Runnable doRun = new Runnable() {//activateWindow(frame);

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    private void activateWindow(JFrame frame) {
                        frame.setExtendedState(Frame.ICONIFIED);
                        frame.setExtendedState(Frame.NORMAL);
                        frame.setAlwaysOnTop(true);
                        frame.setAlwaysOnTop(false);
                        Point location = MouseInfo.getPointerInfo().getLocation();
                        Point locationOnScreen = frame.getLocationOnScreen();
                        r.mouseMove(locationOnScreen.x + 100, locationOnScreen.y + 10);
                        r.mousePress(InputEvent.BUTTON1_MASK);
                        r.mouseRelease(InputEvent.BUTTON1_MASK);
                        r.mouseMove(location.x, location.y);
                    }
                });
            }
        }

        public static void main(String[] args) {
            RunOnceFromFile roff = new RunOnceFromFile();
        }
    }
//

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;

    public class SingleInstanceController {

        private String appname = null;
        private Socket client = null;
        private File file = null;
        private ArrayList<ApplicationStartedListener> listener = null;
        private ObjectInputStream ois = null;
        private ObjectOutputStream oos = null;
        private boolean result = false;
        private ServerSocket server = null;

        public SingleInstanceController(String appname) {
            this(new File(System.getProperty("java.io.tmpdir") + "/923jhakE53Kk9235b43.6m7"), appname);
        }

        public SingleInstanceController(File file, String appname) {
            this.file = file;
            this.appname = appname;
            this.listener = new ArrayList<ApplicationStartedListener>();
        }

        public void addApplicationStartedListener(ApplicationStartedListener asl) {
            this.listener.add(asl);
        }

        public void removeApplicationStartedListener(ApplicationStartedListener asl) {
            this.listener.remove(asl);
        }

        public boolean isOtherInstanceRunning() {
            if (!this.file.exists()) {
                return false;
            }
            return sendMessageToRunningApplication(new ClassCheck(this.appname));
        }

        public boolean sendMessageToRunningApplication(final Object obj) {
            this.result = false;
            try {
                this.client = new Socket("localhost", getPortNumber());
                new Thread(new Runnable() {

                    public void run() {
                        try {
                            SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
                            SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
                            SingleInstanceController.this.oos.writeObject(obj);
                            SingleInstanceController.this.oos.flush();
                            SingleInstanceController.this.result = SingleInstanceController.this.ois.readBoolean();
                        } catch (IOException e) {
                            SingleInstanceController.this.result = false;
                        }
                    }
                }).start();
                for (int i = 0; i < 10; i++) {
                    if (this.result == true) {
                        break;
                    }
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                this.client.close();
                return this.result;
            } catch (IOException e) {
                return false;
            }
        }

        public boolean registerApplication() {
            try {
                if (!this.file.exists()) {
                    if (!this.file.getParentFile().mkdirs() && !this.file.getParentFile().exists()) {
                        return false;
                    }
                    if (!this.file.createNewFile()) {
                        return false;
                    }
                }
                BufferedWriter wuffy = new BufferedWriter(new FileWriter(this.file));
                int port = getFreeServerSocket();
                if (port != -1) {
                    startServer();
                }
                wuffy.write(String.valueOf(port));
                wuffy.close();
                return true;
            } catch (IOException e) {
                return false;
            }
        }

        protected void messageArrived(Object obj) {
            for (ApplicationStartedListener asl : this.listener) {
                asl.messageArrived(obj);
            }
        }

        protected void applicationStartet() {
            for (ApplicationStartedListener asl : this.listener) {
                asl.applicationStarted();
            }
        }

        protected void foreignApplicationStarted(String name) {
            for (ApplicationStartedListener asl : this.listener) {
                asl.foreignApplicationStarted(name);
            }
        }

        private int getPortNumber() {
            try {
                BufferedReader buffy = new BufferedReader(new FileReader(this.file));
                int port = Integer.parseInt(buffy.readLine().trim());
                buffy.close();
                return port;
            } catch (Exception e) {
                return -1;
            }
        }

        private void startServer() {
            new Thread(new Runnable() {

                public void run() {
                    while (true) {
                        try {
                            SingleInstanceController.this.client = SingleInstanceController.this.server.accept();
                            if (SingleInstanceController.this.client.getInetAddress().isLoopbackAddress()) {
                                new Thread(new Runnable() {

                                    public void run() {
                                        try {
                                            SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
                                            SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
                                            Object obj = SingleInstanceController.this.ois.readObject();
                                            if (obj instanceof ClassCheck) {
                                                if (obj.toString().equals(SingleInstanceController.this.appname)) {
                                                    SingleInstanceController.this.oos.writeBoolean(true);
                                                    applicationStartet();
                                                } else {
                                                    SingleInstanceController.this.oos.writeBoolean(false);
                                                    foreignApplicationStarted(obj.toString());
                                                }
                                            } else {
                                                messageArrived(obj);
                                                SingleInstanceController.this.oos.writeBoolean(true);
                                            }
                                            SingleInstanceController.this.oos.flush();
                                            SingleInstanceController.this.client.close();
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        } catch (ClassNotFoundException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }).start();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }

        private int getFreeServerSocket() {
            for (int i = 2000; i < 10000; i++) {
                try {
                    this.server = new ServerSocket(i);
                    return i;
                } catch (IOException ignore) {
                }
            }
            return -1;
        }
    }
Kailyard answered 26/5, 2011 at 13:55 Comment(17)
What does this all things do?Circulate
What happens when I close the single running instance? The file used to lock not get deleted at that time. And also at running time the file is also not properly locked cause user can delete file by going in temp directory.Circulate
@Harry Joy "user can delete file by going in temp directory" yes that's correct, because not all PC users have admin access on OS, and you have to check how ServerSocket worksKailyard
@mKorbel: what is the use of call sendMessageToRunningApplication("toFront")? what does it do?Circulate
@Harry Joy if is file (if JVM exist) locked by ServerSocket, then notify already running aplications (if you set JFrame.DO_NOTHING_ON_CLOSE, then you have to add frame.set*Visibel(true), too) frame.toFront();Kailyard
@Harry Joy which changes :-), maybe is about your implementations, maybe is about changes important for codes stable, can you little bit more concreteKailyard
@mKorbel: it gives exception "Port out of range -1" in getPortNumber() method. why?Circulate
@Harry Joy System.out.print(port); always returns 2000 on 1st. App startUp, then 100times just with 20002000BUILD SUCCESSFUL (total time: 1 second) from winXp/Java 1.6.025, Win2008_64/Java 1.6.024, what did you changed,Kailyard
@mKorbel: I have added a fileLock to file.Circulate
@Harry Joy this idea doesn't make me sense, because if I debug that that ServerSocket helt "Pointer" on this file if concrete JVM instance exist, that isn't about if File exist or notKailyard
@mKorbel: while debugging I saw that buffy.readLine() is null in method getPortNumber(). This is what I have added before getting bufferreader byffy in registerApplication() method: this.fileChannel = new RandomAccessFile(this.fileToBeLocked, "rw").getChannel(); this.fileLock = this.fileChannel.tryLock(); if (this.fileLock == null) { // File is lock by other application this.fileChannel.close(); throw new RuntimeException( "Only 1 instance of Jogge Talk can run.");} ShutdownHook shutdownHook = new ShutdownHook(); Runtime.getRuntime().addShutdownHook(shutdownHook);Circulate
@Harry Joy 1/ public static void main(String[] args) { GuiFrame gf = new GuiFrame(); } 2) public GuiFrame() { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { testSic(); } }); } 3) follows with unchanged code 4) why ShutdownHook, really if you close App with System.exit(0); then ServerSocket doesn't exists too, why complicate simple thingsKailyard
@mKorbel: ShutdownHook is to remove the file lock that I have added on system exit.Circulate
@Harry Joy ...continue... 5) if is there real reason for that, then start Timer and check if File exist, 6) *** way *** or just let File in append Mode, then isn't possible to delete it from Native OS, if JVM died, File could be free again ..., :-) note correct way it to avoid to complicated that, and result of test code == created Fatal error from code to the JVM instance, you'll seeKailyard
@mKorbel: How to make file in append mode?Circulate
@Harry Joy download.oracle.com/javase/tutorial/essential/io/file.html or java2s.com/Code/Java/File-Input-Output/…Kailyard
What abort a multi-user system, where tmp file is in a common area. Then only one user can use it.Acid
R
4

There is a library called jUnique which does that and will save you the bother of implementing it yourself.

Referent answered 26/5, 2011 at 6:47 Comment(2)
can I embed jUnique to my app without any permission or have to buy it?Circulate
The author states it as being free, but requests a donation if you find it useful. Seems reasonable.Referent
H
2

If you deploy with Java WebStart the SingleInstanceService does this.

See http://download.oracle.com/javase/6/docs/technotes/guides/javaws/developersguide/faq.html#218

Hols answered 26/5, 2011 at 6:49 Comment(0)
E
1

My vote goes to locking on a port (i think this is what you mean by socket). I don't know the exact reason for this. But in fact i come across only this as a solution in most practical projects. Though i will be happy to hear the alternative ways.

Euterpe answered 26/5, 2011 at 6:45 Comment(1)
Locking a Socket has no overhead once the application has started. It uses about 4 lines of code. The advantage is the second instance can communicate with the first e.g. say you want to open a file with the second instance, it can send a message to the first to open the file instead before exiting.Puerperium
C
1

In response to your question, the port solution will keep more resources from the machine:
- You will keep a port locked: ports are limited and you may find problems with firewalls or other programs listening on the same port.
- You'll need an active thread.

The file solution will use less resources from the machine, to avoid locking the file forever you need to add a thread, to delete the file, in the addShutdownHook method from Runtime.

Colorific answered 26/5, 2011 at 7:43 Comment(0)
K
1

EDIT: I tried that with Win200864b(version isn't important) and alive JFrame and move toFront() or Iconified in SystemTray with JFrame.DO_NOTHING_ON_CLOSE

    public interface ApplicationStartedListener {

        void applicationStarted();

        void foreignApplicationStarted(String name);

        void messageArrived(Object obj);
    }

//

    import java.io.Serializable;

    public class ClassCheck implements Serializable {

        private static final long serialVersionUID = 1L;
        private String className = null;

        public ClassCheck() {
        }

        public ClassCheck(String className) {
            setClassName(className);
        }

        @Override
        public String toString() {
            return this.className;
        }

        public String getClassName() {
            return this.className;
        }

        public void setClassName(String className) {
            this.className = className;
        }
    }
//

    import java.awt.AWTException;
    import java.awt.BorderLayout;
    import java.awt.Frame;
    import java.awt.MouseInfo;
    import java.awt.Point;
    import java.awt.Robot;
    import java.awt.event.InputEvent;
    import java.io.File;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;

    public class RunOnceFromFile {

        private SingleInstanceController sic = null;
        private JFrame frame;
        private Robot r;
        private JTextField tf;

        public RunOnceFromFile() {
            try {
                r = new Robot();
            } catch (AWTException ex) {
                ex.printStackTrace();
            }
            sic = new SingleInstanceController(new File(System.getProperty("java.io.tmpdir") + "Example.file"), "sic_example_application");
            if (sic.isOtherInstanceRunning()) {
                sic.sendMessageToRunningApplication("toFront");
                System.exit(0);
            } else {
                frame = new JFrame("TEST");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 300);
                tf = new JTextField("JTextFiled");
                frame.add(tf, BorderLayout.NORTH);
                frame.setExtendedState(Frame.ICONIFIED);
                frame.setExtendedState(Frame.NORMAL);
                frame.setExtendedState(frame.getExtendedState() | JFrame.ICONIFIED);
                frame.setExtendedState(frame.getExtendedState() & (~JFrame.ICONIFIED));
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                sic.registerApplication();
                sic.addApplicationStartedListener(new ApplicationStartedListener() {

                    public void applicationStarted() {
                        Runnable doRun = new Runnable() {

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    public void foreignApplicationStarted(final String name) {
                        Runnable doRun = new Runnable() {

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    public void messageArrived(final Object obj) {
                        Runnable doRun = new Runnable() {//activateWindow(frame);

                            public void run() {
                                frame.toFront();
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }

                    private void activateWindow(JFrame frame) {
                        frame.setExtendedState(Frame.ICONIFIED);
                        frame.setExtendedState(Frame.NORMAL);
                        frame.setAlwaysOnTop(true);
                        frame.setAlwaysOnTop(false);
                        Point location = MouseInfo.getPointerInfo().getLocation();
                        Point locationOnScreen = frame.getLocationOnScreen();
                        r.mouseMove(locationOnScreen.x + 100, locationOnScreen.y + 10);
                        r.mousePress(InputEvent.BUTTON1_MASK);
                        r.mouseRelease(InputEvent.BUTTON1_MASK);
                        r.mouseMove(location.x, location.y);
                    }
                });
            }
        }

        public static void main(String[] args) {
            RunOnceFromFile roff = new RunOnceFromFile();
        }
    }
//

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;

    public class SingleInstanceController {

        private String appname = null;
        private Socket client = null;
        private File file = null;
        private ArrayList<ApplicationStartedListener> listener = null;
        private ObjectInputStream ois = null;
        private ObjectOutputStream oos = null;
        private boolean result = false;
        private ServerSocket server = null;

        public SingleInstanceController(String appname) {
            this(new File(System.getProperty("java.io.tmpdir") + "/923jhakE53Kk9235b43.6m7"), appname);
        }

        public SingleInstanceController(File file, String appname) {
            this.file = file;
            this.appname = appname;
            this.listener = new ArrayList<ApplicationStartedListener>();
        }

        public void addApplicationStartedListener(ApplicationStartedListener asl) {
            this.listener.add(asl);
        }

        public void removeApplicationStartedListener(ApplicationStartedListener asl) {
            this.listener.remove(asl);
        }

        public boolean isOtherInstanceRunning() {
            if (!this.file.exists()) {
                return false;
            }
            return sendMessageToRunningApplication(new ClassCheck(this.appname));
        }

        public boolean sendMessageToRunningApplication(final Object obj) {
            this.result = false;
            try {
                this.client = new Socket("localhost", getPortNumber());
                new Thread(new Runnable() {

                    public void run() {
                        try {
                            SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
                            SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
                            SingleInstanceController.this.oos.writeObject(obj);
                            SingleInstanceController.this.oos.flush();
                            SingleInstanceController.this.result = SingleInstanceController.this.ois.readBoolean();
                        } catch (IOException e) {
                            SingleInstanceController.this.result = false;
                        }
                    }
                }).start();
                for (int i = 0; i < 10; i++) {
                    if (this.result == true) {
                        break;
                    }
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                this.client.close();
                return this.result;
            } catch (IOException e) {
                return false;
            }
        }

        public boolean registerApplication() {
            try {
                if (!this.file.exists()) {
                    if (!this.file.getParentFile().mkdirs() && !this.file.getParentFile().exists()) {
                        return false;
                    }
                    if (!this.file.createNewFile()) {
                        return false;
                    }
                }
                BufferedWriter wuffy = new BufferedWriter(new FileWriter(this.file));
                int port = getFreeServerSocket();
                if (port != -1) {
                    startServer();
                }
                wuffy.write(String.valueOf(port));
                wuffy.close();
                return true;
            } catch (IOException e) {
                return false;
            }
        }

        protected void messageArrived(Object obj) {
            for (ApplicationStartedListener asl : this.listener) {
                asl.messageArrived(obj);
            }
        }

        protected void applicationStartet() {
            for (ApplicationStartedListener asl : this.listener) {
                asl.applicationStarted();
            }
        }

        protected void foreignApplicationStarted(String name) {
            for (ApplicationStartedListener asl : this.listener) {
                asl.foreignApplicationStarted(name);
            }
        }

        private int getPortNumber() {
            try {
                BufferedReader buffy = new BufferedReader(new FileReader(this.file));
                int port = Integer.parseInt(buffy.readLine().trim());
                buffy.close();
                return port;
            } catch (Exception e) {
                return -1;
            }
        }

        private void startServer() {
            new Thread(new Runnable() {

                public void run() {
                    while (true) {
                        try {
                            SingleInstanceController.this.client = SingleInstanceController.this.server.accept();
                            if (SingleInstanceController.this.client.getInetAddress().isLoopbackAddress()) {
                                new Thread(new Runnable() {

                                    public void run() {
                                        try {
                                            SingleInstanceController.this.oos = new ObjectOutputStream(SingleInstanceController.this.client.getOutputStream());
                                            SingleInstanceController.this.ois = new ObjectInputStream(SingleInstanceController.this.client.getInputStream());
                                            Object obj = SingleInstanceController.this.ois.readObject();
                                            if (obj instanceof ClassCheck) {
                                                if (obj.toString().equals(SingleInstanceController.this.appname)) {
                                                    SingleInstanceController.this.oos.writeBoolean(true);
                                                    applicationStartet();
                                                } else {
                                                    SingleInstanceController.this.oos.writeBoolean(false);
                                                    foreignApplicationStarted(obj.toString());
                                                }
                                            } else {
                                                messageArrived(obj);
                                                SingleInstanceController.this.oos.writeBoolean(true);
                                            }
                                            SingleInstanceController.this.oos.flush();
                                            SingleInstanceController.this.client.close();
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        } catch (ClassNotFoundException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }).start();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }

        private int getFreeServerSocket() {
            for (int i = 2000; i < 10000; i++) {
                try {
                    this.server = new ServerSocket(i);
                    return i;
                } catch (IOException ignore) {
                }
            }
            return -1;
        }
    }
Kailyard answered 26/5, 2011 at 13:55 Comment(17)
What does this all things do?Circulate
What happens when I close the single running instance? The file used to lock not get deleted at that time. And also at running time the file is also not properly locked cause user can delete file by going in temp directory.Circulate
@Harry Joy "user can delete file by going in temp directory" yes that's correct, because not all PC users have admin access on OS, and you have to check how ServerSocket worksKailyard
@mKorbel: what is the use of call sendMessageToRunningApplication("toFront")? what does it do?Circulate
@Harry Joy if is file (if JVM exist) locked by ServerSocket, then notify already running aplications (if you set JFrame.DO_NOTHING_ON_CLOSE, then you have to add frame.set*Visibel(true), too) frame.toFront();Kailyard
@Harry Joy which changes :-), maybe is about your implementations, maybe is about changes important for codes stable, can you little bit more concreteKailyard
@mKorbel: it gives exception "Port out of range -1" in getPortNumber() method. why?Circulate
@Harry Joy System.out.print(port); always returns 2000 on 1st. App startUp, then 100times just with 20002000BUILD SUCCESSFUL (total time: 1 second) from winXp/Java 1.6.025, Win2008_64/Java 1.6.024, what did you changed,Kailyard
@mKorbel: I have added a fileLock to file.Circulate
@Harry Joy this idea doesn't make me sense, because if I debug that that ServerSocket helt "Pointer" on this file if concrete JVM instance exist, that isn't about if File exist or notKailyard
@mKorbel: while debugging I saw that buffy.readLine() is null in method getPortNumber(). This is what I have added before getting bufferreader byffy in registerApplication() method: this.fileChannel = new RandomAccessFile(this.fileToBeLocked, "rw").getChannel(); this.fileLock = this.fileChannel.tryLock(); if (this.fileLock == null) { // File is lock by other application this.fileChannel.close(); throw new RuntimeException( "Only 1 instance of Jogge Talk can run.");} ShutdownHook shutdownHook = new ShutdownHook(); Runtime.getRuntime().addShutdownHook(shutdownHook);Circulate
@Harry Joy 1/ public static void main(String[] args) { GuiFrame gf = new GuiFrame(); } 2) public GuiFrame() { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { testSic(); } }); } 3) follows with unchanged code 4) why ShutdownHook, really if you close App with System.exit(0); then ServerSocket doesn't exists too, why complicate simple thingsKailyard
@mKorbel: ShutdownHook is to remove the file lock that I have added on system exit.Circulate
@Harry Joy ...continue... 5) if is there real reason for that, then start Timer and check if File exist, 6) *** way *** or just let File in append Mode, then isn't possible to delete it from Native OS, if JVM died, File could be free again ..., :-) note correct way it to avoid to complicated that, and result of test code == created Fatal error from code to the JVM instance, you'll seeKailyard
@mKorbel: How to make file in append mode?Circulate
@Harry Joy download.oracle.com/javase/tutorial/essential/io/file.html or java2s.com/Code/Java/File-Input-Output/…Kailyard
What abort a multi-user system, where tmp file is in a common area. Then only one user can use it.Acid
J
0

the serversocket solution is cross-platform . And will not be vulnerable to the program crashing and not resetting the lock.

Jordonjorey answered 26/5, 2011 at 6:53 Comment(0)
U
0

File lock is better way to do- imo. When you create the file in User's Home directory, this will still work in a multi-user environment.

I came across - JUnique - haven't had a chance to use it http://www.sauronsoftware.it/projects/junique/manual.php

Undine answered 26/5, 2011 at 6:54 Comment(0)
A
0

I know that this question is pretty old, but I have to solve the same problem at the moment. I prefer the socket solution because I have never thought that such kind of task should have anything to do with the file system. It is better to solve the problem in memory and not in the file system I think.

Anticipate answered 18/2, 2013 at 19:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.