Bizarre problem in 1.4.0RC1

Hi all,
I’m experiencing very strange behavior with 1.4.0RC1. The problem is, I
can’t seem to isolate a simple test case, when I extract the offending
code
from my app, everything works fine. The code works fine under builds of
1.4.0dev prior to commit 3f8ac10821a43dd63c1af40b801ba3e7e77f52d4 (found
using git bisect).

The error arises in this code fragment (again, if you try and run this
it
will run correctly, it is just within my app that it doesn’t work)

module Core

Thrown if an illegal element is used to create a Path or if the

syntax
for

creating a Path is not correct

class PathSyntaxError < RuntimeError
end

class Path
extend Forwardable

def_delegators :@path, :<=>, :hash, :each, :each_with_index, :map,

:inject,
:size, :length, :empty?

# Create a new Path
# Parameters:
# - contents: a Path, Symbol, String, Symbol[], String[] or nil. 

Strings
and
# Symbols will be parsed, Arrays will be decomposed into Path
elements,
# Paths will be copied and nil will return an empty Path
# Exceptions:
# PathSyntaxError: If contents is of an illegal type
def initialize(contents=nil)
@path = case contents
when NilClass
[]
when String, Symbol
parse(StringScanner.new(contents.to_s))
when Array
contents.map do |e|
case e
when String
e.to_sym
when Array, Path
Path.new(e)
else
e
end
end
when Path
contents.map do |e|
case e
when Path
Path.new(e)
else
e
end
end
else
raise PathSyntaxError, “Un Path puede formarse a partir de otro
Path, un String, un Symbol, un Array de Symbol o String, o nil. Un
#{contents.class} es inaceptable” #<===== This is line 716
end
end
end
end

The error I’m getting is:

/Users/mario/Desktop/abstra.cc/projects/BMClient/src/main/ruby/conf/…/app/core/model.rb:716:in
`raise’: exception object expected (TypeError)

Which, of course, makes absolutely no sense. Now, I added a ‘p contents’
and
‘p contents.class’ at the beginning of the initialize method. It turns
out
contents is nil (and its class IS NilClass).

Which makes even less sense, since it should be caught by the “when
NilClass” at the top of the case. If I change the “when NilClass” to
“when
nil” then the case works fine (but then crashes somewhere else).

So it seems there’s some corruption of SOMEthing happening which is
messing
up the class structure.

Now, looking at the commit where the error first pops up
(3f8ac10821a43dd63c1af40b801ba3e7e77f52d4) things are even
weirder…it’s
just a one-line patch to securerandom.rb.

I’m completely out of options, aside from freezing our environment at
the
previous commit. I don’t think it’s productive to file a bug at this
point
since I really can’t reproduce it. Anybody have any ideas as to what I
can
do, or at least how I can go about isolating the bug?

Thanks,
-Mario.

Curiouser and curiouser…
If I try to run against the current trunk (1.5.0dev, just pulled from
github) the error continues to occur. However, if I add the
jruby-engine-1.1.6 JAR to my classpath AFTER the jruby-complete JAR,
everything works fine.

AARRGGHHHHHH!!! Help please!

-Mario.


I want to change the world but they won’t give me the source code.

Hi Mario,

On Tue, Oct 6, 2009 at 9:49 PM, Mario C. [email protected]
wrote:

Hi all,
I’m experiencing very strange behavior with 1.4.0RC1. The problem is, I
can’t seem to isolate a simple test case, when I extract the offending code
from my app, everything works fine. The code works fine under builds of
1.4.0dev prior to commit 3f8ac10821a43dd63c1af40b801ba3e7e77f52d4 (found
using git bisect).

This is indeed very bizarre. The one-line change mentioned above
should not really cause such problem, and seems to be completely
unrelated to the problem you’re seeing.

As a suggestion, could you revert that change manually on top of the
latest master branch and re-run your app to see whether it works or
not. I just would like to make sure that indeed this change is
responsible for the problem (or not).

Thanks,
–Vladimir


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Wed, Oct 7, 2009 at 10:45, Vladimir S. [email protected]
wrote:

–Vladimir

Hi Vladimir,

Things are even weirder. I reverted the change but the problem is still
occurring. Heisenbug ho! The problem now occurs regardless of the
inclusion
of jruby-engine-1.1.6 in the CLASSPATH.

-Mario.

More bizarreness is ensuing.
I added a ‘p “contents class: #{contents.class}”’ right before the case
contents…and the app started working.

I then removed it…and it continued to work

I added it again…and got the error again.

So this is a heisenbug of the worst sort, one that has absolutely no
logic
behind it.

Does anybody have any ideas for narrowing this down? I’m seriously
thinking
of doing some voodoo rites…
-Mario.


I want to change the world but they won’t give me the source code.

A few things to check, and then maybe we can help walk through things on
IRC…

  • Make sure there’s only one JRuby jar getting loaded
  • Make sure contents isn’t getting passed across JRuby instances, like
    via a session store or something

The heisenbug quality of the issue is amusing, but it could mean the
actual problem is somewhere else or it’s timing/threading/jit related.

I’d recommend trying to do a bisect again to see if it goes away, and
make sure while doing so you’re not loading multiple JRuby jars. And
for each bisection, run it a couple times.

On Thu, Oct 8, 2009 at 11:32 AM, Mario C. [email protected]
wrote:

On Tue, Oct 6, 2009 at 9:49 PM, Mario C. [email protected] wrote:
should not really cause such problem, and seems to be completely
Hi Vladimir,


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hi again,
I have yet to redo the git bisect, but here’s some things I’ve found
out:

  • With yesterday’s master, I tried running the app 10 times. Out of
    those 10
    it successfully ran 3 times with no discernible pattern (2 crashes - 1
    OK -
    4 crashes - 1 OK - 1 crash - 1 OK)

  • As per Tom’s suggestion, I turned off the JIT with
    -Djruby.compile.mode=OFF (I’m using RedBridge so my main method is
    Scala).
    The results (again 10 runs) were: crash - OK - crash - OK - OK - crash -
    crash - OK crash - crash

After this I noticed I had jruby-engine-1.1.6.jar in my CLASPATH (right
after jruby-complete-1.5.0dev.jar) so I removed it. The results for 10
runs
were as follows:

  • JIT on: 10 crashes
  • JIT off : 10 crashes
  • JIT FORCE: 10 crashes

So now it seems I can faithfully reproduce the crash (or at least it
happened 30 times in a row - never assume).

I’m using a single JRuby instance in my program (it’s a stand-alone GUI
app). I keep the engine in an (immutable) val stored in a Scala
singleton
object, so no sharing of state between instances.

Next up: git bisect again to get to the failing commit.

It just hit me that I failed to list my environment, in case there’s
something in it that might help.

I’m running on a MacBook Pro (2.5 GHz Core 2 Duo) with OS X 10.6 and 4
GB
RAM

% java -version
java version “1.6.0_15”
Java™ SE Runtime Environment (build 1.6.0_15-b03-219)
Java HotSpot™ 64-Bit Server VM (build 14.1-b02-90, mixed mode)

Java command line:

java -Dswing.defaultlaf=com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel
-Djruby.compile.mode=OFF -d32 -cp
:bin/…/src/main/ruby:bin/…/target/classes:/Users/mario/.m2/repository/org/scala-lang/scala-library/2.7.5/scala-library-2.7.5.jar:/Users/mario/.m2/repository/org/scala-lang/scala-swing/2.7.5/scala-swing-2.7.5.jar:/Users/mario/.m2/repository/net/sourceforge/pagelayout/pagelayout/1.16/pagelayout-1.16.jar:/Users/mario/.m2/repository/net/java/dev/swing-layout/swing-layout/1.0.2/swing-layout-1.0.2.jar:/Users/mario/.m2/repository/cc/abstra/scuby/scuby/0.1-SNAPSHOT/scuby-0.1-SNAPSHOT.jar:/Users/mario/.m2/repository/org/jruby/jruby-complete/1.5.0dev/jruby-complete-1.5.0dev.jar:/Users/mario/.m2/repository/com/sun/script/jruby/jruby-engine/1.1.6/jruby-engine-1.1.6.jar:/Users/mario/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/Users/mario/.m2/repository/org/swinglabs/swingx/0.9.7/swingx-0.9.7.jar:/Users/mario/.m2/repository/jivesoftware/smack/3.1.0/smack-3.1.0.jar:/Users/mario/.m2/repository/jivesoftware/smackx/3.1.0/smackx-3.1.0.jar:/Users/mario/.m2/repository/org/jivesoftware/smackx/pubsub/1.0-SNAPSHOT/pubsub-1.0-SNAPSHOT.jar:/Users/mario/.m2/repository/net/liftweb/lift-json/1.1-M5/lift-json-1.1-M5.jar
cc.abstra.bluemountain.client.Main

To make it a bit clearer here’s the script that sets my classpath (for
the
2nd run of tests I removed jruby-engine-1.1.6.jar):

PRJ_HOME=dirname $0/…
MVN_REPO=${HOME}/.m2/repository
export PRJ_HOME MVN_REPO

echo ${PRJ_HOME}/src/main/ruby
echo ${PRJ_HOME}/target/classes
echo
${MVN_REPO}/org/scala-lang/scala-library/2.7.5/scala-library-2.7.5.jar
echo ${MVN_REPO}/org/scala-lang/scala-swing/2.7.5/scala-swing-2.7.5.jar
echo
${MVN_REPO}/net/sourceforge/pagelayout/pagelayout/1.16/pagelayout-1.16.jar
echo
${MVN_REPO}/net/java/dev/swing-layout/swing-layout/1.0.2/swing-layout-1.0.2.jar
echo
${MVN_REPO}/cc/abstra/scuby/scuby/0.1-SNAPSHOT/scuby-0.1-SNAPSHOT.jar
echo
${MVN_REPO}/org/jruby/jruby-complete/1.5.0dev/jruby-complete-1.5.0dev.jar
echo
${MVN_REPO}/com/sun/script/jruby/jruby-engine/1.1.6/jruby-engine-1.1.6.jar
echo
${MVN_REPO}/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
echo ${MVN_REPO}/org/swinglabs/swingx/0.9.7/swingx-0.9.7.jar
echo ${MVN_REPO}/jivesoftware/smack/3.1.0/smack-3.1.0.jar
echo ${MVN_REPO}/jivesoftware/smackx/3.1.0/smackx-3.1.0.jar
echo
${MVN_REPO}/org/jivesoftware/smackx/pubsub/1.0-SNAPSHOT/pubsub-1.0-SNAPSHOT.jar
echo ${MVN_REPO}/net/liftweb/lift-json/1.1-M5/lift-json-1.1-M5.jar%

-Mario.


I want to change the world but they won’t give me the source code.

You can also run with the JIT off as an additional exercise (-X-C) on
command-line (jruby --properties for java prop to do the same thing).

-Tom

On Thu, Oct 8, 2009 at 3:26 PM, Charles Oliver N.
[email protected] wrote:

make sure while doing so you’re not loading multiple JRuby jars. And

Does anybody have any ideas for narrowing this down? I’m seriously thinking

using git bisect).
Thanks,


blog: http://blog.enebo.com twitter: tom_enebo
mail: [email protected]


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Sat, Oct 10, 2009 at 6:23 AM, Mario C. [email protected]
wrote:

at http://kenai.com/projects/jruby-embed/pages/Home#Context_Instance_Type
This should probably go into the release notes as well…

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Since I don’t think there is a big installed base of JRuby Embed users
yet,
this probably deserves a little scrutiny.

In experimenting with JRuby Embed, I’m not sure the ThreadLocal scope is
the
most intuitive default. I haven’t posted an alternative yet because I’m
not
sure if there is an intuitive default. I personally have cases where
I
want either the Singleton or SingleThread behavior, and JRuby Embed is
cool
because it now allows me to choose which of these I want without having
to
construct that behavior myself around the Ruby runtime. I don’t have
any
cases at all where the ThreadLocal behavior works for me, but I think
that
may be endemic to my (embedded, Web based) user stories and not the
universe
at large.

That said, so far, I absolutely can’t pick between Singleton or
SingleThread
as to which I think would be a better natural default. SingleThread
makes
sense as a default because it is naive (runtime contention is the
developer’s problem), but I suspect it also is the most challenging for
a
developer to handle correctly. This anecdote makes me think that
Singleton
might be the easiest natural behavior for most developers and most
cases.

Yesterday on IRC Charles was kind enough to walk me through some
debugging
to clear this up.

Basically the problem was that I had inadvertently created 2 instances
of
the JRuby engine and I was sharing data between them, so the NilClass in
one
of them was different from the NilClass in the other. I was getting back
an
object from a call and sending it as a parameter in another.

This happened when I changed from using the old jruby-engine to the new
jruby-embed API. The reason there were 2 engines was that, in our Swing
app,
I was making calls to JRuby both in the main Thread and in the Event
Dispatch Thread. It turns out that, by default, the actual JRuby engine
is
stored in a ThreadLocal variable (and this happens transparently). I
stored
my reference to the ScriptEngine in a val in a Scala singleton object so
I
assumed there was a single Engine.

The way around it was to use
-Dorg.jruby.embed.localcontext.scope=singleton
in the command line to turn the JRuby engine into a singleton. The docs
for
that are at
http://kenai.com/projects/jruby-embed/pages/Home#Context_Instance_Type

Oodles of thanks to Charles for his invaluable help.
-Mario.

On Sat, Oct 10, 2009 at 9:31 PM, Rob H.
[email protected] wrote:

That said, so far, I absolutely can’t pick between Singleton or SingleThread
as to which I think would be a better natural default. SingleThread makes
sense as a default because it is naive (runtime contention is the
developer’s problem), but I suspect it also is the most challenging for a
developer to handle correctly. This anecdote makes me think that Singleton
might be the easiest natural behavior for most developers and most cases.

I might lean toward singleton being the default, since we’ve long
talked about making JRuby one-runtime-per-classloader, which would
simplify many things. As it stands right now nothing else
runtime-related goes in thread-locals (other than thread-local data),
so I agree it could be a little unexpected. And of course Mario’s case
shows what can happen when you inadvertently create two runtimes and
start passing things from one to another…

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Sun, Oct 11, 2009 at 06:41, Charles Oliver N.
[email protected]wrote:

I might lean toward singleton being the default, since we’ve long
talked about making JRuby one-runtime-per-classloader, which would
simplify many things. As it stands right now nothing else
runtime-related goes in thread-locals (other than thread-local data),
so I agree it could be a little unexpected. And of course Mario’s case
shows what can happen when you inadvertently create two runtimes and
start passing things from one to another…

  • Charlie

“Make easy things easy, difficult things possible”. I agree that the
simplest/most intuitive case would probably be the Singleton (but of
course,
my intuition may have nothing to do with anybody else’s). OTOH, looking
at
the Collections API and StringBuilder there IS a precedent for making
threading be the developer’s problem by default. However in this case I
would choose the Singleton to be the default.

-Mario.

On Sun, Oct 11, 2009 at 8:48 AM, Mario C. [email protected]
wrote:

  • Charlie

“Make easy things easy, difficult things possible”. I agree that the
simplest/most intuitive case would probably be the Singleton (but of course,
my intuition may have nothing to do with anybody else’s). OTOH, looking at
the Collections API and StringBuilder there IS a precedent for making
threading be the developer’s problem by default. However in this case I
would choose the Singleton to be the default.
-Mario.

Once I wondered about what type should be a default because I wasn’t
sure in what kind of applications people would use embedding API.
Eventually, I chose a thread local type hoping web applications would
be major ones for Red Bridge. If people want to have the singleton to
be default, I don’t mind to change it. So, I’ll make new thread on
jruby-ml about this topic to see what is the best choice.

-Yoko


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email