We get a lot of bug reports on the JRuby project. No, it's not because JRuby's a buggy POS. It's because we're implementing the core of an entire platform. It's hard.
Over the past year or so we kinda let the bug tracker go a little wild. We've never had more than two full-time people on the project, and community contributions wax and wane with the seasons, so we've had to choose our battles. For some amount of time, we would focus on performance, since without a reasonably-performing implementation, nobody would choose to use JRuby. Then we'd cycle back to fixing bugs, usually in the last couple weeks before a release. So the flow of bug fixes waxed and waned with our release cycles.
The problem with this approach was that we really couldn't keep up with all the reports coming in and continue to work on the "unreported issues" of JRuby like performance. So something had to give, and it was sometimes the bugs.
Roughly around September, we crossed an important threshold: 500 open bugs. They dated as far back as 2006 (we moved to Codehaus in 2006), and across the entire release sequence of JRuby; there were even some bug reports against pre-1.0 versions. From September until about mid-January, we worked to keep the number of open bugs below 500. Sometimes it would peek above, but we were generally successful.
About mid-January, I figured it was time to really bite the bullet, and I started walking from the oldest bug forward. It has been a long slog, but I'm making great progress.
So far, I've managed to whittle the total number of bugs down from 506 to 326, and that's with a couple dozen more filed in the past two weeks. The majority of these were either already fixed or invalid/incomplete bugs, but I've also made a concentrated effort to focus on and fix as many as possible. At the very least, I've made an attempt on every single one.
During that process, I learned a bit about how my brain works. During the past year, if I didn't know immediately how to fix a bug I often walked away from it and worked on something fun like compiler optimization. But during this latest bug hunt, because I did not want to just punt all those bugs one more time, I did something a little different.
Whenever I encountered a bug that seemed difficult or that I simply didn't want to fix, I would do one of two things:
- Take a break. Often this meant I had reached my limit and needed a breather. A little Wii, a glass of scotch, a movie...anything to take my mind of it for a bit.
- Count to ten. Sometimes, after reading through the bug, all I really needed was a moment for my brain to start "wondering" about the solution. Once the wheels started turning, I was almost compelled to dig deeper.
For your amusement, here is the complete list of bugs we have resolved during the past nine weeks, since shortly after the 1.1.6 release. These aren't all fixes, but even the "already fixed", "won't fix", "not a bug", or "incomplete" ones were reviewed, tested, and considered. A couple of these I just applied patches or marked resolved based on someone else's work. And of course we're not done with JRuby 1.2 yet. Just you wait and see :)
Bugs Resolved (Fixed, Won't Fix, Not A Bug, or Incomplete Information), Past Nine Weeks:
(in the order they were resolved)
File#chmod always returns -1, fails rubyspec | |
Solidify public APIs separate from those that might change | |
ant task api-docs runs out of memory, patch included | |
Rubinius -bad instanceof tests in RubiniusMachine for attempt at fast path evaluation | |
Zlib::GzipReader.each_line yields compressed data | |
[PATCH] Support atime updates via utime | |
Testing errors in test_java_mime.rb | |
test_java_pkcs7.rb - Problem coercing Bignum into class java.math.BigInteger | |
Bad cast in jruby-openssl X509Utils | |
IO.read and IO.readlines do not take a block | |
ConcurrencyError bug when installing Merb on JRuby | |
jruby can't load file produced with jrubyc | |
RaiseException#printStrackTrace doesn't deal well with nil messages | |
sqlite db file on MRI is put in db dir. We put it in CWD. | |
:date is stored as integer (not date) in sqlite3 | |
NPE at Connection Shutdown | |
java.lang.NullPointerException when trying to connect to a Oracle XE database | |
Renaming indexed columns fails | |
Rails migrations fail with: undefined method `create_database' for class `# | |
ActiveRecord/JRuby Memory leak in update_attributes!() | |
new samples/jnlp dir: includes both unsigned and signed examples that work in Java 1.5 and 1.6 | |
using activerecord 'to_xml' method crashes JRuby (and debugger) | |
Constant lookup should omit topmost lexical scope; not bail out on first Object-hosting lexical scope | |
Array#reduce is undefined | |
JRuby command line scripts do not work with spaces in the path | |
patch attached to update eclipse .classpath to refer to bytelist-1.0.1.jar | |
patch attached to update eclipse .classpath to add new jars in build_lib/ | |
New IO#readpartial and IO#seek spec failures | |
jruby -S script/console fails in Rails application | |
IllegalArgumentException in X509V3CertificateGenerator when executing Hoe's rake gem running on SoyLatte JDK | |
New ARGF spec failures | |
Add public RubyInstanceConfig#setCompatVersion | |
loading rake breaks import | |
Float range to restrictive in FFI code | |
Array#pack('w') is broken (exceptions and wrong results) | |
ArrayIndexOutOfBoundsException in tmail | |
Can not execute JRuby 1.1.1 "ant test" with IBM JDK | |
JRuby trunk does not build with IBM JVM 1.5 | |
undefined method `quote' for Regexp:Class (NoMethodError) when runs gem list on AIX with IBM JAVA 1.5 | |
'-i flag not supported | |
Doesn't biuld on windows for ffi problem | |
[1.9] splat of array at front of assignment broken (same for other grammatical constructs) | |
tempfile.rb sucks in JRuby | |
Fixnums & Floats should be coerced to the narrowest java.lang.Number when passed to a java method that expects Object | |
jdbc_mysql.rb should not enforce the utf8_bin collation on table creation | |
Error doing add_column with Derby and jdbc-adapter-0.7.2 | |
[PATCH] Derby handling of binary/date/time fields. hsqldb handling of binary fields. | |
[activerecord-jdbcsqlite3 adapter] Date/Datetime/Time fields simplification to INTEGER sqlite storage type is not correctly handled | |
JRuby script engine does not load on IBM JDK | |
Update stdlib to an appropriate 1.8.6 patchlevel | |
Time assumes UTC timezone | |
Make JRuby's Time#local behave more like MRI | |
BigDecimal#precs fails two new rubyspec tests | |
Kernel.srand calls #to_i on number | |
Kernel#system does not work correctly | |
Performance degradation on write operations | |
error accessing JRuby DRb server from MRI DRb client | |
JRuby DRb client cannot connect to MRI DRb server | |
Many new Array#pack failures in updated RubySpecs | |
Time#_load RubySpec failures | |
Time#_dump RubySpec failures | |
Array#fill spec failures | |
Dir.pwd correctly displays dirs with unicode characters in them | |
spec --line does not work with JRuby | |
require "tempfile"; Dir.tmpdir fails | |
The private keyword doesn't change visiblity of previously called methods with same send/call site | |
Missing constant in Process::Constants on Mac OS X (darwin) | |
Including more than one java interface stops Test::Unit execution | |
Get Rails tests running in a CI server somewhere before 1.1.6 release, to ensure no future breakages | |
If 'jruby' executable is a relative symlink, JRuby won't start | |
Incorrect behavior for case/when when true or false are the first conditions | |
SystemStackError with YAML.dump | |
Javasand does not compile with JRuby 1.1.5 | |
idea | |
ConcurrentModificationException In Application Startup | |
Major divergence in threading behaviour between Ruby 1.8.6 and JRuby 1.1.6 | |
Deadlock between RubyModule.includeModule() and RubyClass.invalidateCacheDescendants() | |
Error in string encoding conversion | |
String#unpack('m') fails with ArrayIndexOutOfBoundsException | |
The body of POST requests is not passing through jruby-rack | |
JRuby can double slash ("//") the directory given by __FILE__ when "everything" suits this thing to happen. :-) | |
jdbc_postgre.rb issue handling nil booleans | |
Memory Leak in ActiveRecord-jdbc or JRubyEngine used with BeanScriptingFramework | |
jdbc_postgre.rb needs microsecond support | |
activerecord jdbc derby adapter should quote columns called "year" | |
jdbcderby adapter should ignore :limit for INTEGER | |
jdbcsqlite3 at JRuby on Rails do not work properly | |
Update H2 to a later version | |
Wrabler escapes config.ru twice | |
Upgrade to derby 10.4.2.0 to allow unique constraints with nullable columns | |
Mistake in selecting identity with H2/HSQLDB | |
java.lang.IllegalArgumentException in debug mode when using CLOB | |
Race condition in JRuby when Active Support is overriding Kernel.require | |
Inconsistent DynamicScope instances in evalScriptlet | |
java.lang.ArrayIndexOutOfBoundsException in RubyArray.java | |
Tempfile defaults to a directory that does not exist on Windows | |
String#unpack invalid output | |
Compiled case/when blows up with arrays as when clauses | |
attr_accessor, attr_reader, attr_writer, and attr not obeying visibility | |
Post parse processing of the result comment placing as example | |
Ability to write JUnit4+ tests in JRuby | |
Allow visible fields from inherited Java classes show up as instance variables (@foo) | |
IOWaitLibrary ready? returns nil when ready | |
JRUBY-1890 IO.popen does not support "-" | |
jirb exits on ESC followed by any arrow key followed by return | |
"RAILS_ROOT" cannot be put on a place different from "Context root" in Goldspike. | |
jruby.compile.frameless=true cause "Superclass method 'initialize' disabled." | |
Method#to_proc.call invocations much slower than normal Method#call invocations | |
Very unverbose message when problem with native library exists | |
jIRB cannot get any input with Polish characters (utf-8) on Mac OSX | |
Kernel#exec should not raise SystemExit | |
EOF handling in case of reading program from standard input | |
System.gc() is extremely expensive when calling Java code from JRuby | |
getting in $SAFE level 4 freezes | |
weakref-based singleton class "attached" can blow up in certain unusual circumstances | |
DST bug in second form of Time.local | |
next statement should return the argument passed, not nil | |
Pure-Java version of lstat doesn't fail on non-existing file | |
standardize and publish public API for embedders | |
SNMP Requests does not timeout properly | |
We should generate method binding code with APT | |
File output cuts off at a certain point? | |
NPE in org.jruby.RubyIO.flush | |
UDP locking problems when receiving from multiple senders on same port | |
usage of unexistant variable in REXML::SourceFactory | |
Nailgun does not compile under HP-UX | |
Process.kill breaks up JRuby, while works in MRI on Windows | |
'ant spec' failures on on MacOS | |
test_io (test_copy_dev_null) fails under WinXP | |
Multiple assignment could be made faster by not returning unused array | |
java.util.ConcurrentModificationException | |
Java input/output streams from Ruby string's backing byte array | |
Pathological slowdown in Array#insert | |
FileTest methods only work with string arguments | |
multi-byte character encoding probrem | |
Jruby shell script don't work on KSH shell | |
Pure-Java tempfile does not use a #make_tmpname callback | |
Dir["some glob"] doesn't work for files inside a jar | |
Dir.glob processes nested braces incorrectly | |
Faulty marshalling error blows up in ActiveSupport | |
Problems with the H2 jdbc adapter, schema metadata behavior | |
Make fields immutable where possible | |
ReWriteVisitor transforms Fixnums into base 10 despite their original format | |
Missing peephole optimizations in parser, compiler | |
DATA.flock causes ClassCastException | |
Recursively locking on a mutex results in deadlock | |
Regression: rubyspec run with -V option breaks JRuby | |
Wrong stacktraces from exceptions about wrong number of arguments | |
Exception when stopping WEBrick running the new rails application | |
jdbcpostgresql adapter inserts invalid number literals into generated SQL, causes exceptions | |
'attr' implementation is incompatible with MRI 1.9.1 behavior | |
Objects with custom to_yaml methods break collection to_yaml | |
Couple of new rubyspec failures for URI library | |
2 digit year resolves to 1st century rather than 20th when using postgres timestamp with timezone + activerecord-jdbcpostgresql-adapter | |
BasicSocket#close_read and #close_write not working | |
TCPSocket.new('localhost', 2001) connects on the wrong interface | |
Time Zone "MET" maps to Asia/Tehran | |
Class Socket is missing #bind | |
Thread#wakeup fails when sleep is called with a parameter | |
Zlib::Deflate doesn't appear to deflate | |
ArgumentError: dump format error() when unmarshalling Rails session and EOFError when unmarshalling hash with containing value of type ActionController::Flash::FlashHash | |
Some error saving to a Rails session [Marshalling bug?] | |
Net::HTTP spec failures in get_print spec; IO not getting expected "print" call | |
IO.popen of 'yes' process hangs on close | |
Precompiled scripts do not set initial position information correctly | |
unicode symbol not supported as in MRI | |
File.chown works with 64bit JDK, but raises NotImplementedError on 32 bit JDK | |
MS SQL-Server - Create/Drop Database bug | |
System triggered from inside of tracing behaves oddly | |
dbd-jdbc: Support Ruby DBI Statement.fetch_scroll | |
dbd-jdbc: Add helper functions to wrap already existing jdbc Connection and Statement objects | |
dbd-jdbc: Override Ruby DBI's default database return value coercion for Date / Time / Timestamp columns | |
dbd-jdbc: Register a handler for DBI 0.4.x's default parameter binding type coercion | |
Files added to a module via Kernel.autoload are not automatically loaded if the class they contain is extended | |
ActiveScaffold 1.1.1 fails with JRuby 1.1.2, probable path problem | |
If user's PATH contains '.' and 'jruby' resolves to './jruby', JRUBY_HOME is incorrectly set to '.', leading to 'NoClassDefFoundError' | |
Most Etc methods behave diferently on Windows under x32 and x64 JVMs | |
String#<<> | |
Memcache session store does not work across multiple application servers | |
'-S switch breaks if you have directory in pwd matching name of file in bin/PATH | |
CCE using proc{} in AR callbacks | |
Improve JRuby::Commands' handling of bindir | |
Cannot call super inside a method that overrides a protected method on Java base class | |
ThreadService.getRubyThreadFromThread supports only one non-rubynative thread at a time. | |
"No such file or directory (IOError)" when JAR file named in java.class.path but not active filesystem | |
JRuby does not support options in shebang line | |
gem generate_index broken | |
Rails static page caching won't generally work with Java ServletFilter unless some serious hack with the cache directory is found | |
Serialization of wrapped Java objects could be handled as user-marshalled data by Marshal | |
Newly overridden methods are not called if the old superclass method has already been called | |
specs hang under Apple Java 5 | |
Ruby runtimes are pinned to memory due to ChannelStream | |
Incomplete HTTS response from Microsoft IIS servers using net/https | |
popen IO lockup with multiple threads | |
Java Integration can now instantiate Java classes with no public constructor | |
JRuby wrapped Java objects formerly exposed readers for non-public fields | |
JAR URLs are inconsistently supported by APIs that access the filesystem | |
Kernel::fork should use forkall(2) on solaris instead of fork(2) | |
Have to call setPaint instead of assigning to g.paint | |
Pathname#realpath fails for Windows drive letters | |
convertToRuby does not work if to_s does not return a String (but for example nil) | |
Need a better solution for tracking Java object wrappers | |
When define_method replaces an inherited Java method, the ruby_case_version is not replaced | |
repeated popen call may throw NULL pointer exception | |
multi-byte exception message turned into garbled characters when Java Exception nested NativeException. | |
String#<<> | |
alias_method_chain pattern is extremely show on jruby | |
Unicode regular expressions by UTF-8 don't work | |
jirb does not echo characters to the terminal after suspend and resume in the shell | |
Dir[] results in NPE depending on permissions | |
integration issues with Java classes containing inner classes | |
Message method value of Exception is missing in Java when exception raised in ruby | |
Nested Class/Enum issue with JRockit | |
java classes with non-public constructors are incorrectly instantiated | |
Regression: Inheriting method with same name from two Java interfaces causes Java classloader error | |
jdbcsqlite3 adapter does not respect default parameter | |
[Derby] Allow select/delete/update conditions with comparison to NULL using '=' | |
jruby-openssl: SSLSocket.syswrite error for big (>16k) data | |
DRb "premature header" error on JRuby client | |
Create caching mechanism for all our many calls to callMethod from Java code | |
insert statement returns null from the postgresql jdbc adapter | |
Migration step with create_table with string column with :default => "" fails due to missing default value in SQL | |
ActiveRecord is slower on JRuby than on MRI | |
url style Postgres configuration is broken in rake. | |
def is almost 3x slower in JRuby | |
Table does not exist error possibly caused by upper case table name | |
ArrayStoreException in compiler when calling Array.fill | |
break performance is slower than MRI, sometimes slower than interpreted | |
active_scaffold - No such file or directory | |
Array#eql? rubyspec failure | |
Array#== rubyspec failure | |
Thread#status is "run" when thread is blocking on condition variable | |
RubySpec: Numeric#coerce calls #to_f to convert other if self responds to #to_f | |
permission javax.management.MBeanServerPermission "createMBeanServer"; | |
Using a ruby Numeric to set a parameter with a signature of java.lang.Integer causes a java.lang.ClassCastException | |
1.1.4 unable to use 'logging' gem (works in 1.1.3) | |
Attributes defined from Java tried to use current frame for visibility | |
defined? CONST is not following proper constant lookup rules | |
Digest::Base stores in memory all bytes passed to the digest, causing OutOfMemoryError | |
Some Socket constants not supported. | |
Different jruby behaviour that ruby 1.8.6/1.8.7/1.9 when running file that is named as one of required file. | |
Cloning java byte array returns incorrect object | |
ConcurrentModificationException | |
http spec tests fail when webrick starts on address 0.0.0.0 | |
JRuby conversion of String to Java String is arcane | |
FFI MemoryPointer#get_string(0, x) gets confused by null byte in the buffer | |
jruby -S picks up script from local directory | |
Incorrect namespace for CipherError | |
define_method methods do not display the correct stack trace, may not be using frame safely | |
Classpath search order is not respected by require when classpath includes both jars and directories | |
Problems with migrations where direct type specified | |
running with -rprofile with multithreaded test causes NPE | |
Update sybase driver to pass simple unit tests with jtds and verify it works with the new dialect keyword | |
New public LoadService#findFileToLoad method | |
ThreadContext should use SoftReference instead of WeakReference | |
import org.eclipse.jface.dialogs.MessageDialog -- causes java.lang.NullPointerException | |
Exception trying to use BSF (java.lang.NoClassDefFoundError: org/apache/bsf/util/BSFEngineImp) | |
rexml pretty printing wrap() error | |
undef'ing and redef'ing methods should give disabled message? | |
Java toString() mapping to invoke(... to_s ...).toString() doesn | |
Glassfish Gem 0.9.0 does not work with JRuby 1.1.5 | |
JRUBY-549 bfts test_file_test failures | |
Problem with active_scaffold defaults defined in application.rb | |
httprequest error for a SOAP request to a Rails ActiveWebService | |
Stomp gem hangs in Stomp::Client#subscribe | |
Class in default package can't be reopened under Java namespace | |
IO.select sometime reports Unable to establish loopback | |
JDBC adapter in JAR file not being picked up by java.lang.Class.forName in 1.1.3 (worked in 1.1.2) | |
Automatically convert RubyFile to java.io.File | |
Overriding require causes eval to give wrong __FILE__ in certain circumstances | |
Failure in String#crypt specs, Mac OS X, Soylatte | |
ENV[] is case sensitive on Windows | |
File.expand_path rubyspec failure on Mac OS X, Soylatte | |
Examine whether -Xrs flag to JVM could be used to improve our signal-handling logic | |
jirb + jline do not work in cygwin | |
Compilation Warning for Sun proprietary API using | |
Running merb under a concurrent load causes ArrayIndexOutOfBoundsExceptions | |
File.stat('/home') treated as a relative path | |
NPE when yielding method | |
EOFError while consuming REST web service from glassfish v3 | |
rails image_tag generates url get 404 | |
chmod_R broken | |
String#unpack with 'w' is completely unimplemented | |
Unable to insert YAML into t.text field (behavior different from Ruby 1.8.6) | |
Excess warnings when using rake TestTask | |
File.expand_path does not work as expected | |
defineAlias reports original name and not aliased one in stack traces | |
TCPSocket.new(dest_adrr, dest_port, src_addr, src_port) missing from JRuby | |
REXML returns error for add_attribute | |
org.jruby.util.RubyInputStream is unused | |
"jruby" script failed to find JRUBY_HOME leads to class not found | |
method `module_eval' for main:Object should be undefined? | |
Net::IMAP#authenticate stalls / blocks in recent versions of JRuby | |
1.1b1 doesn't build with gcj 4.2 | |
Make Time.now monotonically increasing | |
Etc.getpwuid should raise TypeError if invalid type | |
loadpath and classpath problem | |
JRuby crashes after running 110 RSpec examples | |
Add constant caching for Colon2 and Colon3 (specific module and Object cases) | |
super error message is inaccurate when superclass doesn't implement method. | |
File#getc fails on illegal seek when reading from /dev/ttyS0 on Linux | |
RubyUDPSocket.send tries to do inet address lookup, pauses too long for inet6 failure | |
CLONE -JIT max and JIT threshold should be adjusted for improvements in JRuby over the past months | |
FFI Stack Level Too Deep on Library.send(:method, args) | |
Add -y flag to debug the parser | |
Compiler closures use two different binding mechanisms, need better construction and caching logic | |
JRuby can't handle do/end blocks within String-inlined expressions | |
Group expression class path fails to parse | |
OpenSSL::Random#pseudo_bytes raises ArgumentError on negative arguments | |
"RStone" port of PyStone is slower on JRuby than 1.9 | |
Regression: error serializing array of objects with custom to_yaml def to yaml | |
builder library is slower in JRuby than in MRI | |
handling of file close while reading differs from mri | |
load and require don't work correctly for .class files | |
Import is sometimes confused by unquoted class name | |
Array#to_java with java object reference doesn't carry over object identity | |
IO.sysopen not defined | |
Illegal seek error trying to read() from pipe | |
Process.times returns invalid values | |
Process.uid does not work on non-natve platforms (jna-posix) | |
Compiled argument processing and arity checking are too large, too much bytecode | |
NKF(unsupported Q encode stream) | |
Embedding JRuby-Rack (non-war deployment) | |
Update ruby_test tests and incorporate changes into build | |
Timeout.rb is not working in special cases (Thread may block whole application). | |
Lack of default jruby.home in embedded usage causes NPE | |
File::link using CIFS raises Errno::EEXIST error if the 'old_file' is open while Matz Ruby raises Errno::ETXTBSY | |
Iterative String concatenation operations in JRuby degrade faster than in MRI. | |
jruby -S script/server fails in Rails application | |
after installing minigems (and after minigem setup gems not working on 1.1.6) | |
DRb hangs when transferring Ruby objects created in Java | |
Java Stacktrace and exception is swallowed | |
Wrong monitor handling in o.j.util.ChannelStream.read | |
Select with nil arrays should throw an exception |