JR
Ronald Olsson and Aaron Keen's extension of Java at UC Davis that grafts the SR language's concurrency model onto Java: dynamically created virtual machines, remote objects, asynchronous send, synchronous call, rendezvous and semaphores, all translated into standard Java
Created by Ronald A. Olsson and Aaron W. Keen (University of California, Davis)
JR is a concurrent programming language that extends Java with the concurrency model of SR (Synchronizing Resources), the language Gregory Andrews and Ronald Olsson built at the University of Arizona. It was designed at the University of California, Davis, by Ronald A. Olsson and his doctoral student Aaron W. Keen, with early contributions from Tingjian Ge and Justin Maris. A JR program is ordinary Java plus a handful of new constructs: dynamically created virtual machines, remote objects, processes and, at the center of it all, operations. An operation can be invoked synchronously (call) or asynchronously (send), and it can be serviced either by a method or by a multi-way inni input statement. The JR translator turns this into standard Java, which runs on a standard JVM against a runtime library also written in Java.
JR never left the university. It is still a tidy answer to a question every Java programmer runs into eventually: what if threads, synchronized and RMI were not the whole story?
History and Origins
The SR inheritance
SR first appeared in Andrews’s 1981 TOPLAS paper “Synchronizing Resources”, and a substantially revised SR (version 2) was described in 1988. Olsson was a co-author of the 1988 TOPLAS paper describing SR and its implementation, and co-wrote the 1993 book The SR Programming Language with Andrews. SR’s distinguishing trait was expressive power. It offered remote procedure call, rendezvous, asynchronous message passing, dynamic process creation, semaphores and shared variables, all built from a few underlying ideas. But SR was not object-oriented, and by the late 1990s Java had become the language students and researchers actually used.
The JR papers lay out the motivation plainly. Java gave you “threads, a primitive monitor-like mechanism, and remote method invocation (RMI)”, which the authors judged useful but inflexible for designing concurrent programs. Their approach was “to extend Java with the concurrency model provided by the SR concurrent programming language”, producing “a new language, a superset of Java, which we call JR.” The early work was funded in part by National Science Foundation grant CCR-9527295.
From prototype to public release
An early JR prototype was in use by spring 2000. The project’s own credits thank undergraduates who “bravely used an early JR prototype” in independent study in Winter and Spring 2000, and the Fall 2000 ECS 140B (Programming Languages) class, which used it “(successfully!) as part of an assignment.”
The first paper appeared at ICDCS 2001 in April 2001. According to Internet Archive snapshots, the project page through October 2001 still read “PAGE UNDER CONSTRUCTION” and hoped for a public prototype release in January 2001. By late December 2001 the archived page reportedly carried download and installation instructions for a UNIX-only jr.tar, with a Windows port promised “soon”. The encyclopedia’s date of 1987 cannot be right for a Java extension. It may be a confusion with JR’s parent language SR.
Keen finished his Ph.D. in May 2002 with a dissertation titled Integrating Concurrency Constructs with Object-Oriented Programming Languages: A Case Study, and later joined the faculty of California Polytechnic State University (his affiliation in the 2004 book). Olsson kept the project going at Davis with a long series of undergraduate and master’s students. Their names fill the project page’s personnel list.
Design Philosophy
The stated design goal was “to retain the ‘feel’ of Java while providing a richer concurrency model.” In practice that meant three rules:
- A superset, not a replacement. Every Java class is a JR class. JR adds declarations and statements but leaves sequential Java alone.
- Few concepts, many mechanisms. As in SR, most of JR’s concurrency comes from one idea, the operation, combined with two ways to invoke it and two ways to service it.
- Object-oriented synchronization. SR’s mechanisms were adapted to classes and inheritance. The TOPLAS paper names “how JR resolves the tension between inheritance and concurrency” as a core contribution, and describes JR’s object-oriented approach to synchronization as novel.
Key Features
Operations: one abstraction, four combinations
An operation generalizes a method. It has a name, parameters and possibly a return value, but how it is invoked and how it is serviced are independent choices:
| Serviced by a method | Serviced by an input statement (inni / receive) | |
|---|---|---|
Invoked by call (synchronous) | procedure call / RPC | rendezvous |
Invoked by send (asynchronous) | dynamic process creation | asynchronous message passing |
The same declaration can therefore act as a procedure, a message channel or a rendezvous entry. The program text says which.
Processes and the inni statement
The project’s sample readers/writers program shows most of the core syntax. op declares operations, process declares threads of control (here with a quantifier that creates several at once), and inni services whichever pending invocation is acceptable, guarded by st (“such that”) clauses:
| |
inni combines and generalizes aspects of Ada’s accept and select (the TOPLAS paper says this of SR’s in statement, on which inni is based). Like SR’s in, it can also take a scheduling expression, a by clause that orders pending invocations, for example servicing the lowest-numbered caller first with something like inni void CSenter(int id) by id { ... }.
Abbreviations
JR provides shorthand for common uses of operations: process declarations, op-methods, receive statements, and semaphores with P and V:
| |
The language also includes reply and forward statements, operation capabilities (first-class references to operations), and a quiescence mechanism. When every process has terminated or deadlocked, the runtime can invoke a registered operation instead of simply ending the program.
Virtual machines and remote objects
A JR virtual machine is an address space located on a single physical machine. VMs are created at run time much as objects are, and objects can be created remotely on them:
| |
In the original implementation, VM creation went through a central manager called JRX, modeled on SR’s SRX. JRX started each remote JR virtual machine (jrvm) over rsh. Later instructions describe swapping in ssh through a JRRSH property.
Later additions
Many of the later features were built as student projects at Davis: parameterized virtual machines (2003-04), quantifiers and a timeout arm on inni, a concurrent invocation statement for issuing groups of invocations together, with its own exception handling (Euro-Par 2005), and support for Java 5 generics in operations and capabilities.
Implementation
The JR translator (jrc) originally extended the Java compiler from Sun’s JDK 1.2.1. It converts .jr files into standard .java files in a jrGen directory, which javac then compiles against the JR runtime jars. A jr driver script automates translate-compile-run, and a verification suite (jrv) checks an installation. The 2004 book states that the implementation ran on UNIX-based systems (Linux, Mac OS X and Solaris) and on Windows.
The JR 2.x line rebuilt the translator on the Java 1.5 implementation. That choice limited its future: the final release’s notes say JR does not support Java 6, 7 or 8 language features. For example, a switch on a String is rejected at translation time. JR also stopped working with Java 9 and later, because jrc depends on rt.jar, which the modular JDK removed.
Performance, with its context
The authors were candid that “performance has not been a primary concern,” and their measurements are narrow:
- Remote invocation vs. RMI. In the ICDCS 2001 paper, the authors timed repeated invocations of an empty remote operation that took an array argument. The test ran on a cluster of 350 MHz Pentium II workstations on 10 Mbps Ethernet, using Sun’s JDK 1.2.2 for Linux. For a 1-integer argument, JR took 3.03 ms against 2.72 ms for plain RMI, about 11% slower. At 10,000 and 100,000 integers the two were essentially equal. JR was built on RMI, so the difference is the extra layer of operation dispatch.
- Local invocation vs. a Java method. In the draft TOPLAS paper on the project site (same cluster, JDK 1.3.1, Linux 2.4.2), an empty local JR operation took about 0.37 µs against about 0.074 µs for an empty Java method. That is roughly five times longer, attributed to four extra method calls for dynamic dispatch and causal message ordering.
- Readers/writers. In the same draft, a readers/writers server built on
innitook 1.31 to 1.40 times as long as an equivalent RMI solution (run as a persistent server), across three reader/writer/iteration mixes. A JR version using semaphore abbreviations came within 1.01 to 1.09 times. The authors traced theinnioverhead to the code that preserves its fair invocation selection, and noted that the JR semaphore version beat RMI when the RMI server was restarted between runs, which reduced the benefit of Java’s JIT.
Evolution
| Period | Milestone |
|---|---|
| 2000 | Prototype used by UC Davis students |
| 2001 | ICDCS paper; first UNIX download |
| 2003 | Windows and Mac OS X support |
| 2004 | JR 1.00041, TOPLAS paper, Kluwer book |
| 2005 | JR 1.00061: concurrent invocation statement, inni timeout (last 1.x line, Java 1.4) |
| 2006 | JR 2.00001: Java 1.5 base, generics |
| 2006 to 2014 | Maintenance releases tracking Java 6, 7 and 8 (2.00002 to 2.00607) |
| 2017 | JR 2.00608, the final release, requires Java 1.8 |
Community tooling stayed small but real. A vim syntax file by Francois Kilchoer appeared in 2006 and an Emacs mode by Bryan W. Bell in 2007. In 2012 the project page began pointing to PySy, which it describes as “a Python package for JR-like concurrent programming.”
Current Relevance
JR is historical. The project page’s last news item (September 2019) says 2.00608 “remains” the latest version. It still works with Java 1.8 if you install that JDK yourself, but not with newer Java. The distribution, the book’s complete code extract and the papers are all still downloadable from the UC Davis project page. That makes JR unusually easy to study for a research language of its era. No Docker image or package-manager build exists.
Why It Matters
JR is a clear record of a recurring idea: the concurrency primitives a mainstream language ships with are not the only reasonable ones. Within a single language, JR showed that RPC, rendezvous, asynchronous message passing, semaphores and dynamic process creation could all be built from one abstraction (the operation) and fitted into Java’s object model without breaking its syntax. Its examples, such as guarded multi-way receives, ordering of pending invocations and quiescence handlers, address problems that later actor libraries, CSP-style channel languages and Java’s own java.util.concurrent attack in other ways. For students at UC Davis and readers of the 2004 book, it was also a working, portable way to write SR-style concurrent programs in a language they already knew.
Timeline
Notable Uses & Legacy
UC Davis concurrent programming courses
JR was used in ECS 140B (Programming Languages) from Fall 2000 and afterwards in ECS 244 (Concurrent Programming), giving students rendezvous, asynchronous message passing and distributed virtual machines without leaving Java syntax
The JR Programming Language (Kluwer, 2004)
Olsson and Keen's textbook (ISBN 1-4020-8085-9) teaches concurrent programming through JR, with Part II developing complete applications: matrix multiplication, partial differential equations, the traveling salesman problem, a distributed file system and discrete event simulation
Concurrency-language research at UC Davis
JR was the vehicle for a run of papers on language design, including fairness in shared invocation servicing (2002), exception handling for asynchronous invocation (Euro-Par 2002), inter-entry invocation selection (Euro-Par 2003), partial quiescence (Euro-Par 2006, CCPE 2008) and generic operations (2009)
Teaching other concurrency notations
The JR distribution ships preprocessors that translate conditional critical regions, monitors and CSP into JR, plus an SR-to-JR translator written by Justin Maris, so one runtime can host several classic notations