GitHub - apposed/jgo: Launcher and dependency manager for Java programs ☕
jgo: painless Java environments and execution
Summary
jgo launches Java applications directly from Maven coordinates—no installation required. Specify a Maven artifact identifier and an optional main class, and jgo resolves dependencies, materializes the environment including the version of Java needed, and runs your program.
# Run Jython REPL (latest version) jgo org.python:jython-standalone # Run with specific version jgo org.python:jython-standalone:2.7.3
Features
- Zero-configuration execution: Automatic Java download and version management thanks to
cjdkintegration - Pure Python dependency resolver: No Maven installation required to resolve dependency graphs
- Reproducible environments:
jgo.tomlproject files with lock files (likepackage.json+package-lock.json) - Three-layer architecture: Independently useful layers for Maven resolution, environment building, and execution
- Powerful Python API: Fine-grained control over dependency resolution and execution
- Intelligent module handling: Full support of the Java module system (JPMS), including intelligent classification of dependencies on module-path or class-path as appropriate
Quick Start
CLI Usage
# Run Jython REPL jgo org.python:jython-standalone # Run with arguments jgo org.python:jython-standalone -- -- script.py --verbose # Multiple artifacts with main class (use @ separator) jgo org.scijava:scijava-common+org.scijava:scripting-jython@ScriptREPL # Force update from remote repos jgo -u org.python:jython-standalone # Use specific Java version jgo --java-version 17 net.imagej:imagej # Print classpath without running jgo info classpath org.python:jython-standalone # Preview commands without executing (--dry-run) jgo --dry-run run org.scijava:parsington # See java command jgo --dry-run init org.python:jython-standalone # Preview jgo.toml
Python API
import jgo # Simple one-liner jgo.run("org.python:jython-standalone:2.7.3", app_args=["script.py"]) # Build environment without running env = jgo.build("org.python:jython-standalone") print(env.classpath) # List of JAR paths # Resolve dependencies components = jgo.resolve("org.python:jython-standalone") for comp in components: print(f"{comp.groupId}:{comp.artifactId}:{comp.version}")
Project Mode with jgo.toml
Create reproducible environments:
# jgo.toml [environment] name = "my-java-app" [repositories] scijava.public = "https://maven.scijava.org/content/groups/public" [dependencies] coordinates = ["net.imagej:imagej:2.15.0"] [entrypoints] default = "main" main = "net.imagej.Main" [settings] cache_dir = ".jgo" # Local environment like .venv
# Run from current directory jgo sync # Creates .jgo/ with jars/ and jgo.lock.toml
Installation
Installing jgo with uv
uv tool install "jgo[cli]"Installing jgo with pip
Installing jgo with conda
conda install -c conda-forge jgo
Installing jgo from source
git clone https://github.com/apposed/jgo
uv tool install --with-editable "jgo[cli]" jgoWhen installed in this fashion, changes to the jgo source code will be immediately reflected when running jgo from the command line.
Using jgo as a library dependency
or
Not sure which to use? Read this.
The cli extra (jgo[cli]) is only needed when using the jgo command-line tool, not when using jgo as a Python library.
Examples
| Program | Command |
|---|---|
| Jython REPL | jgo org.python:jython-standalone |
| JRuby eval | echo "puts 'Hello Ruby'" | jgo org.jruby:jruby-complete@jruby.Main |
| Groovy REPL | jgo org.codehaus.groovy:groovy-groovysh+commons-cli:commons-cli:1.3.1@shell.Main |
Note the usage of the + syntax as needed to append elements to the classpath.
If you add
scijava.public = https://maven.scijava.org/content/groups/public
to the
[repositories] section of your settings file
(see the configuration docs),
you can also try:
| Program | Command |
|---|---|
| SciJava REPL with JRuby | jgo org.scijava:scijava-common+org.scijava:scripting-jruby@ScriptREPL |
| SciJava REPL with Jython | jgo org.scijava:scijava-common+org.scijava:scripting-jython@ScriptREPL |
| SciJava REPL with Groovy | jgo org.scijava:scijava-common+org.scijava:scripting-groovy@ScriptREPL |
| SciJava REPL with Clojure | jgo org.scijava:scijava-common+org.scijava:scripting-clojure@ScriptREPL |
| SciJava REPL with JavaScript | jgo org.scijava:scijava-common+org.scijava:scripting-javascript@ScriptREPL |
FAQ
- Is it fast?
Endpoints are synthesized in a local cache under
~/.cache/jgo. So invoking the same endpoint a second time is really quick. - What does "no installation" mean?
Classpath elements are hard-linked
into
~/.cache/jgofrom~/.m2/repositoryrather than copied, so the cache folder has a tiny footprint even if you execute lots of different endpoints. - What if an endpoint has a new version?
Pass the
-uflag tojgoto rebuild the endpoint. Note that unlikemvn,jgodoes not check for updates otherwise.
Documentation
Full documentation is available at jgo.apposed.org:
- Getting Started — Installation and quick start
- CLI Reference — All commands and options
- Project Mode — Working with
jgo.toml - Python API — Using jgo from Python code
- Configuration — Repositories, shortcuts, and settings
- Migration Guide — Upgrading from jgo 1.x
- Architecture — The three-layer design
Use help(jgo) in Python for detailed API documentation.
Development
Code style
jgo uses ruff for linting and formatting:
Testing
# Run all tests make test # Run specific test file bin/test.sh tests/test_maven_basic.py # Run with coverage uv run pytest --cov=src/jgo tests/