Description
I’m testing a Rails 8 app on JRuby 10 using warbler from the master branch (as of July 1, 2025), and running into a deployment failure when deploying the resulting WAR file to Tomcat 9.
The app is completely minimal and exists specifically to demonstrate this problem. You can find it here:
https://github.com/tillsc/warbler_test
It uses only activerecord-jdbcsqlite3-adapter for JRuby + SQLite and no custom configuration. The WAR builds fine, but Tomcat fails to deploy it.
Environment:
- JRuby: 10.0.0.1
- Rails: 8.0.2
- Java: OpenJDK 24.0.1
- Tomcat: 9.0.106
- OS: macOS (Apple Silicon)
- warbler: master branch from jruby/warbler
How to reproduce:
git clone https://github.com/tillsc/warbler_test
cd warbler_test
bundle install
rails war
Then copy the .war file to Tomcat’s webapps/ directory and start Tomcat.
Tomcat fails with the following error during deployment:
01-Jul-2025 11:47:10.206 SEVERE [Catalina-utility-1] org.apache.catalina.core.StandardContext.listenerStart Error sending 'Context Initialized' event to listener instance of class [org.jruby.rack.rails.RailsServletContextListener]
java.lang.NoClassDefFoundError: org/jruby/CompatVersion
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(java/lang/Class.java:3035)
at java.lang.Class.getDeclaredMethods(java/lang/Class.java:2331)
at org.jruby.javasupport.binding.MethodGatherer$1.computeValue(org/jruby/javasupport/binding/MethodGatherer.java:300)
at org.jruby.javasupport.binding.MethodGatherer$1.computeValue(org/jruby/javasupport/binding/MethodGatherer.java:296)
at java.lang.ClassValue.getFromHashMap(java/lang/ClassValue.java:229)
at java.lang.ClassValue.getFromBackup(java/lang/ClassValue.java:211)
at java.lang.ClassValue.get(java/lang/ClassValue.java:117)
at org.jruby.javasupport.binding.MethodGatherer$2.computeValue(org/jruby/javasupport/binding/MethodGatherer.java:310)
at org.jruby.javasupport.binding.MethodGatherer$2.computeValue(org/jruby/javasupport/binding/MethodGatherer.java:307)
at java.lang.ClassValue.getFromHashMap(java/lang/ClassValue.java:229)
at java.lang.ClassValue.getFromBackup(java/lang/ClassValue.java:211)
at java.lang.ClassValue.get(java/lang/ClassValue.java:117)
at org.jruby.javasupport.binding.MethodGatherer.eachAccessibleMethod(org/jruby/javasupport/binding/MethodGatherer.java:184)
at org.jruby.javasupport.binding.MethodGatherer.getMethods(org/jruby/javasupport/binding/MethodGatherer.java:164)
at org.jruby.javasupport.binding.MethodGatherer.setupMethods(org/jruby/javasupport/binding/MethodGatherer.java:617)
at org.jruby.javasupport.binding.MethodGatherer.initialize(org/jruby/javasupport/binding/MethodGatherer.java:134)
at org.jruby.javasupport.binding.ClassInitializer.initialize(org/jruby/javasupport/binding/ClassInitializer.java:44)
at org.jruby.javasupport.binding.Initializer.setupProxyClass(org/jruby/javasupport/binding/Initializer.java:60)
at org.jruby.javasupport.Java.createProxyClass(org/jruby/javasupport/Java.java:595)
at org.jruby.javasupport.Java.generateClassProxy(org/jruby/javasupport/Java.java:553)
at org.jruby.javasupport.Java.createProxyClassForClass(org/jruby/javasupport/Java.java:510)
at org.jruby.javasupport.JavaSupport$2.computeValue(org/jruby/javasupport/JavaSupport.java:125)
at org.jruby.javasupport.JavaSupport$2.computeValue(org/jruby/javasupport/JavaSupport.java:117)
at org.jruby.javasupport.JavaSupport.getProxyClassFromCache(org/jruby/javasupport/JavaSupport.java:399)
at org.jruby.javasupport.Java.getProxyClass(org/jruby/javasupport/Java.java:471)
at org.jruby.javasupport.Java.createProxyClassForClass(org/jruby/javasupport/Java.java:499)
at org.jruby.javasupport.JavaSupport$2.computeValue(org/jruby/javasupport/JavaSupport.java:125)
at org.jruby.javasupport.JavaSupport$2.computeValue(org/jruby/javasupport/JavaSupport.java:117)
at org.jruby.javasupport.JavaSupport.getProxyClassFromCache(org/jruby/javasupport/JavaSupport.java:399)
at org.jruby.javasupport.Java.getProxyClass(org/jruby/javasupport/Java.java:471)
at org.jruby.javasupport.Java.getInstance(org/jruby/javasupport/Java.java:308)
at org.jruby.javasupport.Java.getInstance(org/jruby/javasupport/Java.java:290)
at org.jruby.javasupport.JavaUtil.convertJavaToUsableRubyObject(org/jruby/javasupport/JavaUtil.java:198)
at org.jruby.javasupport.JavaMethod.convertReturn(org/jruby/javasupport/JavaMethod.java:382)
at org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:306)
at org.jruby.javasupport.JavaMethod.invokeDirect(org/jruby/javasupport/JavaMethod.java:168)
at RUBY.capture(uri:classloader:/jruby/rack/capture.rb:94)
at org.jruby.RubyClass.finvoke(org/jruby/RubyClass.java:702)
at org.jruby.RubyBasicObject.callMethod(org/jruby/RubyBasicObject.java:372)
at org.jruby.rack.DefaultRackApplicationFactory.captureMessage(org/jruby/rack/DefaultRackApplicationFactory.java:494)
at org.jruby.rack.DefaultRackApplicationFactory.access$000(org/jruby/rack/DefaultRackApplicationFactory.java:44)
at org.jruby.rack.DefaultRackApplicationFactory$RackApplicationImpl.init(org/jruby/rack/DefaultRackApplicationFactory.java:459)
at org.jruby.rack.DefaultRackApplicationFactory.getApplication(org/jruby/rack/DefaultRackApplicationFactory.java:118)
at org.jruby.rack.SharedRackApplicationFactory.doInit(org/jruby/rack/SharedRackApplicationFactory.java:36)
at org.jruby.rack.RackApplicationFactoryDecorator.init(org/jruby/rack/RackApplicationFactoryDecorator.java:104)
at org.jruby.rack.RackServletContextListener.contextInitialized(org/jruby/rack/RackServletContextListener.java:50)
at org.apache.catalina.core.StandardContext.listenerStart(org/apache/catalina/core/StandardContext.java:4059)
...
Caused by: java.lang.ClassNotFoundException: org.jruby.CompatVersion
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1354)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1163)
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
...
This appears to be a missing class in JRuby 10 that is still referenced by jruby-rack or something pulled in by Warbler.
Happy to help test further or narrow it down. Let me know if you need the full WAR or build logs.