# jgo
**Repository Path**: mirrors_scijava/jgo
## Basic Information
- **Project Name**: jgo
- **Description**: Launch Java code from the CLI, installation-free. ☕
- **Primary Language**: Unknown
- **License**: Unlicense
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-09-25
- **Last Updated**: 2025-10-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
[](https://github.com/scijava/jgo/actions/workflows/build.yml)
[](https://github.com/psf/black)
# jgo: painless Java component execution

## Summary
[Maven](https://maven.apache.org/) is a great tool. It manages dependencies so
that Java projects become reusable "building blocks" in a robust way, like
`pip` for Python, `npm` for JavaScript, `gem` for Ruby, `cpan` for Perl, etc.
And the [Maven Central repository](https://search.maven.org/) contains a
tremendous wealth of code, ripe for reuse in your own projects.
Unfortunately, Maven provides no easy way to actually __launch code__ from the
beautifully managed dependencies stored so lovingly into `~/.m2/repository`.
This project fills that gap: `jgo` launches Java code. You do not need to
download or install any JARs; you just specify an "endpoint" consisting of a
[Maven artifact](https://stackoverflow.com/a/2487511/1207769) identifier, plus
a main class if needed/desired, and `jgo` uses Maven to obtain and run it.
To do this, `jgo` builds the local environment on demand, caching it into a
subfolder of `~/.jgo`, so that the endpoint's particular dependencies are
available in one place.
## Installation
The `jgo` project began life as a shell script, but was later translated into
Python, so that tools such as [scyjava](https://github.com/scijava/scyjava)
could leverage its environment-building capabilities.
As such, there are now two implementations from which to choose!
Each has pros and cons.
### Prerequisites
`jgo` uses `mvn` and `java` for the heavy lifting.
The shell script version needs some common utilities (e.g., `cat`).
If you are missing anything, the script will tell you.
### The shell script
The `jgo.sh` shell script requires a POSIX-friendly system. It is known to
work on Linux, macOS, [Cygwin](https://www.cygwin.com/), Microsoft's
[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install),
and Git BASH from the [Git for Windows](https://git-for-windows.github.io/) project.
Installing the shell script
Just clone this repo and symlink `jgo.sh` into your favorite `bin` directory.
For example, assuming `~/bin` is on your PATH:
```shell
cd
git clone https://github.com/scijava/jgo
cd bin
ln -s ../jgo/jgo.sh jgo
jgo --help
```
### The Python module
The Python version of `jgo` offers a `jgo` console script, as
well as a `jgo` module for programmatically creating endpoints.
Installing with pip
```shell
pip install jgo
```
Installing with conda
```shell
conda install -c conda-forge jgo
```
Installing from source
```shell
git clone https://github.com/scijava/jgo
cd jgo
# install globally (not recommended unless using a virtual environment)
pip install .
# install into ~/.local (see pip install --help for details)
pip install --user .
# install into $PREFIX
pip install --prefix=$PREFIX .
# install globally in developer mode (hot linked to working copy folder)
pip install -e .
```
## Usage
```
Usage: jgo [-v] [-u] [-U] [-m]
-v : verbose mode flag
-u : update/regenerate cached environment
-U : force update from remote Maven repositories (implies -u)
-m : use endpoints for dependency management (see "Pitfalls" below)
: any list of arguments to the JVM
: the artifact(s) + main class to execute
: any list of arguments to the main class
The endpoint should have one of the following formats:
- groupId:artifactId
- groupId:artifactId:version
- groupId:artifactId:mainClass
- groupId:artifactId:version:mainClass
- groupId:artifactId:version:classifier:mainClass
If version is omitted, then RELEASE is used.
If mainClass is omitted, it is auto-detected.
You can also write part of a class beginning with an @ sign,
and it will be auto-completed.
Multiple artifacts can be concatenated with pluses,
and all of them will be included on the classpath.
However, you should not specify multiple main classes.
```
### 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:@shell.Main+commons-cli:commons-cli:1.3.1` |
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 `.jgorc`
(see [Repositories](#repositories) below),
you can also try:
| Program | Command |
|-----------------------------:|:------------------------------------------------------------------------------------|
| SciJava REPL with JRuby | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-jruby` |
| SciJava REPL with Jython | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-jython` |
| SciJava REPL with Groovy | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-groovy` |
| SciJava REPL with Clojure | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-clojure` |
| SciJava REPL with JavaScript | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-javascript` |
### FAQ
* __Is it fast?__
Endpoints are synthesized in a local cache under `~/.jgo`.
So invoking the same endpoint a second time is really quick.
* __What does "no installation" mean?__
Classpath elements are [hard-linked](https://en.wikipedia.org/wiki/Hard_link)
into `~/.jgo` from `~/.m2/repository` rather than copied, so the `~/.jgo`
folder has a tiny footprint even if you execute lots of different endpoints.
* __What if an endpoint has a new version?__
Pass the `-U` flag to `jgo` to rebuild the endpoint.
Note that unlike `mvn`, though, `jgo` does not check for updates otherwise.
### Configuration
You can configure the behavior of `jgo` using the `~/.jgorc` file.
#### Repositories
You can define additional remote Maven repositories,
from which artifacts will be retrieved. E.g.:
```ini
[repositories]
scijava.public = https://maven.scijava.org/content/groups/public
```
If you need more control over where artifacts come from—for example, if you
want to use your own remote Maven repository as a mirror of Maven Central—you
can do it using Maven's usual `~/.m2/settings.xml`; see [Using Mirrors for
Repositories](https://maven.apache.org/guides/mini/guide-mirror-settings.html).
You can also use the `-r` flag to pass additional repositories to individual
invocations of jgo.
#### Shortcuts
You can define shortcuts for launching commonly used programs:
```ini
[shortcuts]
repl = imagej:org.scijava.script.ScriptREPL
imagej = net.imagej:imagej
fiji = sc.fiji:fiji:LATEST
scifio = io.scif:scifio-cli
```
Shortcuts are substituted verbatim from the beginning of the endpoint,
single-pass in the order they are defined. So e.g. now you can run:
```shell
jgo repl
```
Note that with the `repl` shortcut above, the main class
(`org.scijava.script.ScriptREPL`) comes from a _different_ artifact than
the toplevel artifact (`net.imagej:imagej`). This is intentional, so that
all of [ImageJ](https://imagej.net/), including all of the various SciJava
`scripting-` plugins, is included in the classpath of the REPL.
#### Settings
There are a few configurable settings:
```ini
[settings]
m2Repo = /path/to/.m2Repo (default ~/.m2/repository)
cacheDir = /path/to/.jgo (default ~/.jgo)
links = soft (options: hard, soft, none; default hard)
```
Note that the `jgo` cache dir can also be set via the `JGO_CACHE_DIR` environment
variable when using **Python** `jgo`. The precedence of reading the cache dir, from
highest to lowest:
- `JGO_CACHE_DIR` environment variable
- `cacheDir` in `settings` sections in `~/.jgorc`
- default to `~/.jgo`
### Pitfalls
#### Dependency management
Maven has a feature whereby a project can override the versions of transitive
(a.k.a. inherited) dependencies, via a `` configuration.
The problem is: a library may then believe it depends on components at
particular versions as defined by its ``, but downstream
projects which depend on that library will resolve to different versions.
See [this SO thread](https://stackoverflow.com/q/45041888/1207769) and
[this gist](https://gist.github.com/ctrueden/d058330c8a3687317806ce8cc18332c3)
for full details.
To work around this issue, you can pass `-m` to jgo, which
causes it to add all endpoints to the synthesized POM's
`` section using
[import scope](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies).
By doing this, the versions of transitive dependencies used in the synthesized
project should more precisely match those of each endpoint itself—although in
the case of multiple endpoints concatenated via the `+` operator with
conflicting dependency management, the earlier endpoints will win because they
will be declared earlier in the POM. See also
[issue #9](https://github.com/scijava/jgo/issues/9) in the jgo issue tracker.
## Development
### Code style
`jgo` uses [`black`](https://github.com/psf/black) for its code style.
After `pip install tox`, you can lint the code with:
```shell
tox -e lint
```
## Alternatives
* [JBang](https://github.com/jbangdev/jbang)
* [mvnx](https://github.com/mvnx/mvnx)
* [JPM4J](https://github.com/jpm4j) (discontinued)
* [Mop](https://github.com/chirino/mop) (unmaintained)
* [marun](https://github.com/nishemon/marun) (unmaintained, Python 2 only)