jruby/docs BETA
JRuby · intro

Use any Java JAR from JRuby (no gem required)

5 min read

Use any Java JAR from JRuby (no gem required)

You don’t need a Ruby gem wrapper to use a Java library. JRuby treats .jar
files as first-class load targets — require works on them the same as on
.rb files.

Get the jar

Most Java libraries publish their releases on Maven Central. The URL pattern is

https://repo1.maven.org/maven2/{group/with/slashes}/{artifact}/{version}/{artifact}-{version}.jar

For jsoup (an HTML parser):

mkdir vendor/jsoup
curl -L -o vendor/jsoup-1.22.2.jar \
  https://repo1.maven.org/maven2/org/jsoup/jsoup/1.22.2/jsoup-1.22.2.jar

Load and use it

require 'java'
require_relative 'vendor/jsoup/jsoup-1.22.2.jar'

java_import 'org.jsoup.Jsoup'

doc = Jsoup.connect("https://example.com").get
puts doc.title
puts doc.select("a").map { |a| [a.text, a.attr("href")] }

That’s the whole pattern. JRuby resolved the .jar, registered its classes
with the JVM, and java_import made org.jsoup.Jsoup available as a
top-level constant. Every public Java class in the jar is reachable
either by full name (Java::OrgJsoupNodes::Element) or by importing.

Loading a directory of jars

Some libraries ship as several jars (Lucene’s core + analysis-common +
queryparser, Jackson’s core + databind + annotations). Glob and
require all of them:

require 'java'

Dir[File.expand_path('vendor/**/*.jar', __dir__)].sort.each do |jar|
  require jar
end

sort keeps the load order deterministic — useful when one jar shadows
classes from another.

Inspecting a jar with JarFile

When you want to see what’s inside before importing — for example, to
discover which packages a fat-jar bundles, or pull the version out of its
manifest — use java.util.jar.JarFile:

 include "jsoup-inspect.rb"

A few good uses for this:

  • Confirm a fat-jar actually bundles its dependencies (look for class
    prefixes from packages you didn’t expect).
  • Pull Implementation-Version out of an unknown jar so your app can
    log which build it loaded.
  • Double-check that a jar exports the package you’re trying to import.

Where to store jars

Pick the convention that fits the project:

  • vendor/ checked into git. Reproducible, no network at boot,
    but bloats the repo. Best for small jars and air-gapped environments.
  • A Rakefile task that curls them on first run. Repo stays light,
    CI bootstraps automatically. Add the target dir to .gitignore.
  • ~/.m2/repository/. Let Maven manage them and point JRuby at the
    resolved paths. Portable across machines that have mvn, awkward for
    ones that don’t.

When a gem is the right answer

If you’re shipping more than a handful of jars or want to share them
across multiple JRuby projects, package the bundle as a thin gem: a single
lib/{name}.rb whose only job is require_relative-ing the bundled jars.

Scaling up: jar-dependencies

Once a project has several Java libraries with their own transitive
dependencies, maintaining curl commands and manual jar lists becomes
fragile. The jar-dependencies gem lets you declare Java dependencies in a
gemspec and resolves the full dependency graph via an embedded Maven runtime
— no mvn in your PATH needed, and Jars.lock pins the exact versions.
See the Manage Java dependencies with jar-dependencies recipe.

Next steps

  • Add a build-time step (Rake, Mage, plain shell) that fetches the jars
    you need so a fresh checkout becomes runnable in one command.
  • For libraries that ship annotations (@Nullable, @NotNull), grab the
    annotation jar too — JRuby reflects over them at load time and will
    otherwise warn at first use of an annotated class.
  • Browse the library’s docs on this site to find the entry-point classes
    worth java_import-ing.
← All recipes