edu.rice.cs.drjava.model.repl.newjvm
Class MainJVM

java.lang.Object
  extended by edu.rice.cs.util.newjvm.AbstractMasterJVM
      extended by edu.rice.cs.drjava.model.repl.newjvm.MainJVM
All Implemented Interfaces:
MainJVMRemoteI, MasterRemote, Remote

public class MainJVM
extends AbstractMasterJVM
implements MainJVMRemoteI

Manages a remote JVM.

Version:
$Id: MainJVM.java 4694 2008-12-08 20:47:26Z dlsmith $

Nested Class Summary
static class MainJVM.DummyDebugModel
          DebugModelCallback which does not react to events.
static class MainJVM.DummyInteractionsModel
          InteractionsModel which does not react to events.
static class MainJVM.DummyJUnitModel
          JUnitModel which does not react to events.
 
Field Summary
static String DEFAULT_INTERPRETER_NAME
           
 
Fields inherited from class edu.rice.cs.util.newjvm.AbstractMasterJVM
_log, _masterJVMLock, _slave, _waitForQuitThreadName
 
Constructor Summary
MainJVM(File wd)
          Creates a new MainJVM to interface to another JVM; the MainJVM has a link to the partially initialized global model.
 
Method Summary
 void addBuildDirectoryClassPath(File f)
          Blocks until the interpreter is connected.
 void addExternalFilesClassPath(File f)
          Blocks until the interpreter is connected.
 void addExtraClassPath(File f)
          Blocks until the interpreter is connected.
 void addInterpreter(String name)
          Adds a named interpreter to the list.
 void addProjectClassPath(File f)
          Blocks until the interpreter is connected.
 void addProjectFilesClassPath(File f)
          Blocks until the interpreter is connected.
protected  boolean allowAssertions()
          Return whether to allow assertions in the InterpreterJVM.
 void classFileError(ClassFileError e)
          Called if the slave JVM encounters an illegal class file in testing.
 void enableRestart()
          ReEnables restarting the slave if it has been turned off by repeated startup failures.
 InterpreterJVMRemoteI ensureInterpreterConnected()
          If an interpreter has not registered itself, this method will block until one does.
 void errorStartingSlave(Throwable cause)
          Called if the slave JVM dies before it is able to register.
 List<String> findTestClasses(List<String> classNames, List<File> files)
          Sets up a JUnit test suite in the Interpreter JVM and finds which classes are really TestCases classes (by loading them).
 Iterable<File> getClassPath()
          Returns the current classpath of the interpreter as a list of unique entries.
 String getConsoleInput()
          Asks the main jvm for input from the console.
 String getCurrentInterpreterName()
          Accesses the cached current interpreter name.
protected  int getDebugPort()
          Returns the debug port to use, as specified by the model.
 File getFileForClassName(String className)
          Called when the JUnitTestManager wants to open a file that is not currently open.
protected  InterpretResult.Visitor<Void> getResultHandler()
          Returns the visitor to handle an InterpretResult.
 String getVariableToString(String var)
          Gets the string representation of the value of a variable in the current interpreter.
 String getVariableType(String var)
          Gets the class name of a variable in the current interpreter.
protected  void handleSlaveConnected()
          Called when Interpreter JVM connects to us after being started.
protected  void handleSlaveQuit(int status)
          React if the slave JVM quits.
 void interpret(String s)
          Interprets string s in slave JVM.
 boolean isInterpreterRunning()
           
 boolean isStartupInProgress()
          Returns whether a JVM is currently starting.
 void killInterpreter(File wd)
          Kills the running interpreter JVM, and restarts with working directory wd if wd != null.
 void nonTestCase(boolean isTestAll)
          Called if JUnit is invoked on a non TestCase class.
 void quitFailed(Throwable th)
          This method is called by the interpreter JVM if it cannot be exited.
 void removeInterpreter(String name)
          Removes the interpreter with the given name, if it exists.
 boolean runTestSuite()
          Runs the JUnit test suite already cached in the Interpreter JVM.
 boolean setActiveInterpreter(String name)
          Sets the current interpreter to the one specified by name.
 void setAllowAssertions(boolean allow)
          Sets whether the remote JVM will run "assert" statements after the next restart.
 void setDebugModel(DebugModelCallback model)
          Provides an object to listen to debug-related events.
 void setInteractionsModel(InteractionsModelCallback model)
          Provides an object to listen to interactions-related events.
 void setJUnitModel(JUnitModelCallback model)
          Provides an object to listen to test-related events.
 void setOptionArgs(String argString)
          Sets the extra (optional) arguments to be passed to the interpreter.
 void setPackageScope(String packageName)
          Sets the Interpreter to be in the given package.
 void setPrivateAccessible(boolean allow)
          Sets the interpreter to allow access to private members.
 void setShowMessageOnResetFailure(boolean show)
          Blocks until the interpreter is connected.
 void setStartupClassPath(String classPath)
          Sets the classpath to use for starting the interpreter JVM.
 boolean setToDefaultInterpreter()
          Sets the default interpreter to be the current one.
 boolean slaveJVMUsed()
           
protected  void slaveQuitDuringStartup(int status)
          Action to take if the slave JVM quits before registering.
 void startInterpreterJVM()
          Starts the interpreter if it's not running already.
 void systemErrPrint(String s)
          Forwards a call to System.err from InterpreterJVM to the local InteractionsModel.
 void systemOutPrint(String s)
          Forwards a call to System.out from InterpreterJVM to the local InteractionsModel.
 void testEnded(String testName, boolean wasSuccessful, boolean causedError)
          Called when a particular test has ended.
 void testStarted(String testName)
          Called when a particular test is started.
 void testSuiteEnded(JUnitError[] errors)
          Called when a full suite of tests has finished running.
 void testSuiteStarted(int numTests)
          Called to indicate that a suite of tests has started running.
 
Methods inherited from class edu.rice.cs.util.newjvm.AbstractMasterJVM
checkStillAlive, dispose, getSlave, invokeSlave, invokeSlave, invokeSlave, quitSlave, registerSlave, waitSlaveDone
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface edu.rice.cs.util.newjvm.MasterRemote
checkStillAlive, registerSlave
 

Field Detail

DEFAULT_INTERPRETER_NAME

public static final String DEFAULT_INTERPRETER_NAME
See Also:
Constant Field Values
Constructor Detail

MainJVM

public MainJVM(File wd)
        throws RemoteException
Creates a new MainJVM to interface to another JVM; the MainJVM has a link to the partially initialized global model. The MainJVM but does not automatically start the Interpreter JVM. Callers must set the InteractionsModel and JUnitModel and then call startInterpreterJVM().

Throws:
RemoteException
Method Detail

isInterpreterRunning

public boolean isInterpreterRunning()

slaveJVMUsed

public boolean slaveJVMUsed()

setInteractionsModel

public void setInteractionsModel(InteractionsModelCallback model)
Provides an object to listen to interactions-related events.


setJUnitModel

public void setJUnitModel(JUnitModelCallback model)
Provides an object to listen to test-related events.


setDebugModel

public void setDebugModel(DebugModelCallback model)
Provides an object to listen to debug-related events.

Parameters:
model - the debug model

setAllowAssertions

public void setAllowAssertions(boolean allow)
Sets whether the remote JVM will run "assert" statements after the next restart.


setOptionArgs

public void setOptionArgs(String argString)
Sets the extra (optional) arguments to be passed to the interpreter.

Parameters:
argString - the arguments as they would be typed at the command-line

interpret

public void interpret(String s)
Interprets string s in slave JVM. Blocks until the interpreter is connected and evaluation completes. No masterJVMLock synchronization because reading _restart is the only access.to master JVM state.


getVariableToString

public String getVariableToString(String var)
Gets the string representation of the value of a variable in the current interpreter. Blocks until the interpreter is connected.

Parameters:
var - the name of the variable

getVariableType

public String getVariableType(String var)
Gets the class name of a variable in the current interpreter. Blocks until the interpreter is connected.

Parameters:
var - the name of the variable

addProjectClassPath

public void addProjectClassPath(File f)
Blocks until the interpreter is connected.


addBuildDirectoryClassPath

public void addBuildDirectoryClassPath(File f)
Blocks until the interpreter is connected.


addProjectFilesClassPath

public void addProjectFilesClassPath(File f)
Blocks until the interpreter is connected.


addExternalFilesClassPath

public void addExternalFilesClassPath(File f)
Blocks until the interpreter is connected.


addExtraClassPath

public void addExtraClassPath(File f)
Blocks until the interpreter is connected.


getClassPath

public Iterable<File> getClassPath()
Returns the current classpath of the interpreter as a list of unique entries. The list is empty if a remote exception occurs. Blocks until the interpreter is connected.


setPackageScope

public void setPackageScope(String packageName)
Sets the Interpreter to be in the given package. Blocks until the interpreter is connected.

Parameters:
packageName - Name of the package to enter.

setShowMessageOnResetFailure

public void setShowMessageOnResetFailure(boolean show)
Blocks until the interpreter is connected.

Parameters:
show - Whether to show a message if a reset operation fails.

systemErrPrint

public void systemErrPrint(String s)
                    throws RemoteException
Forwards a call to System.err from InterpreterJVM to the local InteractionsModel.

Specified by:
systemErrPrint in interface MainJVMRemoteI
Parameters:
s - String that was printed in the other JVM
Throws:
RemoteException

systemOutPrint

public void systemOutPrint(String s)
                    throws RemoteException
Forwards a call to System.out from InterpreterJVM to the local InteractionsModel.

Specified by:
systemOutPrint in interface MainJVMRemoteI
Parameters:
s - String that was printed in the other JVM
Throws:
RemoteException

findTestClasses

public List<String> findTestClasses(List<String> classNames,
                                    List<File> files)
                             throws RemoteException
Sets up a JUnit test suite in the Interpreter JVM and finds which classes are really TestCases classes (by loading them). Blocks until the interpreter is connected and the operation completes.

Parameters:
classNames - the class names to run in a test
files - the associated file
Returns:
the class names that are actually test cases
Throws:
RemoteException

runTestSuite

public boolean runTestSuite()
                     throws RemoteException
Runs the JUnit test suite already cached in the Interpreter JVM.

Returns:
false if no test suite is cached; true otherwise
Throws:
RemoteException

nonTestCase

public void nonTestCase(boolean isTestAll)
                 throws RemoteException
Called if JUnit is invoked on a non TestCase class. Forwards from the other JVM to the local JUnit model.

Specified by:
nonTestCase in interface MainJVMRemoteI
Parameters:
isTestAll - whether or not it was a use of the test all button
Throws:
RemoteException

classFileError

public void classFileError(ClassFileError e)
                    throws RemoteException
Called if the slave JVM encounters an illegal class file in testing. Forwards from the other JVM to the local JUnit model.

Specified by:
classFileError in interface MainJVMRemoteI
Parameters:
e - the ClassFileError describing the error when loading the class file
Throws:
RemoteException

testSuiteStarted

public void testSuiteStarted(int numTests)
                      throws RemoteException
Called to indicate that a suite of tests has started running. Forwards from the other JVM to the local JUnit model.

Specified by:
testSuiteStarted in interface MainJVMRemoteI
Parameters:
numTests - The number of tests in the suite to be run.
Throws:
RemoteException

testStarted

public void testStarted(String testName)
                 throws RemoteException
Called when a particular test is started. Forwards from the slave JVM to the local JUnit model.

Specified by:
testStarted in interface MainJVMRemoteI
Parameters:
testName - The name of the test being started.
Throws:
RemoteException

testEnded

public void testEnded(String testName,
                      boolean wasSuccessful,
                      boolean causedError)
               throws RemoteException
Called when a particular test has ended. Forwards from the other JVM to the local JUnit model.

Specified by:
testEnded in interface MainJVMRemoteI
Parameters:
testName - The name of the test that has ended.
wasSuccessful - Whether the test passed or not.
causedError - If not successful, whether the test caused an error or simply failed.
Throws:
RemoteException

testSuiteEnded

public void testSuiteEnded(JUnitError[] errors)
                    throws RemoteException
Called when a full suite of tests has finished running. Forwards from the other JVM to the local JUnit model.

Specified by:
testSuiteEnded in interface MainJVMRemoteI
Parameters:
errors - The array of errors from all failed tests in the suite.
Throws:
RemoteException

getFileForClassName

public File getFileForClassName(String className)
                         throws RemoteException
Called when the JUnitTestManager wants to open a file that is not currently open.

Specified by:
getFileForClassName in interface MainJVMRemoteI
Parameters:
className - the name of the class for which we want to find the file
Returns:
the file associated with the given class
Throws:
RemoteException

addInterpreter

public void addInterpreter(String name)
Adds a named interpreter to the list. Blocks until the interpreter is connected.

Parameters:
name - the unique name for the interpreter
Throws:
IllegalArgumentException - if the name is not unique

removeInterpreter

public void removeInterpreter(String name)
Removes the interpreter with the given name, if it exists. Blocks until the interpreter is connected.

Parameters:
name - Name of the interpreter to remove

setActiveInterpreter

public boolean setActiveInterpreter(String name)
Sets the current interpreter to the one specified by name. Blocks until the interpreter is connected.

Parameters:
name - the unique name of the interpreter to set active
Returns:
Whether the new interpreter is currently processing an interaction

setToDefaultInterpreter

public boolean setToDefaultInterpreter()
Sets the default interpreter to be the current one. Blocks until the interpreter is connected.

Returns:
Whether the new interpreter is currently in progress with an interaction

getCurrentInterpreterName

public String getCurrentInterpreterName()
Accesses the cached current interpreter name.


killInterpreter

public void killInterpreter(File wd)
Kills the running interpreter JVM, and restarts with working directory wd if wd != null. If wd == null, the interpreter is not restarted. Note: If the interpreter is not restarted, all of the methods that delegate to the interpreter will silently fail! Therefore, killing without restarting should be used with extreme care and only in carefully controlled test cases or when DrJava is quitting anyway.


setStartupClassPath

public void setStartupClassPath(String classPath)
Sets the classpath to use for starting the interpreter JVM. Must include the classes for the interpreter.

Parameters:
classPath - Classpath for the interpreter JVM

startInterpreterJVM

public void startInterpreterJVM()
Starts the interpreter if it's not running already.


handleSlaveQuit

protected void handleSlaveQuit(int status)
React if the slave JVM quits. Restarts the JVM unless _restart is false, and notifies the InteractionsModel if the quit was unexpected. Called from a thread within AbstractMasterJVM waiting for the death of the process that starts and runs the slave JVM.

Specified by:
handleSlaveQuit in class AbstractMasterJVM
Parameters:
status - Status returned by the dead process.

slaveQuitDuringStartup

protected void slaveQuitDuringStartup(int status)
Action to take if the slave JVM quits before registering. Assumes _masterJVMLock is held.

Overrides:
slaveQuitDuringStartup in class AbstractMasterJVM
Parameters:
status - Status code of the JVM TODO: revise the unit tests that kill the slave prematurely (by making them wait until the slave registers) and remove the TEST_MODE escape.

errorStartingSlave

public void errorStartingSlave(Throwable cause)
                        throws RemoteException
Called if the slave JVM dies before it is able to register.

Specified by:
errorStartingSlave in interface MasterRemote
Specified by:
errorStartingSlave in class AbstractMasterJVM
Parameters:
cause - The Throwable which caused the slave to die.
Throws:
RemoteException

quitFailed

public void quitFailed(Throwable th)
                throws RemoteException
This method is called by the interpreter JVM if it cannot be exited.

Specified by:
quitFailed in interface MainJVMRemoteI
Parameters:
th - The Throwable thrown by System.exit
Throws:
RemoteException

isStartupInProgress

public boolean isStartupInProgress()
Returns whether a JVM is currently starting. This override widens the visibility of the method.

Overrides:
isStartupInProgress in class AbstractMasterJVM

handleSlaveConnected

protected void handleSlaveConnected()
Called when Interpreter JVM connects to us after being started. Assumes that _masterJVMLock is already held.

Specified by:
handleSlaveConnected in class AbstractMasterJVM

enableRestart

public void enableRestart()
ReEnables restarting the slave if it has been turned off by repeated startup failures.


getResultHandler

protected InterpretResult.Visitor<Void> getResultHandler()
Returns the visitor to handle an InterpretResult.


getDebugPort

protected int getDebugPort()
Returns the debug port to use, as specified by the model. Returns -1 if no usable port could be found.


allowAssertions

protected boolean allowAssertions()
Return whether to allow assertions in the InterpreterJVM.


setPrivateAccessible

public void setPrivateAccessible(boolean allow)
Sets the interpreter to allow access to private members. Blocks until an interpreter is connected.


ensureInterpreterConnected

public InterpreterJVMRemoteI ensureInterpreterConnected()
If an interpreter has not registered itself, this method will block until one does.


getConsoleInput

public String getConsoleInput()
Asks the main jvm for input from the console.

Specified by:
getConsoleInput in interface MainJVMRemoteI
Returns:
the console input