FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Adding JVM + JShell documentation · DrJavaAtRice/drjava@7b11da3 · GitHub

Repository navigation

Commit 7b11da3

Browse files
Adding JVM + JShell documentation
Use this to get a better picture of communication b/w the 2 JVMs, JShell in InterpreterJVM, and next steps for JShell
1 parent e4a85d6 commit 7b11da3

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# InterpreterJVM Documentation
2+
3+
## Primary commands
4+
To build drjava (2 ways):
5+
1. **`ant build`** (oftentimes doesn’t work)
6+
2. **`ant compile`, `ant jar`, `java -jar drjava.jar`**
7+
8+
## Current State of jshell-min-set
9+
10+
### Builds
11+
The current version of the jshell-min-set branch of DrJava as of November 2024 (commit e4a85d6) compiles and builds with Java 9+ with JShell support. For Java 8 and older versions, this branch will not compile because when the JShell is not found, jshell-min-set is not currently set up to default to a DynamicJava interpreter. If you try to compile with Java 9+ using the --release option to specify Java 8 (i.e., **`ant compile -Djavac.release=8`** then **`ant jar`**), it will compile and jar. However, the jar file output from running these commands seems to only build with Java 9+ running. Attempting to build this jar file with Java 8 and older versions results in an error.
12+
13+
### Structure
14+
Currently, Dr. Java runs on two JVMs: the Main JVM which runs the **`drjava/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/MainJVM.java`** class and the Interpreter JVM which runs the **`drjava/drjava/src/edu/rice/cs/drjava/model/repl/newjvm/InterpreterJVM.java`** class. Note that in the codebase, the Main JVM and its class may be referred to as the Master JVM and the Interpreter JVM and its class is often referred to as the Slave JVM. The Main JVM runs Dr. Java’s GUI, mainframe, and compilation which is, in essence, the primary functions of the application. The Interpreter / Slave JVM runs JUnit and the Interpreter window which are the secondary portions of the application.
15+
16+
These JVMs communicate via Remote Method Invocation (RMI). The Interpreter / Slave JVM also runs a “demon thread” that checks if the Main JVM still acknowledges its existence. If the Main JVM responds in the affirmative, then the Interpreter / Slave JVM stays alive. If the Main JVM responds in the negative, the Interpreter / Slave JVM shuts down. This is done with the `removeInterpreter` method in **`MainJVM.java`**.
17+
18+
In DrJava, from the user’s perspective when we have a hung computation, the current way to handle this issue in the **`jshell-min-set`** branch is to go to **`Tools -> Reset Interactions and Clear Console`**. Doing this results in the message **`”Resetting Interactions and Clearing Console”`** appearing in the console before the console is cleared.
19+
20+
**Behind the scenes, this is what we know**
21+
22+
From our current working understanding of DrJava we believe the current safe way to kill a JVM in DrJava is by use of `quitSlave()`. Currently `quitSlave()` is called in `MainJVM.java` for `stop()` and `restart(boolean force)`. `quitSlave()` transitions state from RUNNING to STOPPING, calls `attemptQuit(_slave)`, sets `_slave` to null, and then sets `_monitor` to FRESH. `dispose()` is called to clean up external resources and release RMI hooks.
23+
24+
**MainFrame.java**: In MainFrame.java, when resetting the interactions pane and clearing the console, a new AbstractActions is created: `_resetInteractionsAction`. Within this new action, `_doResetInteractions()` is called. Within the `_doResetInteractions()` function, a call to `_interactionsPane.discardUndoEdits()` is made, which discards any edits and resets undoManager, and then a new Thread is started. Now, before `.start()` is called on this new thread, three things of note happen. First,` _model.resetConsole()` is called. This resets the console and fires `consoleReset()` event. Second, `_model.resetInteractions(_model.getWorkingDirectory(), true)` is called. This returns the working directory for the slave (interactions pane) JVM. Third, `_closeSystemInAction.setEnabled(true)` is called. This calls `_interactionsController.setEndOfStream(true)` and `_interactionsController.interruptConsoleInput()`, which sets the end of the stream flag and forces console input to complete without the user hitting `Enter` (called by MainFrame when reset is called so that this lock is released; this method is thread safe) respectively.
25+
26+
**Functions of Note and the Files that Define Them**
27+
* **GlobalModel.java**: `quit()`: exits the program (only quits if all documents are successfully closed). `forcequit()`: halts the program immediately.
28+
* **DefaultGlobalModel.java**: `dispose()`: prepares the model to be thrown away.
29+
* **AbstractMasterJVM.java**: `quitSlave()`: Quits Slave JVM. If a slave is not currently started and running, blocks until that state is reached. `attemptQuit()`: Makes an attempt to invoke slave.quit(), logs an error if it fails. `dispose()`: Frees the resources required for this object to respond to RMI invocations and requires the slave to have quit; blocks until that occurs. An object is no longer useful once it has been disposed of.
30+
* **InteractionsPane.java**: `discardUndoEdits()`: discards edits and resets undoManager.
31+
* **InteractionsController.java**: `setEndOfStream()`: sets the end of the stream flag. `interruptConsoleInput():` forces console input to complete without the user hitting `Enter` (called by MainFrame when reset is called so that this lock is released; this method is thread safe) respectively.
32+
* **FileGroupingState.java**: `getWorkingDirectory()`: returns the working directory for the Slave JVM
33+
* **InteractionsModel.java**: `resetInterpreter()`: Resets the Java interpreter with working directory wd. `_interactionIsOver()`: Performs the common behavior when an interaction ends (adds completed interaction to history, changes progress of document to false, inserts prompt, and notifies that interaction has ended)
34+
* **ConsoleDocument.java**: `reset(String banner)`: Resets the document to a clean state and only runs in the event thread; the parameter banner is the value to which to set the banner
35+
* **InteractionsController.java**: `disableInputs()`: Disables all input to the text box, does not change the appearance of the text
36+
* **MainFrame.java**: . `_enableInteractionsPane()`: Makes Interactions Pane editable, sets cursor to text cursor, and enables navigation actions within the Interactions Pane. `_disableInteractionsPane()`: Makes Interactions Pane uneditable, sets cursor to waiting cursor, and disables navigation actions within the Interactions Pane.
37+
**Relationships between files**
38+
* MainFrame.java invokes `discardUndoEdits()` from InteractionsPane.java, `getWorkingDirectory()`, `resetConsole()`, and `resetInteractions()` from AbstractGlobalModel.java, `setEndOfStream()` and `interruptConsoleInput()` from InteractionsController.java, and `getWorkingWorkingDirectory()` from FileGroupingState.java
39+
* AbstractGlobalModel.java: invokes `quit()` and `forceQuit()`from GlobalModel.java, and `dispose()` from DefaultGlobalModel.java
40+
* MainJVM.java invokes `quitSlave()`, `attemptQuit()`, and `dispose()` from AbstractMasterJVM.java
41+
* InteractionsModel.java invokes `reset(String banner)` from ConsoleDocument.java
42+
* AbstractGlobalModel.java invokes `consoleReset()` from GlobalEventNotifier.java
43+
44+
### Current Challenges
45+
Our main challenge is stopping the Interactions Pane when an operation is hanging. This idea of killing the interactions pane becomes more complex when the idea of merging the Main and Secondary JVMs is introduced, a concept we will elaborate on in the Future Work section below. Currently, the only way to stop the interpreter is to reset the interactions page (Tools -> Reset Interactions and Clear Console). If this action is taken, the interactions pane is cleared and all operations and outputs are no longer visible. Note that while the pane is visibly cleared, the history is still intact and you can retrieve singular previous operations by pressing the up key in the interactions pane. Currently, the best way to recover the entirety of the cleared information after resetting the pane is to save your interactions pane history through Tools -> History -> Save Interactions History…. This will save the full history (operations but not their outputs pre and post reset) in a text file located in **`drjava/drjava/src/edu/rice/cs/drjava/model/compiler`**. The best way to save a holistic copy of the interactions pane (operations and their outputs) is to save the interactions pane before resetting it. This can be done by choosing Tools -> Interactions and Console -> Save Copy of Interactions in the top task/tool bar. This option will save a complete record of the interactions pane (operations and outputs) as a .txt file in **`drjava/drjava/src/edu/rice/cs/drjava/model/compiler`**.
46+
47+
## Future Work on jshell-min-set
48+
Long term, the goal is to integrate the two JVMs into a singular JVM. Currently, the JShell Interpreter is spun up in its own JVM. When the “demon” thread that reaches out to the MainJVM indicates that the MainJVM is no longer acknowledging the Interpreter JVM (sometimes triggered by resetting the interactions pane) the entire JShell Interpreter JVM is killed, and a new one is started. Eventually, with a singular JVM, instead of killing the JVM, there should be the ability to kill the thread. Right now, the prevailing way to potentially implement this functionality is to call `thread.stop()`. However, `thread.stop()` presents many safety issues as the objects it may have interacted with could be left damaged with no warning to the rest of the program.
49+
50+
Additionally, we’d like to be able to stop a hanging operation in the Interactions Pane. Traditionally, the user presses Ctrl+C to terminate a hanging operation and return to a ready prompt in JShell and most other CLI applications. As of right now, the Interactions Pane is not set up to receive multi-key keypress actions nor does it allow any keyboard inputs whenever an operation is running. To rectify this, we would need to change what happens when `_disableInteractionsPane` is called such that the pane is still editable, can receive keyboard input, and can call either `interactionEnded` or `interactionErrorOccurred` in order to terminate the operation. The decision to choose one of the two will come down to whether we want to interpret a hanging operation as an error or simply a characteristic of the operation that was interpreted.
51+
52+
Alternatively, given the limited functionality of JShell in the Interactions Pane (/help doesn’t work, CLI is susceptible to human error in bloated Dr. Java codebase, etc.), one could solve this issue by swapping the JShell specific Interactions Pane with a Terminal / PowerShell pane. With a Terminal / Powershell pane all input, error handling, keyboard interrupts, etc. can be handled by applications native to the user’s device. These panes can even be started with JShell running by programmatically running the `jshell` command and erasing all command history from view before that call. This also allows for users to explore their project’s directories, practice various Linux commands (adding more opportunities for students to learn basic programming practices), and run CLI applications similar to JShell for other languages if they’re working on a Java application that runs programs in other languages.

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL