A Go rewrite of the previous TypeScript-based J2ME-For-Web project for running J2ME MIDlets on modern platforms.
J2ME-GO is a hobby J2ME virtual machine written in Go.
It is the Go successor to the earlier TypeScript implementation, with the same broad goal: boot real J2ME bytecode, bridge enough CLDC/MIDP APIs to run MIDlets, and make classic mobile games playable again in a modern browser.
Unlike the TypeScript version, this project pushes more of the VM and runtime into Go and uses Go WebAssembly as the browser-facing execution target.
| Component | Status | Details |
|---|---|---|
| Class-file loader | ✅ Working | Parses constant pool, fields, methods, and attributes |
| Interpreter core | ✅ Working | Executes a substantial subset of JVM bytecode needed by current tests and sample MIDlets |
| Runtime model | ✅ Working | Java classes, objects, arrays, shadow classes, exceptions, and method area |
| Native bridge | ✅ Working | Registry-based native dispatch for java.lang, java.io, LCDUI, RMS, game APIs, and Nokia APIs |
| MIDP / LCDUI | 🟡 In Progress | Display, Canvas, Graphics, Form, commands, and input are wired up, but game compatibility is still uneven |
| RMS / Resources | 🟡 In Progress | RecordStore and resource loading work for multiple sample games, with edge cases still being filled in |
| Browser / WASM runner | ✅ Working | Web loader, debug page, keyboard input, canvas flushing, and MIDlet boot pipeline are available |
| Game compatibility | 🟡 In Progress | Asteroids reaches visible, keyboard-driven 2D play; other MIDlets are used as compatibility samples |
| Automated tests | ✅ Passing | go test ./... is green |
-
2D MIDP compatibility is the active focus
- Added float/double JVM instructions, local variables, arrays, and conversions
- Added common floating-point
java/lang/MathAPIs - Added LCDUI
Listshadow inheritance fromDisplayable - Added a silent J2ME Media API compatibility backend, so optional audio no longer blocks 2D game startup
- M3G / JSR-184 3D is explicitly deferred rather than driving the core runtime roadmap
-
Asteroids is the current 2D reference sample
- It renders, advances frames, and accepts keyboard input in the browser
- High-volume runtime logs were removed from the browser DOM path to protect frame performance
-
智力方块 now reaches its visible LCDUI menu
- Its standard
Listis bridged to the Canvas renderer and produces non-black browser frames - Menu input and command activation remain the next compatibility step
- Its standard
-
The browser debugging loop is usable for real game bring-up
- MIDlet loading from the web page works
- 宠物王国4、宠物王国5与怪兽仙境3已加入选择器,作为 RPG 资源与运行时兼容样本
- 宠物王国5已补 Nokia
DirectUtils/DirectGraphics.setARGBColor/drawImage/fillPolygon的最小 2D 桥接;下一步是浏览器首帧回测,不涉及新的渲染后端 - 怪兽仙境3已到
startApp(),目前阻塞于其私有资源包格式;这不是 Go 或 2D 渲染性能问题 - Canvas flushing and non-black frame detection are in place
- Runtime logs make it practical to chase compatibility gaps one by one
- A recent Go toolchain with WebAssembly support
- Python 3
- A modern browser
git clone https://github.com/lingfeng11111/J2ME-GO.git
cd J2ME-GO
go test ./...
make build-wasm
make serve-webThen open http://localhost:8080.
- Build the WASM target with
make build-wasm - Start the local web server with
make serve-web - Place your own MIDlet JAR in
web/locally - Open the debug page and load the MIDlet in the browser
cmd/
├─ j2me-go/ # Desktop entry
└─ j2me-go-wasm/ # Browser / WASM entry
pkg/
├─ classfile/ # Java class-file parser
├─ interpreter/ # JVM bytecode interpreter
├─ runtime/ # Java classes, objects, arrays, exceptions, loaders
├─ native/ # Native method registry and platform bridges
└─ midp/ # MIDP graphics, display, canvas, RMS, resources
web/
├─ index.html # Browser debug loader
├─ wasm_exec.js # Go WASM runtime shim
├─ batch_test.js # Browser-side test helpers
└─ serve.sh # Local serving helper
tests/
├─ classfiles/ # Small Java test programs and compiled fixtures
└─ src/ # Test source files
- Go-first VM architecture: parser, interpreter, runtime, and native bridge are implemented in Go
- Browser target: runs through Go WebAssembly with a Canvas-based rendering path
- Shadow-class approach: missing Java ME platform classes can be modeled incrementally
- Compatibility-driven development: real MIDlets are used to expose missing runtime behavior
- Test-backed core: parser, interpreter, runtime, MIDP, and native layers all have Go tests
Because flip-phone Java games are too interesting to leave trapped in old hardware.
And because rewriting a VM twice, first in TypeScript and then in Go, is exactly the kind of unreasonable idea that occasionally turns into a good project.
The earlier TypeScript project, J2ME-For-Web, established the direction for this rewrite.
This repository also benefited from studying older J2ME browser efforts and existing reference implementations such as Mozilla's PluotSorbet, along with other open J2ME projects used for comparison and debugging.
Issues and pull requests are welcome.
If you want to work on compatibility, the most useful path is usually:
- Pick one failing MIDlet behavior
- Reproduce it in the browser runner
- Trace the missing bytecode, runtime class, or native method
- Add a focused test when possible