{"id":50480385,"url":"https://github.com/orenskl/pico-jvm","last_synced_at":"2026-06-01T17:02:24.854Z","repository":{"id":215058768,"uuid":"718752810","full_name":"orenskl/pico-jvm","owner":"orenskl","description":"A small Java virtual machine for Raspberry Pi Pico. This is based on the CLDC Profile for embedded devices.","archived":false,"fork":false,"pushed_at":"2024-11-19T11:58:46.000Z","size":2008,"stargazers_count":20,"open_issues_count":5,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-19T12:53:42.885Z","etag":null,"topics":["arm","bare-metal","cldc","cortex-m","embedded","j2me","java","jvm","midp","phoneme","pico","raspberry","raspberry-pi","raspberry-pi-pico","real-time"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/orenskl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-14T18:20:55.000Z","updated_at":"2024-11-19T11:58:50.000Z","dependencies_parsed_at":"2024-11-19T12:36:04.738Z","dependency_job_id":"72bfd8db-c824-4488-94f1-9a272209f3fb","html_url":"https://github.com/orenskl/pico-jvm","commit_stats":{"total_commits":58,"total_committers":1,"mean_commits":58.0,"dds":0.0,"last_synced_commit":"8471f444db80842e6c6cb3540e617269bd765651"},"previous_names":["orenskl/pico-jvm"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/orenskl/pico-jvm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orenskl%2Fpico-jvm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orenskl%2Fpico-jvm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orenskl%2Fpico-jvm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orenskl%2Fpico-jvm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orenskl","download_url":"https://codeload.github.com/orenskl/pico-jvm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orenskl%2Fpico-jvm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33784631,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arm","bare-metal","cldc","cortex-m","embedded","j2me","java","jvm","midp","phoneme","pico","raspberry","raspberry-pi","raspberry-pi-pico","real-time"],"created_at":"2026-06-01T17:02:24.262Z","updated_at":"2026-06-01T17:02:24.849Z","avatar_url":"https://github.com/orenskl.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/orenskl/pico-jvm/main.yml?label=build)](https://github.com/orenskl/pico-jvm/actions/workflows/main.yml)\n[![GitHub Tag](https://img.shields.io/github/v/tag/orenskl/pico-jvm)](https://github.com/orenskl/pico-jvm/tags)\n\n# Pico JVM\n\nThis is a Java virtual machine for the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/), this project is based on the [CLDC](https://en.wikipedia.org/wiki/Connected_Limited_Device_Configuration) virtual machine and more specifically on the [phoneME](https://phonej2me.github.io) project from Sun/Oracle. The [phoneME](https://phonej2me.github.io) is a very old project that currently is not maintained anymore. However I was able to find a github [repo](https://github.com/magicus/phoneME) that I used as a reference. This JVM is targeted to small embedded devices with limited resources so don't expected a full blown Java experience on [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/).\n\nThe original [phoneME](https://phonej2me.github.io) project used a Makefile based build system, I converted the build system to CMake so I can use more modern tools and integration with modern CI/CD workflows. There are currently two main targets : Linux (used mainly for debugging) and Pico.\n\nCurrently the JVM support [CLDC 1.1](https://docs.oracle.com/javame/config/cldc/ref-impl/cldc1.1/jsr139/index.html) specification which is a limited subset of the Java  J2SE specification and language.\n\n## Features\n\n+ Small footprint - 270KB Flash, 18KB RAM (not including the Java heap)\n+ Java 1.4 and [CLDC 1.1](https://docs.oracle.com/javame/config/cldc/ref-impl/cldc1.1/jsr139/index.html) API\n+ [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) Low Level API (See [here](https://github.com/orenskl/pico-jvm/wiki/Examples))\n\n## Installation and setup\n\nDownload the release package from the [Releases](https://github.com/orenskl/pico-jvm/releases) page of this repository, extract the package. The package contains the following content :\n\n```\n├── bin\n├── doc\n├── lib\n└── pjvm-X.Y.Z.uf2\n```\n\nThe `bin` directory contains tools and scripts required to post process class and jar files to be able to run them on the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/). This directory also contains a Linux version of the virtual machine (`pjvm`) that may be used in development\nstage to test applications on your host machine.\n\nThe `doc` directory contains the javadoc for the device specific (e.g. GPIO) classes.\n\nThe `lib` directory contains the run-time class libraries (`classes.jar`)\n\nThe `pjvm-X.Y.Z.uf2` (where X.Y.Z is the version of the firmware) is the Java Virtual Machine UF2 file, this file needs to be flashed to the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) using [picotool](https://github.com/raspberrypi/picotool). The virtual machine already contains the run time classes so these are not required to be flashed separately.\n\nThe `examples` directory in this repository contains some examples you can run with an [Ant](https://ant.apache.org) `build.xml` file. To build the examples and the following Hello World application you will need to setup the environment variable `JAVA_PICO_HOME` to point to the extracted package location.\n\nFor example if you extracted the package to `/opt/pjvm-X.Y.Z` you will need to setup the variable with the following command :\n\n```\nexport JAVA_PICO_HOME=/opt/pjvm-X.Y.Z\n```\n\nYou will also need [JDK 8](https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html) to build application, currently the latest versions of Java are not supported.\n\n## Building and running a Java application\n\nTo run a Java application on the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) you will need to flash the Java virtual machine itself and than flash the Java application at the address `0x10100000`.\n\nLets say we have a simple hello world application :\n\n```java\nclass Main {\n    public static void main(String[] args) {\n        System.out.println(\"Hello, World!\"); \n    }\n}\n```\n\n**NOTE : The name of the class `Main` is currently fixed as the first class that is loaded by the VM.**\n\n1. Compile the class :\n\n    ```\n    javac -source 1.4 -target 1.4 -d main.dir -bootclasspath $JAVA_PICO_HOME/lib/classes.jar Main.java\n    ```\n\n    Make sure to setup you environment correctly so that `JAVA_PICO_HOME` points to the right place (see [here](#installation-and-setup))\n\n2. Preverify the classes\n\n    Before running the compiled classes on the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) we will need to Preverify them. Preverifying is the process of post processing the class files so they can be run more efficiently on the target system. Preverifying is done with the `preverify` tool in the `bin` directory of the package.\n\n    ```\n    $JAVA_PICO_HOME/bin/preverify -d main.preverify -classpath $JAVA_PICO_HOME/lib/classes.jar main.dir\n    ```\n\n3. Package the application as a JAR file :\n\n    ```\n    cd main.preverify\n    jar -cfM0 ../main.jar .\n    ```\n\n4. Wrap the JAR file \n\n    Now we need to wrap the JAR with a header so we can run it on the Pi Pico :\n\n    ```\n    $JAVA_PICO_HOME/bin/wrapjar.sh main.jar main.jar.bin\n    ```\n\n    The `wrapjar.sh` script is located in the `bin` directory of the package.\n\n5. Flash the binary file and reboot\n\n    Now we can flash the application to address `0x10100000` using `picotool` :\n\n    ```\n    picotool load build/main.jar.bin --offset 10100000\n    ```\n\n    Reboot your Pi Pico and you should see `Hello, World!` on your terminal\n\nThis repository includes an `example` directory with a complete [Ant](https://ant.apache.org) `build.xml` for each example that runs all the above steps in a single command.\n\n## Building\n\nThis project can be built on Ubuntu 22 as the build machine, please install the following packages :\n\n```\nsudo apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential gcc-multilib g++-multilib ninja-build\n```\n\n\nYou will also need JDK 8 (Yes 8) for this, please install it and make sure it is your default Java installation.\n\nAfter cloning the project cd into it and run the the usual CMake commands :\n\n```\nmkdir build\ncd build\ncmake -DTARGET=PICO -DPICO_SDK_PATH=/home/oren/projects/pico-sdk .. -G Ninja\ncmake --build .\n```\n\nMake sure you set `PICO_SDK_PATH` to point to your Pico SDK location.\n\nIf all goes well you should end up with a `pjvm.uf2` file in your `build` directory. This file can be flashed to the Pi Pico (helper scripts can be found in the `tools` directory). The `pjvm.uf2` file is the Java VM itself and includes the system classes already romized inside it. A Java application is loaded separately into the flash of the Pi Pico at a specific address.\n\nTo build the virtual machine for Linux use these commands :\n\n```\nmkdir build\ncd build\ncmake -DTARGET=LINUX .. -G Ninja\ncmake --build .\n```\n\nThe output of this build is a Linux executable named `pjvm`.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forenskl%2Fpico-jvm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forenskl%2Fpico-jvm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forenskl%2Fpico-jvm/lists"}