jacobin - A more than minimal JVM written in Go and capable of running Java 11 bytecode.

Overview

Go version Workflow GitHub

jacobin

A more-than-minimal JVM written in Go.

This overview gives the background on this project, including its aspirations and the features that it supports. The remaining pages discuss the basics of JVM operation and, where applicable, how Jacobin implements the various steps, noting any items that would be of particular interest to JVM cognoscenti. I've included references to the official JVM docs, where I can both as a reference for you, the reader, and for the Jacobin team's easy reference.

Status

Intended feature set:

  • Java 11 functionality, but...
  • No JNI (Oracle intends to replace it; see JEP 389)
  • No security manager (Oracle intends to remove it; see JEP 411)
  • No JIT
  • Somewhat less stringent bytecode verification

What we've done so far and what we need to do:

Command-line parsing

  • Gets options from the three environment variables. Details here
  • Parses the command line; identify JVM options and application options
  • Responds to most options listed in the java -help output

To do:

  • Handling JAR files
  • Handling @files (which contain command-line options)
  • Parsing the classpath

Class loading

  • Correctly reads and parses basic classes
  • Extracts bytecode and params needed for execution

To do:

  • Handle more-complex classes
  • Handle interfaces
  • Handle arrays
  • Handle inner classes
  • Automate loading of core Java classes (Object, etc.)

Verification, Linking, Preparation, Initialization

  • Performs integrity check bytecode is correct. ✏️ This is the focus of current coding work

To do:

  • Linking and verification
  • Preparation
  • Initialization

Execution

Not started yet

Garbage Collection

GC is handled by the golang runtime, which has its own GC

Thanks

The overview page carries a right-side panel that expresses our thanks to vendors and programmers who have made the Jacobin project possible. They are many and we are deeply grateful to them.

Issues
  • jacobin failed to recognise class file specified by a.b.c

    jacobin failed to recognise class file specified by a.b.c

    Maybe this report is about a feature that is on the jacobin TO-DO list? If so, pardon my jumping the gun.

    Tree-top: scimark2_java, cloned from https://github.com/texadactyl/scimark2_java. ls -R

    .:
    jnt  LICENSE  original_README.txt  README.md
    
    ./jnt:
    Bench  scimark2
    
    ./jnt/Bench:
    Applet.java  Bench.java  Formatter.java  HTTPPost.java  Plotter.java  SendMail.java  Stopwatch.java  SubmitDialog.java  Target.java
    
    ./jnt/scimark2:
    applet.java        commandline.java  Constants.java  FFT.java     kernel.class  LU.class  MonteCarlo.class  Random.class  SOR.class  SparseCompRow.class  Stopwatch.class
    commandline.class  Constants.class   FFT.class       Jacobi.java  kernel.java   LU.java   MonteCarlo.java   Random.java   SOR.java   SparseCompRow.java   Stopwatch.java
    

    Compile: javac -O jnt/scimark2/commandline.java

    Run the original jvm: java jnt.scimark2.commandline

    SciMark 2.0a, elasped time = 27.23s
    URL: https://math.nist.gov/scimark2/index.html
    
    Composite Score: 2901.249182054803
    FFT (1024): 2033.507015924168
    SOR (100x100):   1887.3214307438175
    Monte Carlo : 1655.731504772598
    Sparse matmult (N=1000, nz=5000): 2590.355516411772
    LU (100x100): 6339.33044242166
    
    java.vendor: Private Build
    java.version: 11.0.15
    java..vm.vendor: Private Build
    java.vm.version: 11.0.15+10-Ubuntu-0ubuntu0.22.04.1
    os.arch: amd64
    os.name: Linux
    os.version: 5.15.0-41-generic
    

    Run jacobin (compiled with go 1.8): jacobin jnt.scimark2.commandline

    Jacobin VM v. 0.1.0, © 2021-2 by Andrew Binstock. All rights reserved. MPL 2.0 License.
    jnt.scimark2.commandline is not a recognized option. Ignored.
    

    Version information: openjdk version "11.0.15" 2022-04-19 x64 Xubuntu 22.04 LTS

    opened by texadactyl 14
  • Figure out why Github is failing a test that passes on the dev system and should pass on Github

    Figure out why Github is failing a test that passes on the dev system and should pass on Github

    The test is TestPrintOfCPpart2() in cpParser_test.go, which simply dumps the previously parsed constant pool (CP) entries to stderr.

    After adding some diagnostic info, got this, which is incorrect b/c it does not show the final two CP entries correctly, which are a dynamic and at UTF8 entry (from Github build and test #221)

        cpParser_test.go:867: dynamic CP entry did not appear in logging of CP contents:
            Number of CP entries parsed: 08
            CP entry: 00, type 00 (dummy entry)
            CP entry: 01, type 16 (method type)      description index: 4370
            CP entry: 02, type 18 (invokedynamic)    boostrap index: 4616, name and type: 4609
            CP entry: 03, type 01 (UTF-8 string)     Module
            CP entry: 04, type 19 (module name)      Module
            CP entry: 05, type 20 (package name)     Module
            CP entry: 06, type 00 (dummy entry)
            CP entry: 07, type 00 (dummy entry)
    

    The correct output should be:

    Number of CP entries parsed: 08
    CP entry: 00, type 00 (dummy entry)
    CP entry: 01, type 16 (method type)      description index: 4370
    CP entry: 02, type 18 (invokedynamic)    boostrap index: 4616, name and type: 4609
    CP entry: 03, type 01 (UTF-8 string)     Module
    CP entry: 04, type 19 (module name)      Module
    CP entry: 05, type 20 (package name)     Module
    CP entry: 06, type 17 (dynamic)          boostrap index: 4616, name and type: 4609
    CP entry: 07, type 01 (UTF-8 string)     Hello
    

    (Notice the difference in the last two entries.)

    After removing the Module and Package entries to see whether they were causing the problem, got the following output (from build and test #222):

            cpParser_test.go:867: dynamic CP entry did not appear in logging of CP contents:
            Number of CP entries parsed: 06
            CP entry: 00, type 00 (dummy entry)
            CP entry: 01, type 16 (method type)      description index: 4370
            CP entry: 02, type 18 (invokedynamic)    boostrap index: 4616, name and type: 4609
            CP entry: 03, type 01 (UTF-8 string)     Module
            CP entry: 04, type 00 (dummy entry)
            CP entry: 05, type 00 (dummy entry) 
    

    So, it's not the previous entries or their position that are causing the problem. Rather, it's the entries of themselves.

    Note: This issue is logged as JACOBIN-86 on the internal Jacobin task list (kept on YouTrack)

    opened by platypusguy 6
  • Local mutex makes no sense

    Local mutex makes no sense

    Local mutex does not make sense

    https://github.com/platypusguy/jacobin/blob/8818d325dae39b9a8a427359bd36ef330067e179/src/thread/jvmThread.go#L36

    shouldn't it be

    var addThreadToTableMutex = sync.Mutex{}
    func AddThreadToTable(t *ExecThread, tbl *list.List) int {
    	addThreadToTableMutex .Lock()
    
    	tbl.PushBack(t)
    	t.ID = tbl.Len() - 1
    	addThreadToTableMutex .Unlock()
    
    	return t.ID
    }
    
    opened by avpavlov 3
  • Is the plan to create a new JCL?

    Is the plan to create a new JCL?

    One of the key components of a Java SE implementation is the Class Library. Currently, I only know that OpenJDK has a complete implementation of the Class Library. It is a little coupled to the Hotspot VM, however, other JVMs, like OpenJ9 can use it.

    So my question is: Is one of the goals of this project reimplement the whole Java Class Library (like the java.lang.Object/java.util.HashMap, ...) or use the same as OpenJDK?

    There are some other implementations of some components that wouldn't be required to be implemented, like using the ECJ for the compiler and Kodda for a replacement of Javadoc.

    (The license of the JCL is GPL2, so it may play some role in the decision)

    opened by Thihup 3
  • JACOBIN-166 - JMOD Support

    JACOBIN-166 - JMOD Support

    Adds support for JMOD files. Attempts to load java.base.jmod on startup, in order to replace the need for the JACOBIN_HOME setup. Test files are in testdata/jmod.

    One note: I didn't end up looking for the classlist in $JAVA_HOME/lib, because this made it less applicable to other modules in the future and also complicated testing a bit. I don't think it is necessary, as the classlist file should be in the module at all times anyway, but I can add that functionality in if you think it is necessary?

    opened by suresk 2
  • func Log and func shutdown contain a local mutex

    func Log and func shutdown contain a local mutex

    As written, I believe that simultaneous threads will never wait because the mutex variable is local to functions being called.

    Guessing from a Go newbie but I believe that you wanted to do something like this: https://notes.shichao.io/gopl/ch9/#mutual-exclusion-syncmutex and move the mutex definition to be global to the log package?

    Those are the only 2 cases (logger.go:Log & main.go:shutdown) that I saw where there are mutexes being used.

    opened by texadactyl 2
  • Uncomment lines from issue #1

    Uncomment lines from issue #1

    This PR is based on my creating a temporary repo and testing uncommenting out the lines referenced in issue #1. Either I have the magic touch [(-;] or Unka Andoo's activity last night somehow cleansed something (?).

    opened by texadactyl 0
Releases(0.2.0)
  • 0.2.0(Aug 8, 2022)

    This is a pre-alpha release: a simple proof of concept. This release includes executables for Windows (jacobin.exe) and Mac (jacobin). If you're on other platforms, here's how you build Jacobin: install go (1.18+), download the src directory from this project, run go build and voilà an executable. Jacobin has no other dependencies.

    To run Jacobin:

    Jacobin expects to find a JDK installation at the location pointed to by the JACOBIN_HOME environment variable. It supports any version of the JDK up through Java 17.

    To run a class: jacobin nameOfClass.class (Note that, unlike the JVM, you need to use the .class extension of the file)

    At present, Jacobin runs only a few simple classes. Some of them can be downloaded from the testdata folder. They do simple things: print a string 10 times (Hello.class), perform simple computations and print the result (Hello2.class, Hello3.class). If you want to see the Java source code, it's in the comments for each class in the wholeClassTests directory. For example, the Java source code to Hello3.class is in the comments in Hello3_test.go

    Jacobin can be run with many command-line options that provide a lot of information about the classes being loaded (there are almost 1500 classes loaded for any given run) and you can even do instruction tracing. Some of those command-line options are explained in this post.

    Source code(tar.gz)
    Source code(zip)
    jacobin(2.74 MB)
    jacobin.exe(2.91 MB)
  • v.0.1.0-proofOfConcept(Feb 4, 2022)

    This is a pre-pre-alpha release: a simple proof of concept. This release includes an executable (for Windows) and a core subset of Java classes (from the standard Java distribution). To run Jacobin:

    • [ ] Extract the .zip file of classes into a directory
    • [ ] Create an environmental variable, `JACOBIN_HOME', and point it to the directory
    • [ ] Run the enclosed executable. If you're not on Windows, here's how you build Jacobin: install go (1.16+), download the src directory from this project, run go build and voila an executable. Jacobin, at present, has no other dependencies.

    To run a class: jacobin nameOfClass.class (Note that unlike the JVM, you need to use the .class extension of the file)

    At present, Jacobin runs only a few simple classes. Four of them can be downloaded from the testdata folder. They do simple things: print a string 10 times (Hello.class), perform simple computations and print the result (Hello2.class, Hello3.class). If you want to see the Java source code, it's in the comments for each class in the wholeClassTests directory. For example, the Java source code to Hello3.class is in the comments in Hello3_test.go

    Jacobin can be run with many command-line options that provide a lot of information about the classes being loaded (there are almost 1500 classes loaded for any given run) and you can even do instruction tracing. Those command-line options are explained in this post.

    Source code(tar.gz)
    Source code(zip)
    classes.zip(2.15 MB)
    jacobin.exe(2.83 MB)
Owner
Andrew Binstock
Former editor of Oracle's Java Magazine and, earlier, of Dr. Dobb's Journal. Java hacker at heart.
Andrew Binstock
Highly extensible, customizable application launcher and window switcher written in less than 300 lines of Golang and fyne

golauncher A go application launcher A simple, highly extensible, customizable application launcher and window switcher written in less than 300 lines

Ettore Di Giacinto 43 Jun 30, 2022
XSD (XML Schema Definition) parser and Go/C/Java/Rust/TypeScript code generator

xgen Introduction xgen is a library written in pure Go providing a set of functions that allow you to parse XSD (XML schema definition) files. This li

null 173 Jul 22, 2022
Build reply markup keyboards easier than ever.

gotgbot keyboard Build reply markup keyboards easier than ever.

null 4 Feb 24, 2022
My Go solution that's faster than 95%

Palindrome-Partitioning My Go solution that's faster than 95% "Given a string s, partition s such that every substring of the partition is a palindrom

Daniel Pickens 0 Nov 15, 2021
Chaosblade executor for chaos experiments on Java applications

Chaosblade-exec-jvm: Chaosblade executor for chaos experiments on Java applications Introduction The project is a chaosblade executor based on jvm-san

null 334 Aug 3, 2022
Zinc Search engine. A lightweight alternative to elasticsearch that requires minimal resources, written in Go.

Zinc Search Engine Zinc is a search engine that does full text indexing. It is a lightweight alternative to Elasticsearch and runs using a fraction of

null 9.9k Aug 7, 2022
Optimistic rollup tech, minimal and generic.

Opti Optimistic rollup tech, minimal and generic. VERY experimental, just exploratory code, question is: 1:1 EVM rollup with interactive fraud proof p

Diederik Loerakker 13 Oct 29, 2021
Minimal example app of hexagonal architecture in go

Hexagonal Architecture Minimal example of hexagonal architecture (ports & adapters) in go. Resources T

Rodrigo Gamba 0 Nov 5, 2021
gosignal is expected to be used in minimal window manager configurations

gosignal is expected to be used in minimal window manager configurations. It provides a simple battery monitor , which notifies of battery events. It has a config file where you can configure the notification messages given

pspiagicw 0 Mar 21, 2022
Gec is a minimal stack-based programming language

Gec is a minimal stack-based programming language

aiocat 1 May 22, 2022
A simple Cron library for go that can execute closures or functions at varying intervals, from once a second to once a year on a specific date and time. Primarily for web applications and long running daemons.

Cron.go This is a simple library to handle scheduled tasks. Tasks can be run in a minimum delay of once a second--for which Cron isn't actually design

Robert K 210 Jul 27, 2022
Workaround for running ubuntu:21.10, fedora:35, and other glibc >= 2.34 distros on Docker <= 20.10.9

clone3-workaround: Workaround for running ubuntu:21.10, fedora:35, and other glibc >= 2.34 distros on Docker <= 20.10.9 Old container engines such as

Akihiro Suda 7 Jun 17, 2022
The VM for running Back

Backvm The VM for running Back Back is a Concurrent Forth implementation, have fun Building the only dependency for backvm is the Go compiler Backvm d

null 1 Dec 11, 2021
Search running process for a given dll/function. Exposes a bufio.Scanner-like interface for walking a process' PEB

Search running process for a given dll/function. Exposes a bufio.Scanner-like interface for walking a process' PEB

Alex Flores 2 Apr 21, 2022
Unik is a Go module for running Go programs as unikernels, without an underlying operating system

Unik is a Go module for running Go programs as unikernels, without an underlying operating system. The included demo is a functional Gio GUI prog

null 0 Feb 9, 2022
Start of a project that would let people stay informed about safe running spaces in their area.

SafeRun Start of a project that would let people stay informed about safe running spaces in their area. Too many people I'm friends with feel unsafe w

Ryan Dunning 0 Feb 11, 2022
Quickly clone an entire org/users repositories into one directory - Supports GitHub, GitLab, Bitbucket, and more

ghorg ghorg allows you to quickly clone all of an orgs, or users repos into a single directory. This can be useful in many situations including Search

Jay Gabriels 990 Jul 31, 2022
Yet another Go REPL that works nicely. Featured with line editing, code completion, and more.

gore Yet another Go REPL that works nicely. Featured with line editing, code completion, and more. (Screencast taken with cho45/KeyCast) Usage gore Af

Hironao OTSUBO 4.6k Aug 8, 2022
Heat, heat and more heat!

Load Operator The intention of this project is to escape from the bad weather during the winter season. ;) Instead of getting wet and cold, it is used

Ben B. 3 Nov 15, 2021