From d2fa11cd10a849579c2e726d679aea9e8487ef4b Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Mon, 28 Oct 2013 21:54:31 +0200 Subject: [PATCH] Fixes false reports on Windows that Jitsi has crashed. --- .../impl/shutdowntimeout/ShutdownTimeout.java | 152 +++++++++------ .../shutdown.timeout.manifest.mf | 3 +- .../launcher/SIPCommunicator.java | 97 +++++----- .../util/launchutils/DeleteOnHaltHook.java | 67 +++++++ .../util/launchutils/SipCommunicatorLock.java | 178 ++++++++---------- 5 files changed, 293 insertions(+), 204 deletions(-) create mode 100644 src/net/java/sip/communicator/util/launchutils/DeleteOnHaltHook.java diff --git a/src/net/java/sip/communicator/impl/shutdowntimeout/ShutdownTimeout.java b/src/net/java/sip/communicator/impl/shutdowntimeout/ShutdownTimeout.java index 5a912fbcb..17fa961f8 100644 --- a/src/net/java/sip/communicator/impl/shutdowntimeout/ShutdownTimeout.java +++ b/src/net/java/sip/communicator/impl/shutdowntimeout/ShutdownTimeout.java @@ -7,21 +7,23 @@ package net.java.sip.communicator.impl.shutdowntimeout; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.launchutils.*; import org.osgi.framework.*; /** - * In order to shut down SIP Communicator we kill the Felix system bundle. - * However, this sometimes doesn't work for reason of running non-daemon - * threads (such as the javasound event dispatcher). This results in having - * instances of SIP Communicator running in the background. + * In order to shut down Jitsi, we kill the Felix system bundle. However, this + * sometimes doesn't work for reason of running non-daemon threads (such as the + * Java Sound event dispatcher). This results in having instances of Jitsi + * running in the background. * - * We use this shutdown timout bundle in order to fix this problem. When our + * We use this shutdown timeout bundle in order to fix this problem. When our * stop method is called, we assume that a shutdown is executed and start a 15 * seconds daemon thread. If the application is still running once these 15 * seconds expire, we System.exit() the application. * * @author Emil Ivov + * @author Lyubomir Marinov */ public class ShutdownTimeout implements BundleActivator @@ -32,25 +34,90 @@ public class ShutdownTimeout /** * The system property which can be used to set custom timeout. */ - public static String SHUTDOWN_TIMEOUT_PROP = - "org.jitsi.shutdown.SHUTDOWN_TIMEOUT"; + private static final String SHUTDOWN_TIMEOUT_PNAME + = "org.jitsi.shutdown.SHUTDOWN_TIMEOUT"; /** - * The number of miliseconds that we wait before we force a shutdown. + * The number of milliseconds that we wait before we force a shutdown. */ - public static final long SHUTDOWN_TIMEOUT_DEFAULT = 5000;//ms + private static final long SHUTDOWN_TIMEOUT_DEFAULT = 5000;//ms /** * The code that we exit with if the application is not down in 15 seconds. */ - public static final int SYSTEM_EXIT_CODE = 500; + private static final int SYSTEM_EXIT_CODE = 500; + + /** + * Runs in a daemon thread started by {@link #stop(BundleContext)} and + * forcibly terminates the currently running Java virtual machine after + * {@link #SHUTDOWN_TIMEOUT_DEFAULT} (or {@link #SHUTDOWN_TIMEOUT_PNAME}) + * milliseconds. + */ + private static void runInShutdownTimeoutThread() + { + long shutdownTimeout = SHUTDOWN_TIMEOUT_DEFAULT; + + // Check for a custom value specified through a System property. + try + { + String s = System.getProperty(SHUTDOWN_TIMEOUT_PNAME); + + if ((s != null) && (s.length() > 0)) + { + long l = Long.valueOf(s); + + // Make sure custom is not 0 to prevent waiting forever. + if (l > 0) + shutdownTimeout = l; + } + } + catch(Throwable t) + { + } + + if (logger.isTraceEnabled()) + { + logger.trace( + "Starting shutdown countdown of " + shutdownTimeout + + "ms."); + } + try + { + Thread.sleep(shutdownTimeout); + } + catch (InterruptedException ex) + { + if (logger.isDebugEnabled()) + logger.debug("Interrupted shutdown timer."); + return; + } + + /* + * We are going to forcibly terminate the currently running Java virtual + * machine so it will not run DeleteOnExitHook. But the currently + * running Java virtual machine is still going to terminate because of + * our intention, not because it has crashed. Make sure that we delete + * any files registered for deletion when Runtime.halt(int) is to be + * invoked. + */ + try + { + DeleteOnHaltHook.runHooks(); + } + catch (Throwable t) + { + logger.warn("Failed to delete files on halt.", t); + } + + logger.error("Failed to gently shutdown. Forcing exit."); + Runtime.getRuntime().halt(SYSTEM_EXIT_CODE); + } /** * Dummy impl of the bundle activator start method. * * @param context unused - * @throws Exception If this method throws an exception - * (which won't happen). + * @throws Exception if this method throws an exception (which won't happen) */ public void start(BundleContext context) throws Exception @@ -64,63 +131,26 @@ public void start(BundleContext context) * bundle-specific activities necessary to stop the bundle. * * @param context The execution context of the bundle being stopped. - * @throws Exception If this method throws an exception, the bundle is - * still marked as stopped, and the Framework will remove the bundle's - * listeners, unregister all services registered by the bundle, and - * release all services used by the bundle. + * @throws Exception If this method throws an exception, the bundle is still + * marked as stopped, and the Framework will remove the bundle's listeners, + * unregister all services registered by the bundle, and release all + * services used by the bundle. */ public void stop(BundleContext context) throws Exception { - Thread shutdownTimeoutThread = new Thread() - { - @Override - public void run() + Thread shutdownTimeoutThread + = new Thread() { - synchronized(this) + @Override + public void run() { - try - { - - long shutDownTimeout = SHUTDOWN_TIMEOUT_DEFAULT; - - // check for custom value available through system - // property - try - { - String shutdownCustomValue = - System.getProperty(SHUTDOWN_TIMEOUT_PROP); - - if(shutdownCustomValue != null - && shutdownCustomValue.length() > 0) - { - long custom = - Long.valueOf(shutdownCustomValue); - - // make sure custom is not 0, or it will - // wait forever - if(custom > 0) - shutDownTimeout = custom; - } - } - catch(Throwable t){} - - if (logger.isTraceEnabled()) - logger.trace("Starting shutdown countdown of " - + shutDownTimeout + "ms."); - wait(shutDownTimeout); - logger.error("Failed to gently shutdown. Forcing exit."); - Runtime.getRuntime().halt(SYSTEM_EXIT_CODE); - }catch (InterruptedException ex){ - if (logger.isDebugEnabled()) - logger.debug("Interrupted shutdown timer."); - } + runInShutdownTimeoutThread(); } - } - }; - if (logger.isTraceEnabled()) - logger.trace("Created the shutdown timer thread."); + }; + shutdownTimeoutThread.setDaemon(true); + shutdownTimeoutThread.setName(ShutdownTimeout.class.getName()); shutdownTimeoutThread.start(); } } diff --git a/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf b/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf index 6991b2f39..a0f1a1d1f 100644 --- a/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf +++ b/src/net/java/sip/communicator/impl/shutdowntimeout/shutdown.timeout.manifest.mf @@ -6,4 +6,5 @@ Bundle-Version: 0.0.1 System-Bundle: yes Import-Package: org.osgi.framework, org.jitsi.service.configuration, - net.java.sip.communicator.util + net.java.sip.communicator.util, + net.java.sip.communicator.util.launchutils diff --git a/src/net/java/sip/communicator/launcher/SIPCommunicator.java b/src/net/java/sip/communicator/launcher/SIPCommunicator.java index 006294ff2..fb5672983 100644 --- a/src/net/java/sip/communicator/launcher/SIPCommunicator.java +++ b/src/net/java/sip/communicator/launcher/SIPCommunicator.java @@ -25,41 +25,44 @@ public class SIPCommunicator { /** - * The name of the property that stores our home dir location. + * Legacy home directory names that we can use if current dir name is the + * currently active name (overridableDirName). */ - public static final String PNAME_SC_HOME_DIR_LOCATION = - "net.java.sip.communicator.SC_HOME_DIR_LOCATION"; + private static final String[] LEGACY_DIR_NAMES + = { ".sip-communicator", "SIP Communicator" }; /** - * The name of the property that stores our home dir name. + * Name of the possible configuration file names (used under macosx). */ - public static final String PNAME_SC_HOME_DIR_NAME = - "net.java.sip.communicator.SC_HOME_DIR_NAME"; + private static final String[] LEGACY_CONFIGURATION_FILE_NAMES + = { + "sip-communicator.properties", + "jitsi.properties", + "sip-communicator.xml", + "jitsi.xml" + }; /** * The currently active name. */ - private static String overridableDirName = "Jitsi"; + private static final String OVERRIDABLE_DIR_NAME = "Jitsi"; /** - * Legacy home directory names that we can use if current dir name - * is the currently active name (overridableDirName). + * The name of the property that stores our home dir location. */ - private static String[] legacyDirNames = - {".sip-communicator", "SIP Communicator"}; + public static final String PNAME_SC_HOME_DIR_LOCATION + = "net.java.sip.communicator.SC_HOME_DIR_LOCATION"; /** - * Name of the possible configuration file names (used under macosx). + * The name of the property that stores our home dir name. */ - private static String[] legacyConfigurationFileNames = - {"sip-communicator.properties", "jitsi.properties", - "sip-communicator.xml", "jitsi.xml"}; + public static final String PNAME_SC_HOME_DIR_NAME + = "net.java.sip.communicator.SC_HOME_DIR_NAME"; /** * Starts the SIP Communicator. * * @param args command line args if any - * * @throws Exception whenever it makes sense. */ public static void main(String[] args) @@ -79,12 +82,18 @@ public static void main(String[] args) setScHomeDir(osName); // this needs to be set before any DNS lookup is run - File f = new File(System.getProperty(PNAME_SC_HOME_DIR_LOCATION), - System.getProperty(PNAME_SC_HOME_DIR_NAME) - + File.separator + ".usednsjava"); + File f + = new File( + System.getProperty(PNAME_SC_HOME_DIR_LOCATION), + System.getProperty(PNAME_SC_HOME_DIR_NAME) + + File.separator + + ".usednsjava"); if(f.exists()) + { System.setProperty( - "sun.net.spi.nameservice.provider.1", "dns,dnsjava"); + "sun.net.spi.nameservice.provider.1", + "dns,dnsjava"); + } if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") || vmVendor.startsWith("Free")) @@ -162,7 +171,7 @@ else if (osName.startsWith("Windows")) * wrappers to call it. * * @param osName the name of the OS according to which the SC_HOME_DIR_* - * properties are to be set + * properties are to be set */ static void setScHomeDir(String osName) { @@ -188,8 +197,8 @@ static void setScHomeDir(String osName) // 2) if such is forced and is the overridableDirName check it // (the later is the case with name transition SIP Communicator // -> Jitsi, check them only for Jitsi) - boolean chekLegacyDirNames = (name == null) || - name.equals(overridableDirName); + boolean chekLegacyDirNames + = (name == null) || name.equals(OVERRIDABLE_DIR_NAME); if (osName.startsWith("Mac")) { @@ -234,28 +243,25 @@ && new File(defaultLocation, defaultName).isDirectory()) name = defaultName; } - // if we need to check legacy names and there is no - // current home dir already created + // if we need to check legacy names and there is no current home dir + // already created if(chekLegacyDirNames - && !checkHomeFolderExist(location, name, osName)) + && !checkHomeFolderExist(location, name, osName)) { - // now check whether some of the legacy dir names - // exists, and use it if exist - for(int i = 0; i < legacyDirNames.length; i++) + // now check whether a legacy dir name exists and use it + for(String dir : LEGACY_DIR_NAMES) { // check the platform specific directory - if(checkHomeFolderExist( - location, legacyDirNames[i], osName)) + if(checkHomeFolderExist(location, dir, osName)) { - name = legacyDirNames[i]; + name = dir; break; } // now check it and in the default location - if(checkHomeFolderExist( - defaultLocation, legacyDirNames[i], osName)) + if(checkHomeFolderExist(defaultLocation, dir, osName)) { - name = legacyDirNames[i]; + name = dir; location = defaultLocation; break; } @@ -271,13 +277,12 @@ && new File(defaultLocation, defaultName).isDirectory()) } /** - * Checks whether home folder exists. - * Special situation checked under macosx, due to created folder - * of the new version of the updater we may end up with our - * settings in 'SIP Communicator' folder and having 'Jitsi' folder - * created by the updater(its download location). - * So we check not only the folder exist but whether it contains - * any of the known configuration files in it. + * Checks whether home folder exists. Special situation checked under + * macosx, due to created folder of the new version of the updater we may + * end up with our settings in 'SIP Communicator' folder and having 'Jitsi' + * folder created by the updater(its download location). So we check not + * only the folder exist but whether it contains any of the known + * configuration files in it. * * @param parent the parent folder * @param name the folder name to check. @@ -285,17 +290,15 @@ && new File(defaultLocation, defaultName).isDirectory()) * @return whether folder exists. */ static boolean checkHomeFolderExist( - String parent, String name, String osName) + String parent, String name, String osName) { if(osName.startsWith("Mac")) { - for(int i = 0; i < legacyConfigurationFileNames.length; i++) + for(String f : LEGACY_CONFIGURATION_FILE_NAMES) { - if(new File(new File(parent, name) - , legacyConfigurationFileNames[i]).exists()) + if(new File(new File(parent, name), f).exists()) return true; } - return false; } diff --git a/src/net/java/sip/communicator/util/launchutils/DeleteOnHaltHook.java b/src/net/java/sip/communicator/util/launchutils/DeleteOnHaltHook.java new file mode 100644 index 000000000..32b1cd5cb --- /dev/null +++ b/src/net/java/sip/communicator/util/launchutils/DeleteOnHaltHook.java @@ -0,0 +1,67 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.util.launchutils; + +import java.io.*; +import java.util.*; + +/** + * In the fashion of java.io.DeleteOnExitHook, provides a way to delete + * files when Runtime.halt(int) is to be invoked. + * + * @author Lyubomir Marinov + */ +public class DeleteOnHaltHook +{ + /** + * The set of files to be deleted when Runtime.halt(int) is to be + * invoked. + */ + private static Set files = new LinkedHashSet(); + + /** + * Adds a file to the set of files to be deleted when + * Runtime.halt(int) is to be invoked. + * + * @param file the name of the file to be deleted when + * Runtime.halt(int) is to be invoked + */ + public static synchronized void add(String file) + { + if (files == null) + throw new IllegalStateException("Shutdown in progress."); + else + files.add(file); + } + + /** + * Deletes the files which have been registered for deletion when + * Runtime.halt(int) is to be invoked. + */ + public static void runHooks() + { + Set files; + + synchronized (DeleteOnHaltHook.class) + { + files = DeleteOnHaltHook.files; + DeleteOnHaltHook.files = null; + } + + if (files != null) + { + List toBeDeleted = new ArrayList(files); + + Collections.reverse(toBeDeleted); + for (String filename : toBeDeleted) + new File(filename).delete(); + } + } + + /** Prevents the initialization of DeleteOnHaltHook instances. */ + private DeleteOnHaltHook() {} +} diff --git a/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java b/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java index e6d8b813f..33b0fb922 100644 --- a/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java +++ b/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java @@ -15,20 +15,20 @@ import net.java.sip.communicator.util.*; /** - * This class is used to prevent from running multiple instances of Jitsi. - * The class binds a socket somewhere on the localhost domain and - * records its socket address in the Jitsi configuration directory. + * This class is used to prevent from running multiple instances of Jitsi. The + * class binds a socket somewhere on the localhost domain and records its socket + * address in the Jitsi configuration directory. * - * All following instances of Jitsi (and hence this class) will look - * for this record in the configuration directory and try to connect to the - * original instance through the socket address in there. + * All following instances of Jitsi (and hence this class) will look for this + * record in the configuration directory and try to connect to the original + * instance through the socket address in there. * * @author Emil Ivov */ public class SipCommunicatorLock extends Thread { - private static final Logger logger = Logger - .getLogger(SipCommunicatorLock.class); + private static final Logger logger + = Logger.getLogger(SipCommunicatorLock.class); /** * Indicates that something went wrong. More information will probably be @@ -44,8 +44,8 @@ public class SipCommunicatorLock extends Thread /** * Returned by the soft start method to indicate that an instance of Jitsi - * has been already started and we should exit. This return - * code also indicates that all arguments were passed to that new instance. + * has been already started and we should exit. This return code also + * indicates that all arguments were passed to that new instance. */ public static final int ALREADY_STARTED = 301; @@ -112,11 +112,11 @@ public class SipCommunicatorLock extends Thread private static final long LOCK_FILE_READ_WAIT = 500; /** - * An address that is reported not local on macosx and is - * assigned as default on loopback interface. + * An address that is reported not local on macosx and is assigned as + * default on loopback interface. */ - private static final String WEIRD_MACOSX_LOOPBACK_ADDRESS = - "fe80:0:0:0:0:0:0:1"; + private static final String WEIRD_MACOSX_LOOPBACK_ADDRESS + = "fe80:0:0:0:0:0:0:1"; /** * Tries to lock the configuration directory. If lock-ing is not possible @@ -124,17 +124,14 @@ public class SipCommunicatorLock extends Thread * list of args to that running instance. *

* There are three possible outcomes of this method. 1. We lock - * successfully; 2. We fail to lock because another instance of Jitsi - * is already running; 3. We fail to lock for some unknown - * error. Each of these cases is represented by an error code returned as a - * result. - * - * @param args - * the array of arguments that we are to submit in case an - * instance of Jitsi has already been started. + * successfully; 2. We fail to lock because another instance of Jitsi is + * already running; 3. We fail to lock for some unknown error. Each of these + * cases is represented by an error code returned as a result. * + * @param args the array of arguments that we are to submit in case an + * instance of Jitsi has already been started. * @return an error or success code indicating the outcome of the lock - * operation. + * operation. */ public int tryLock(String[] args) { @@ -172,10 +169,8 @@ public int tryLock(String[] args) * not return the ALREADY_RUNNING code as it is assumed that this has * already been checked before calling this method. * - * @param lockFile - * the file that we should use to lock the configuration - * directory. - * + * @param lockFile the file that we should use to lock the configuration + * directory. * @return the SUCCESS or ERROR codes defined by this class. */ private int lock(File lockFile) @@ -215,6 +210,7 @@ private int lock(File lockFile) } lockFile.deleteOnExit(); + DeleteOnHaltHook.add(lockFile.getAbsolutePath()); writeLockFile(lockFile, serverSocketAddress); @@ -227,7 +223,7 @@ private int lock(File lockFile) * other instances of Jitsi that are trying to start. * * @return the ERROR code if something goes wrong and - * SUCCESS otherwise. + * SUCCESS otherwise. */ private int startLockServer(InetSocketAddress localAddress) { @@ -268,7 +264,7 @@ private int startLockServer(InetSocketAddress localAddress) * on. * * @return an InetAddress (most probably a loopback) that we can use to bind - * our semaphore socket on. + * our semaphore socket on. */ private InetAddress getRandomBindAddress() { @@ -334,13 +330,12 @@ private int getRandomPortNumber() } /** - * Calls reading of the lock file, retrying if there is - * nothing written in it. + * Calls reading of the lock file, retrying if there is nothing written in + * it. * * @param lockFile the file that we are to parse. - * * @return the SocketAddress that we should use to communicate with - * a possibly already running version of Jitsi. + * a possibly already running version of Jitsi. */ private InetSocketAddress readLockFileRetrying(File lockFile) { @@ -372,11 +367,9 @@ private InetSocketAddress readLockFileRetrying(File lockFile) * contents of lockFile and asserts presence of all properties * mandated by this version. * - * @param lockFile - * the file that we are to parse. - * + * @param lockFile the file that we are to parse. * @return the SocketAddress that we should use to communicate with - * a possibly already running version of Jitsi. + * a possibly already running version of Jitsi. */ private InetSocketAddress readLockFile(File lockFile) { @@ -435,29 +428,28 @@ private InetSocketAddress readLockFile(File lockFile) * Records our lockAddress into lockFile using the * standard properties format. * - * @param lockFile - * the file that we should store the address in. - * @param lockAddress - * the address that we have to record. - * + * @param lockFile the file that we should store the address in. + * @param lockAddress the address that we have to record. * @return SUCCESS upon success and ERROR if we fail to - * store the file. + * store the file. */ private int writeLockFile(File lockFile, InetSocketAddress lockAddress) { Properties lockProperties = new Properties(); - lockProperties.setProperty(PNAME_LOCK_ADDRESS, lockAddress.getAddress() - .getHostAddress()); - - lockProperties.setProperty(PNAME_LOCK_PORT, Integer - .toString(lockAddress.getPort())); + lockProperties.setProperty( + PNAME_LOCK_ADDRESS, + lockAddress.getAddress().getHostAddress()); + lockProperties.setProperty( + PNAME_LOCK_PORT, + Integer.toString(lockAddress.getPort())); try { - lockProperties.store(new FileOutputStream(lockFile), - "Jitsi lock file. This file will be automatically" - + "removed when execution of Jitsi terminates."); + lockProperties.store( + new FileOutputStream(lockFile), + "Jitsi lock file. This file will be automatically removed" + + " when execution of Jitsi terminates."); } catch (FileNotFoundException e) { @@ -470,7 +462,6 @@ private int writeLockFile(File lockFile, InetSocketAddress lockAddress) } return SUCCESS; - } /** @@ -482,15 +473,15 @@ private int writeLockFile(File lockFile, InetSocketAddress lockAddress) */ private File getLockFile() { - String homeDirLocation = System - .getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_LOCATION); - String homeDirName = System - .getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_NAME); - + String homeDirLocation + = System.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_LOCATION); + String homeDirName + = System.getProperty(SIPCommunicator.PNAME_SC_HOME_DIR_NAME); String fileSeparator = System.getProperty("file.separator"); - - String fullLockFileName = homeDirLocation + fileSeparator + homeDirName - + fileSeparator + LOCK_FILE_NAME; + String fullLockFileName + = homeDirLocation + fileSeparator + + homeDirName + fileSeparator + + LOCK_FILE_NAME; return new File(fullLockFileName); } @@ -500,13 +491,11 @@ private File getLockFile() * addressStr or null if no such address exists on the * local interfaces. * - * @param addressStr - * the address string that we are trying to resolve into an - * InetAddress - * + * @param addressStr the address string that we are trying to resolve into + * an InetAddress * @return an InetAddress instance corresponding to - * addressStr or null if none of the local - * interfaces has such an address. + * addressStr or null if none of the local interfaces has + * such an address. */ private InetAddress findLocalAddress(String addressStr) { @@ -549,7 +538,6 @@ private InetAddress findLocalAddress(String addressStr) * * @param sockAddr the address that we are to connect to. * @param args the args that we need to send to sockAddr. - * * @return SUCCESS upond success and ERROR if anything * goes wrong. */ @@ -604,12 +592,12 @@ private int interInstanceConnect(InetSocketAddress sockAddr, String[] args) /** * We use this thread to communicate with an already running instance of - * Jitsi. This thread will listen for a reply to a message that we've - * sent to the other instance. We will wait for this message for a maximum - * of runDuration milliseconds and then consider the remote - * instance dead. + * Jitsi. This thread will listen for a reply to a message that we've sent + * to the other instance. We will wait for this message for a maximum of + * runDuration milliseconds and then consider the remote instance + * dead. */ - private class LockClient extends Thread + private static class LockClient extends Thread { /** * The String that we've read from the socketInputStream @@ -619,14 +607,13 @@ private class LockClient extends Thread /** * The socket that this LockClient is created to read from. */ - private Socket interInstanceSocket = null; + private final Socket interInstanceSocket; /** * Creates a LockClient that should read whatever data we * receive on sockInputStream. * - * @param commSocket - * the socket that this client should be reading from. + * @param commSocket the socket that this client should be reading from. */ public LockClient(Socket commSocket) { @@ -640,8 +627,8 @@ public LockClient(Socket commSocket) * Blocks until a reply has been received or until runDuration * milliseconds had passed. * - * @param runDuration the number of seconds to wait for a reply from - * the remote instance + * @param runDuration the number of seconds to wait for a reply from the + * remote instance */ public void waitForReply(long runDuration) { @@ -694,32 +681,35 @@ public void run() // does not necessarily mean something is wrong. Could be // that we got tired of waiting and want to quit. if (logger.isInfoEnabled()) - logger.info("An IOException is thrown while reading sock", exc); + { + logger.info( + "An IOException is thrown while reading sock", + exc); + } } } } /** - * We start this thread when running Jitsi as a means of - * notifying others that this is + * We start this thread when running Jitsi as a means of notifying others + * that this is */ - private class LockServer extends Thread + private static class LockServer extends Thread { private boolean keepAccepting = true; /** * The socket that we use for cross instance lock and communication. */ - private ServerSocket lockSocket = null; + private final ServerSocket lockSocket; /** * Creates an instance of this LockServer wrapping the * specified serverSocket. It is expected that the serverSocket * will be already bound and ready to accept. * - * @param serverSocket - * the serverSocket that we should use for inter instance - * communication. + * @param serverSocket the serverSocket that we should use for inter + * instance communication. */ public LockServer(ServerSocket serverSocket) { @@ -764,9 +754,8 @@ private static class LockServerConnectionProcessor extends Thread * would handle parameters received through the * connectionSocket. * - * @param connectionSocket - * the socket that we will be using to read arguments from - * the remote Jitsi instance. + * @param connectionSocket the socket that we will be using to read + * arguments from the remote Jitsi instance. */ public LockServerConnectionProcessor(Socket connectionSocket) { @@ -857,13 +846,12 @@ else if (line.startsWith(ARGUMENT)) /** * Determines whether or not the iface interface is a loopback * interface. We use this method as a replacement to the - * NetworkInterface.isLoopback() method that only comes with - * java 1.6. + * NetworkInterface.isLoopback() method that only comes with Java + * 1.6. * * @param iface the inteface that we'd like to determine as loopback or not. - * - * @return true if iface contains at least one loopback address - * and false otherwise. + * @return true if iface contains at least one loopback address and + * false otherwise. */ private boolean isLoopbackInterface(NetworkInterface iface) { @@ -886,8 +874,8 @@ private boolean isLoopbackInterface(NetworkInterface iface) { InetAddress address = addresses.nextElement(); if(address.isLoopbackAddress() - || address.getHostAddress() - .startsWith(WEIRD_MACOSX_LOOPBACK_ADDRESS)) + || address.getHostAddress().startsWith( + WEIRD_MACOSX_LOOPBACK_ADDRESS)) return true; }