Command Line Interface and Locking User Directory
$Revision: 1.2 $Changes: available in CVS
Status: issue 32054
Abstract:
NetBeans currently do not prevent two instances to be executed at once which can lead to certain problems for users and they shall be at least warned that something wrong is possibly going on and also NetBeans do not provide unified system for command line arguments and does not support its extensibility by installed modules. This proposal discusses solution to both these problems.
Requirements
- Warn user when more than one instance of NetBeans is
starting (Done).
- Remove module dependent code from general
launcher.
Currently there is a support for
-open
parameter that is delegated toutilities.jar
module. If we separate platform from the NetBeans IDE (as discussed in installation proposal) this will have to be replaced by some more general mechanism (Done). - Modules should be able to register their own
extensions to the command line interface. So the
-open
argument can be added by a module and does not need to be hardcoded. (possibe, but not stable API yet). - There shall be a default way for communication
with the running IDE.
This is necessary for scripts that open a file or query the system in
other ways. They need to identify that an IDE is running and start
a talk to it (possibe, but not stable API yet).
- Make the -open command work well on multiuser
computers. Currently it works only on single user workstations as it
relies on a fixed port number. We need to make it working on multi
user UNIXes as well (Done).
Content
Locking User Directory
Start of the First Instance
Immediatelly after startup the launcher will try to create alock
file in user directory: $nbuser/lock
. If the creation succeeds, the
launcher continues to run and allocates a java.net.ServerSocket
on
local machine and starts listening on it. After that it writes the port number,
plus some randomly generated key into the lock file. To prevent problems
with shared directories between multiple computers, also the local IP of the
computer is written to the file.
When the application is about to exit, it stops listening on the port and
deletes the lock file (or the file can be marked as deleteOnExit
).
Start of the Second Instance
When a second instance of the NetBeans is executed over the same user dir, it fails to create the lock file, so instead of launching second instance of NetBeans it opens the file and reads its content to find out the port and secret key for communication with the running NetBeans instance. When read (but this may fail as well, see next section) the launcher connects to the specified port on localhost (may fail as well), verifies that the running instance recognizes the secret key and if so, it refuses to start new instance of NetBeans over this directory.Failures
- File exists, but its content is empty. This can happen when the '
other instance is just starting, succeeded to create the file, but has not
yet created the socket and written its port number into the file.
Repair action: Generate a random integer from 0-1000 and wait given ms time and try again to create/read the lock file again. Repeat this at most five times.
- File created, but cannot be written. Can happen on Windows when
The lock file has successfully been created, but before writing to it
another instance of NetBeans is trying to read it.
Repair action: Release your socket, delete the file and wait random amount of ms as in previous case.
- Port read from file, but cannot connect to it. Can happen
when the NetBeans crashes and the file is not deleted.
Repair action: If the host IP written in the file is the same as the one of the computer the second instance runs on, then just delete the file and try to create it your self. Otherwise ask user whether he wants to continue.
- Connected to the port, but secret key not recognized. Probably
because the lock file was out of date and we accidentally connected to
port of another application or user.
Repair action: Delete the file and try to create it your self.
Command Line Communication
The mechanism used for locking the user directory can be easily extended to handle command line interaction with already running NetBeans instance. That way we will be able to remove the hardcoded launcher options and allow modules to provide own extensions.Passing the Extended Command
When the launcher starts and finds out that there is an instance of NetBeans already running, it uses the established socket connection to send all its extended commands to the running system. The system consults all command handlers registered by the installed modules and gives them a chance to interpret the commands. Any generated output is sent back to the lancher that prints it to stdout. This way any application in the system can communicate with the already running instance of NetBeans over the same user directory.
If the launcher finds out that there is no running instance of NetBeans it
obviously starts its own. When the startup is finished, it locates all the
registered command handlers and passes all its extended commands to them. The
output of such processing is send to stdout
of the NetBeans.
Command vs. Extended Command
Some CLI parameters need to be handled before the system is initialized, some of them need to wait until all modules are ready. There needs to be clear distinction between these types of arguments. Because the launcher script cannot know the exact extended commands neither their arity, it is better to separate them completely.
It is suggested to pass all launcher commands first, then include a special
marker --
and after that the set of extended commands for the
modules.
nbexec --help
prints all the regular launcher commandsnbexec --open X.java
is an example of extended command used to open a file in a running NetBeans instancenbexec --print-scripting-server-port
is extended command provided by the scripting module that would print the port number on which the scripting module is listening, so it is possible to query it outside of the running NetBeans
Comments to nbdev@netbeans.org please.