How can I increase the heap/memory size when launching a sub-JRuby?

Historically, JRuby has been very slow to start up, so we have tried to recognize some commands that look like they may be launching more Ruby programs and we start those in the same JVM. In that case, you actually can't adjust the heap.

We have a special system property that controls this behavior VM-wide (pass on the command-line as -J-Djruby.launch.inproc=false):

With the inproc setting disabled, you can now pass -J arguments to the sub-JRuby as it will be launching a new JVM.

In the future, as JRuby and JVM startup performance increases, we may flip the default in-process launching behavior to false to match most peoples' expectations. See also this thread on the JRuby mailing list for a discussion of jruby.launch.inproc.

Why does my application use more memory under JRuby than under ?

Why do I get "Unrecognized option...JVM creation failed" when passing -J flags like -splash?

On Windows, the native jruby.exe launcher usually loads the JVM's DLL directly and spins up the JVM in
the same process, rather than launching an external process using the java.exe command. However, -splash and a few other options are only supported by the java.exe command and are unrecognized by the DLL.

Because we have no way of knowing what options are or are not supported by the DLL, we provide a flag for the
jruby.exe command to force using java.exe and spinning an external process: -Xfork-java. Passing this flag to the jruby command line will allow those other java.exe-only flags to work correctly.

General

Where can I find more information about the Ruby language?

The Ruby Language Home Page has links to a wide range of resources for learning about Ruby, downloading releases of the C implementation of Ruby, documentation on Ruby, and community outlets for talking about Ruby.

The Pragmatic Programmers are the publishers of the de facto standard Ruby text, "Programming Ruby". It is considered a must-have manual to the Ruby language and libraries.

Almost everything you learn about the Ruby language is directly applicable to working with JRuby. JRuby aims to be a drop-in replacement for the C implementation of Ruby.

What incompatibilities does JRuby have with the C implementation of Ruby?

Does JRuby support Ruby 1.9.x features?

Yes. JRuby officially started supporting 1.9.2 features as of the 1.6.x line of releases, though it
is not default in those versions. You must specify the --1.9 flag at the command line or in a JRUBY_OPTS
environment variable, or add "compat.version=1.9" to .jrubyrc (on 1.6.5 or higher).

Ruby 1.9 mode is default in JRuby 1.7.0 and later, 1.8.7 compatibility can still be used with the --1.8 flag.

How do I run JRuby without the command-line scripts?

Frequently users want to run JRuby from NetBeans, from Eclipse, launched from an existing Java application, or in other ways that don't use the command-line scripts. In addition to having jruby.jar and its dependency jars available in CLASSPATH, you must also have the following system property set:

-Djruby.home=<path-to-root-of-JRuby-installation>

You might also want to ensure the maximum memory is set higher than the JVM default. JRuby's own command-line scripts use a maximum of 256MB.

What if I want to use JRuby alongside C Ruby? How do I keep from getting confused?

Why can't JRuby find my installed gems?

JRuby can only see the gems installed with the gem command shipped with JRuby. The gems installed this way will be stored under $JRUBY_HOME/lib/ruby. If you try to run Rails and get the error, "Cannot find gem for Rails ~>1.2.2.0:" (or whatever version you are using), the problem is probably that you haven't installed the Rails-gem and its dependencies with the JRuby gem-command.

When I implement a Java interface and provide my own initialize method, I can't construct it anymore.

In JRuby 0.9.0, any class implementing a Java interface must explicitly call super in their initializers to set up the interface proxy. Add a super call to your implementation's initialize method and it should work.

How do I call JRuby from my existing Java program?

If you don't want to launch JRuby as a separate process, we recommend you use the Bean Scripting Framework (BSF) or Java 6's Scripting Support (JSR223). We do not recommend calling directly into the JRuby runtime, since that code is subject to change.

How do I get a Ruby backtrace when calling JRuby code from Java?

Note that Java 6's scripting via the BSF libraries might not preserve stack traces, and also launches more slowly. It's often preferable (as of February 2007) to use JRuby's own integration.

Why do I get a java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.visit() error when running JRuby 1.X with a custom classpath?

The problem stems from an ASM jar conflict. It was found by setting a custom classpath, which includes a version of Spring that has a conflicting ASM jar, and then invoking JRuby. The easiest workaround is to build jruby-complete as a single jar and edit the JRuby config file (not sure about Windows, but it should be similar) to source only the jruby-complete jar. You will need to add ALL other jars, which I believe includes your jdbc driver as well.

How do I check which version of the JVM JRuby is running on?

Running Rails

Why does script/server (WEBrick) terminate right after saying "Booting WEBrick..."?

This happens if you require ActiveRecord-JDBC in your environment, but you haven't installed the gem. Make sure you have the ActiveRecord-JDBC gem installed.

How do I avoid installing the Rails gem twice for both CRuby and JRuby?

It is possible to set the GEM_HOME directory to a common one, but numerous users reporting weird behavior makes us recommend not setting a common GEM_HOME. DO NOT DO IT :)

The main problem arises that various gems have dependences on native gems. If you install with MRI it will install the c-extension version and not work with JRuby. If you install with JRuby it will not work with MRI. Hitting one of these gems, like Nokogiri, is much too common for this to be worth it.
You just need to set GEM_HOME to point to your CRuby's gem directory. For example, in tcsh:

I get the error "undefined method 'cattr_accessor' for ActiveRecord::Base:Class (NoMethodError)" after configuring activerecord-jdbc-adapter. What is wrong?

I keep getting "500.html running rails app built by goldspike in a JEE Container". What is wrong?

You might not have set the production DB settings in database.yml properly. Goldspike by default builds a war that runs the app in production mode.

You can confirm the problem by finding the production.log file. If you're using JBoss, then it lives in $JBOSS_HOME/server/my_app/tmp/my_rails_war''1234''.war, where ''1234'' is a random number generated by JBoss.

Now you just need to put your i18n[_*].properties files in config/, et voilà!

Calling Into Java

Why do I get ClassNotFoundException when I call java.lang.Class.forName from Ruby?

When JRuby runs at the command line, it loads into the bootstrap class loader. This class loader lives above CLASSPATH, so libraries you add to CLASSPATH are not normally visible. Because Class.forName uses the class loader of the nearest non-system class that called it, it ends up seeing JRuby as the caller and looking for classes only in CLASSPATH.

The workaround for this is simple: Uuse JRuby's import or include_class methods to load the class, or just reference it directly as in Java::my.package.MyClass or org.postgresql.Driver.

How do I access an inner class with a lowercase name?

Sometimes, developers name their inner classes beginning with a lowercase letter. This prevents JRuby from accessing it the "normal way" (it thinks it's a method). For example:

In Java (from the com.sun.enterprise.ee.cms.core package of the Shoal project)

You can also just put the following line somewhere in your Rakefile, or in a custom Rakefile in lib/tasks/*.rake:

ENV['SKIP_AR_JDBC_RAKE_REDEFINES'] ='1'

I am having a weird JNI problem. Help me!

There are two scenarios in which JNI problems occur:

When the jar is in JRuby 1.1.2's lib.

When the jar is loaded using ruby's "require" statement in JRuby < 1.1.

These two scenarios are described below.

JRuby 1.1.2 +

JRuby 1.1.2 changed how it set up the classpath. Earlier versions merged the CLASSPATH environment variable with all .jar files in JRUBY_HOME/lib and passed them to the JVM via the -classpath option. JRuby 1.1.2 instead passes all .jar files in lib to the JVM via the -Xbootclasspath/a: option, while CLASSPATH is passed using -classpath. Jar files that use JNI (e.g. sqljdbc.jar) don't work correctly when they're in the boot classpath, so they should not be placed in JRuby's lib directory. Instead, they should be loaded with require or by setting the CLASSPATH environment variable.

I tried the --server option and received an error

You tried the performance tuning option --server but received an error like "Error: no server' JVM atc:\Program Files\Java\jre6\bin\server\jvm.dll'."
On windows the Java Runtime Environment (JRE) inclues the client VM by default but does not include the server VM. You should download an install the Java Development Kit (JDK).
If you want to use the server VM with the JRE, you can copy JDK's jre\bin\server folder to a bin\server directory in the Java SE Runtime Environment.

How can I make JRuby always use IPv4 addresses, rather than trying to use IPv6

Some JDKs (like OpenJDK/Sun/Oracle/Hotspot) try to use IPv6 addresses for e.g. "localhost" when possible.
If using only similar JDKs to connect, this isn't a problem. However, other tools usually prefer IPv4 addresses and may have trouble connecting.

You can adjust how the JDK (at least OpenJDK/Sun/Oracle/Hotspot) decides to use IPv6 versus IPv4 addresses
via these networking properties.
You can add them to the Java startup options like this:

export JAVA_OPTS="-Djava.net.preferIPv4Stack=true"
jruby ...

Or pass directly to JRuby using -J-D like this:

jruby -J-Djava.net.preferIPv4Stack=true ...

I am seeing an error like "InvalidKeyException" or "Invalid key length". How can I fix it?

This error is reported when the JDK or JRE you're running on does not allow stronger encryption. There are
a few different ways to work around it.

My server seems to have many threads stuck waiting on a Mutex, and I'm not getting good concurrency and request throughput. Why?

If you force a dump of threads on the server JVM, you may see a stack trace like this:

"qtp368471295-36" prio=10 tid=0x00007fbf987c6800 nid=0xa277 waiting on condition [0x00007fbf2c99c000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000070a1e7968> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:811)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1201)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:312)
at org.jruby.RubyThread.lockInterruptibly(RubyThread.java:1468)
at org.jruby.ext.thread.Mutex.lock(Mutex.java:91)
at org.jruby.ext.thread.Mutex$INVOKER$i$0$0$lock.call(Mutex$INVOKER$i$0$0$lock.gen)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:134)
at rubyjit.Rack::Lock$$call_9D2E3A2DC6D4739AEFA0FEFD72B6C9712EF582B8.chained_0_ensure_1$RUBY$__ensure__(/data/app/taxman/installs/taxman_110bbe712d8bf6ee3955b8e87573c2cc278fe20a/vendor/bundle/jruby/1.9/gems/rack-1.4.5/lib/rack/lock.rb:14)
at rubyjit.Rack::Lock$$call_9D2E3A2DC6D4739AEFA0FEFD72B6C9712EF582B8.__file__(/data/app/taxman/installs/taxman_110bbe712d8bf6ee3955b8e87573c2cc278fe20a/vendor/bundle/jruby/1.9/gems/rack-1.4.5/lib/rack/lock.rb)
at rubyjit.Rack::Lock$$call_9D2E3A2DC6D4739AEFA0FEFD72B6C9712EF582B8.__file__(/data/app/taxman/installs/taxman_110bbe712d8bf6ee3955b8e87573c2cc278fe20a/vendor/bundle/jruby/1.9/gems/rack-1.4.5/lib/rack/lock.rb)
at org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
at rubyjit.ActionDispatch::Static$$call_98B9D217DEE0C8798054918A3A9A20D7242072EA.__file__(/data/app/taxman/installs/taxman_110bbe712d8bf6ee3955b8e87573c2cc278fe20a/vendor/bundle/jruby/1.9/gems/actionpack-3.2.16/lib/action_dispatch/middleware/static.rb:63)
at rubyjit.ActionDispatch::Static$$call_98B9D217DEE0C8798054918A3A9A20D7242072EA.__file__(/data/app/taxman/installs/taxman_110bbe712d8bf6ee3955b8e87573c2cc278fe20a/vendor/bundle/jruby/1.9/gems/actionpack-3.2.16/lib/action_dispatch/middleware/static.rb)
...

The trace above indicates there's a single JRuby runtime handling many concurrent requests, but Rails's "threadsafe" mode is not enabled. As a result, Rails inserts a lock acquisition into the request pipeline, and requests execute in serial. Generally, when deploying on JRuby, you will want to either be running threadsafe mode (single JRuby runtime, many concurrent requests) or non-threadsafe mode but with many JRuby instances.

Classpath errors on Mac OS X

Java on OS X adds additional folders (nonstandard) to the classpath. /Library/Java/Extensions and ~/Library/Java/Extensions can contain additional .jar files, which are automatically made available to Java. However, if you have a .jar in Extensions that also happens to be used by JRuby (but are different versions, or were compiled for an older version of Java) having both in the classpath can cause conflicts. You can examine the classpath from irb, by checking the $CLASSPATH global variable, which will list all .jar files used by JRuby which are in the classpath.

One common error caused by having two conflicting versions of the same class on the classpath include: