{"id":25472944,"url":"https://github.com/atgreen/openldk","last_synced_at":"2026-02-01T22:33:31.766Z","repository":{"id":270515487,"uuid":"910583288","full_name":"atgreen/openldk","owner":"atgreen","description":"A JIT Compiler and Runtime for Java in Common Lisp","archived":false,"fork":false,"pushed_at":"2025-12-07T14:06:00.000Z","size":6476,"stargazers_count":231,"open_issues_count":1,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-12-10T01:50:37.631Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atgreen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2024-12-31T17:55:50.000Z","updated_at":"2025-12-07T14:06:04.000Z","dependencies_parsed_at":"2024-12-31T21:21:14.108Z","dependency_job_id":"25e51ccd-595b-4d96-9fbf-d5db3d528f81","html_url":"https://github.com/atgreen/openldk","commit_stats":null,"previous_names":["atgreen/openldk"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/atgreen/openldk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atgreen%2Fopenldk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atgreen%2Fopenldk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atgreen%2Fopenldk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atgreen%2Fopenldk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atgreen","download_url":"https://codeload.github.com/atgreen/openldk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atgreen%2Fopenldk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28993253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T22:01:47.507Z","status":"ssl_error","status_checked_at":"2026-02-01T21:58:37.335Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-02-18T10:02:05.346Z","updated_at":"2026-02-01T22:33:31.761Z","avatar_url":"https://github.com/atgreen.png","language":"Java","readme":"# OpenLDK\n## A JIT Compiler and Runtime for Java in Common Lisp\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003cimg width=\"33%\" src=\"https://github.com/user-attachments/assets/eb723bd3-f676-44d0-97ce-9bbfb11f2cd0\"\u003e\n\u003c/p\u003e\n\nOpenLDK is a Just-In-Time (JIT) compiler and runtime environment for\nJava, implemented entirely in Common Lisp. It bridges the gap between\nJava and Common Lisp by incrementally translating Java bytecode into\nLisp, which is then compiled into native machine code for\nexecution. This unique approach allows Java classes to be seamlessly\nmapped to Common Lisp Object System (CLOS) classes, enabling\neffortless integration between Java and Common Lisp codebases.\n\n## Key Features\n\n- **Java Bytecode to Lisp Translation**: OpenLDK translates Java bytecode into Common Lisp, making it possible to execute Java code within a Lisp environment.\n- **Native Machine Code Compilation**: The translated Lisp code is compiled into native machine code, ensuring efficient execution.\n- **CLOS Integration**: Java classes are mapped to CLOS classes, allowing for smooth interoperability between Java and Common Lisp.\n- **OpenJDK Runtime Libraries**: OpenLDK leverages OpenJDK's core runtime libraries, made possible by the GNU Classpath Exception to the GPL.\n\n## Use Cases\n\nOpenLDK is not designed to be a high-performance Java\nruntime. Instead, it's for when you want to use SBCL, but need that\none Java library. It provides a practical solution for integrating\nJava libraries into a Lisp-based workflow without the need for an\nout-of-process Java runtime environment.\n\n## Requirements\n\n`openldk` has only been tested with sbcl.  It's possible that other\nCommon Lisp implementations could be made to work with it, but I am\nonly developing with sbcl for now.\n\n`openldk` has only been tested in Linux.\n\n`openldk` uses the `JAVA_HOME` environment variable to find the boot classpath.\nBe sure to point it at your Java 8 directory.  On\nmy Fedora Linux system that looks like:\n```\n$ export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.432.b06-3.fc40.x86_64/jre\n```\n\nYou can provide additional classpath elements through the\n`LDK_CLASSPATH` environment variable.\n\nThe OpenLDK project uses [`ocicl`](https://github.com/ocicl/ocicl) for\npackage management.  Be sure to run `ocicl install` before building\n`openldk`.\n\n## Building\n\nRunning `make` produces two executables:\n- `openldk` - the JIT compiler and runtime for Java\n- `javacl` - Java's `javac` compiler transpiled to Lisp and dumped as an executable\n\n## How it Works\n\n`openldk` reads class and jar files, and translates them into lisp\ncode, which sbcl's compiler then turns into machine code for\nexecution.\n\nJava classes and objects are mapped to CLOS classes.  The exception\nhierarchy is mirrored by a Common Lisp condition hierarchy.  CLOS\nprovides everything we need to support reflection, and SBCL's\nbacktrace capabilities allow us check calling classes to support\nJava's security model.\n\nThe first time we read a class definition, we generate a CLOS\ndefinition, with stubs for methods.\n\nFor example...\n\n```\npublic class demo\n{\n    public static int add (int x, int y)\n    {\n        return x + y;\n    }\n\n    public static int x;\n    public static int y;\n\n    public static void main (String[] args)\n    {\n        System.out.println (\"Hello, World\");\n        System.out.println (add (x, y));\n    }\n}\n```\n\n...becomes...\n\n```\n(progn\n (defclass openldk::|demo| (openldk::|java/lang/Object|)\n    ((openldk::|x| :initform 0 :allocation :class)\n     (openldk::|y| :initform 0 :allocation :class)))\n (defparameter openldk::|+static-demo+| (make-instance 'openldk::|demo|))\n (defmethod openldk::|\u003cinit\u003e()| ((openldk::|this| openldk::|demo|))\n   (openldk::%compile-method \"demo\" 1)\n   (openldk::|\u003cinit\u003e()| openldk::|this|))\n (defun openldk::|demo.add(ii)| (openldk::|arg1| openldk::|arg2|)\n   (openldk::%compile-method \"demo\" 2)\n   (openldk::|demo.add(ii)| openldk::|arg1| openldk::|arg2|))\n (defun openldk::|demo.main([ljava/lang/String;)| (openldk::|arg1|)\n   (openldk::%compile-method \"demo\" 3)\n   (openldk::|demo.main([ljava/lang/string;)| openldk::|arg1|)))))\n```\n\nNote that the methods are all stubs that invoke the compiler and then\nthemselves.  This is how we support incremental JIT compilation.\n\nWhen the `add` method is called, the compiler will read `add`'s\nbytecode and generates something like the following:\n\n```\n(defun openldk::|demo.add(ii)| (openldk::|arg0| openldk::|arg1|)\n  (let ((openldk::|s{3}|)\n        (openldk::|s{2}|)\n        (openldk::|s{1}|)\n        (openldk::|local-0| openldk::|arg0|)\n        (openldk::|local-1| openldk::|arg1|))\n    (block nil\n      (tagbody\n       |branch-target-0|\n        (setf openldk::|s{1}| openldk::|local-0|)\n        (setf openldk::|s{2}| openldk::|local-1|)\n        (setf openldk::|s{3}|\n          (let* ((openldk::value2 openldk::|s{2}|)\n                 (openldk::value1 openldk::|s{1}|)\n                 (openldk::result\n                   (logand (+ openldk::value1 openldk::value2)\n                           4294967295)))\n            (if (\u003e openldk::result 2147483647)\n                (- openldk::result 4294967296)\n                openldk::result)))\n        (return-from openldk::|demo.add(ii)| openldk::|s{3}|)))))\n```\n\n## Hacking\n\n### Testing\n\nAs of Nov 23, 2025, OpenLDK can successful compile and run `javac`,\nwhich in turn is capable of building class files from java source\ncode.\n\nAs of Mar 30, 2025, log4j is starting to function correctly.  See\n[cl-log4j](https://github.com/atgreen/cl-log4j) for an example of how\nto wrap a Java library for Common Lisp usage.\n\nRun `make check` to run through the\n[dejagnu](https://www.gnu.org/software/dejagnu/dejagnu)-based testsuite.\nAs of Mar 6 2025, the results look like this\n```\n\t\t=== openldk Summary ===\n\n# of expected passes\t\t8839\n# of unexpected failures\t11\n# of expected failures\t\t1712\n# of unresolved testcases\t11\n```\n\n### Debugging\n\nThe `openldk` runtime will generate useful debug info if you set your\n`LDK_DEBUG` environment variable.  `LDK_DEBUG` should be set to a\nstring of characters that are interpreted as below:\n\n- `b` - trace bytecode compilation\n- `c` - dump all Lisp code prior to evaluation\n- `l` - show class loading (prints \"; LOADING classname\" for each class)\n- `L` - show class loading and method compilation with timing\n- `p` - debug propagation\n- `s` - start a slynk server at startup (port 2025)\n- `t` - trace method entry/exit at runtime\n- `T` - trace method entry/exit with arguments and return values\n- `u` - unmuffle the Lisp compiler\n- `x` - trace opcode execution (use with `t`)\n\nMore specifically, running `LDK_DEBUG=bcltux openldk Hello` will enable\nmost debug output while running `Hello`.\n\n## Status\n\nVery basic programs work.  This includes the whole runtime startup\nprocess, covering class loading, reflection, exceptions, file IO, and\nmore.\n\nNot much more than that works yet.  You are looking at a work in\nprogress that may never be completed.\n\nThe code is not optimized.  Even with heavy optimization, OpenLDK's\nperformance will not be competitive to modern Java implementations.\nIt is not meant to be competitive.  OpenLDK is meant to fill the gap\nfor when you want to code in Common Lisp, but you need that one Java\nlibrary.\n\nHere's an incomplete list of what's not implemented:\n- support for class files beyond Java 8\n- dynamic method invocation\n- bytecode verification\n\nAuthor and License\n-------------------\n\nOpenLDK was written by [Anthony\nGreen](https://github.com/atgreen), and is distributed under the terms\nof the GNU General Public License, Version 2, modified by the\n\"CLASSPATH\" exception to the GPL.  See\n[LICENSE](https://github.com/atgreen/OpenLDK/blob/main/LICENSE)\nfor details.\n","funding_links":[],"categories":["Recently Updated","Java ##","Java"],"sub_categories":["[Feb 16, 2025](/content/2025/02/16/README.md)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatgreen%2Fopenldk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatgreen%2Fopenldk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatgreen%2Fopenldk/lists"}