🧵 From JRuby + WebLogic Panic to Peace: A Debugging Story
Source: Dev.to
😰 The Situation
We have multiple JRuby applications deployed on Oracle WebLogic. One of them suddenly stopped working even though it had been:
- ✅ Working in production
- ✅ Working earlier on the same server
During startup it failed with:
org.jruby.exceptions.StandardError:
(GitError) https://github.com/jruby/warbler (at master@973d14c)
is not yet checked out. Run `bundle install` first.
Multiple layers of errors appeared, starting the investigation.
🥊 Phase 1: Class Conflict Error
The first error looked like a classic class‑loader issue:
undefined method `bytesize' for Rack::Utils:Module
Typical causes:
- Different Rack versions loaded
- Library collisions
- Parent‑first classloading overrides
Our environment:
- Multiple JRuby apps in the same WebLogic domain
- Different JRuby versions (one app using 9.3.5.0, the other 9.4.5.0)
- Different Rack versions
- WebLogic loads classes parent‑first by default, so server‑level classes can override WAR classes.
Fix Attempt #1 – weblogic.xml Change
We added the following to weblogic.xml to prefer classes packaged inside the WAR:
true
This forces WebLogic to load classes from WEB-INF/classes before delegating to the parent classloader.
Cleaning Old Deployments
Multiple WAR versions (including stale ones) cause WebLogic to validate all of them, which can surface hidden conflicts. We cleaned the staging directories:
$DOMAIN_HOME/servers/AdminServer/tmp$DOMAIN_HOME/servers/AdminServer/cache
(Stop the server before cleaning.)
Result: The class‑conflict error disappeared, but a new error emerged.
💥 Phase 2: The Git/Bundler Explosion
After the class‑loader fix, the application failed with:
(GitError) https://github.com/jruby/warbler (at master@973d14c)
is not yet checked out. Run `bundle install` first.
Why Bundler Was Running Inside a WAR
A WAR should be a fully packaged artifact; bundle install is not expected at runtime. The error indicated that Bundler was looking for a Git checkout that didn’t exist inside the deployed WAR.
Discovering the Root Cause
Extracting the WAR (jar xf myapp.war) revealed:
WEB-INF/gems/bundler/gems/warbler-973d14c8f7e3
The suffix (973d14c8f7e3) shows that Warbler was installed from a Git repository. In the Gemfile we had:
gem 'warbler', '2.0.5',
git: 'https://github.com/jruby/warbler',
branch: 'master',
platforms: :jruby
Bundler stored the commit metadata and expected the Git repository to be present at runtime. In WebLogic there is no .git directory, so Bundler raised the GitError.
Correct Fix
-
Pin Warbler to a specific commit (or use the Rubygems version) instead of a mutable branch:
gem 'warbler', git: 'https://github.com/jruby/warbler.git', ref: '973d14c8f7e3' # or the desired commit hash -
Rebuild the bundle without cached data:
bundle install --no-cache -
Re‑package the WAR:
RAILS_ENV=production bundle exec jruby -S warble --trace -
Restart the WebLogic service and redeploy the clean WAR.
Result: The application started successfully.
What Actually Happened
- Layer 1: Classloader conflict caused a Rack
bytesizeerror. - Resolution: Set “ in
weblogic.xmland cleared stale deployments. - Layer 2: A Git‑based Warbler gem left stale metadata in the bundled gems.
- Resolution: Pin Warbler to a specific commit (or use the Rubygems release) and rebuild the bundle with
--no-cache.
The issue was not a single bug but a combination of server classloading behavior and Bundler’s handling of Git‑sourced gems.