backtrace reported by NativeException incorrect under certain scenarios
-----------------------------------------------------------------------

                 Key: JRUBY-3959
                 URL: http://jira.codehaus.org/browse/JRUBY-3959
             Project: JRuby
          Issue Type: Bug
         Environment: java 1.6.0_10, ubuntu 8.10, x86
            Reporter: Andrew Davey
            Assignee: Thomas E Enebo
             Fix For: JRuby 1.4
         Attachments: fix-backtrace-issues.patch, test_case.patch

NativeException backtraces have been greatly improved by JRUBY-3890. However, 
there are a few scenarios in which the backtrace reported is either incorrect 
or causes JRuby to crash (see examples section below).

I've included a test case for each of the examples as well as a patch to 
address the issues presented.

*Examples*

*Example 1*

{code:title=example_1.rb}
def example1
  x = java.lang.String.new("")
  x.charAt(12)
rescue Exception => ex
  puts ex.backtrace.join("\n")
end
example1
{code}

If you save the above to a file and then run the file, the backtrace reported 
will look like:

{noformat}
./jruby -rjava example_1.rb
  java.lang.StringIndexOutOfBoundsException: String index out of range: 12
  java/lang/String.java:687:in `charAt'
  example_1.rb:2:in `example1'
  example_1.rb:8
{noformat}

Instead it should look like the below. The above backtrace incorrectly reports 
the error occuring on line *2* of example_1.rb instead of line *3*.

{noformat}
./jruby -rjava example_1.rb
  java.lang.StringIndexOutOfBoundsException: String index out of range: 12
  java/lang/String.java:687:in `charAt'
  example_1.rb:3:in `example1'
  example_1.rb:8
{noformat}

*Example 2*

{code:title=example_2.rb}
class Example2
  def initialize
    @x = java.lang.String.new("blah")
  end

  def raise_native_exception
    @x.charAt(12)
  rescue Exception => ex
    puts ex.message
    puts ex.backtrace.join "\n"
  end
end

e = Example2.new
e.raise_native_exception
{code}

Produces the following output:

{noformat}
jruby -rjava example_2.rb
  java.lang.StringIndexOutOfBoundsException: String index out of range: 12
  java/lang/String.java:687:in `charAt'
  example_2.rb:15:in `raise_native_exception'
  example_2.rb:16
{noformat}

Instead it should look like below. The difference is the 2nd last line. The 
error occurred on line *8* not on line *15*.

{noformat}
/jruby -rjava example_2.rb
  java.lang.StringIndexOutOfBoundsException: String index out of range: 12
  java/lang/String.java:687:in `charAt'
  example_2.rb:8:in `raise_native_exception'
  example_2.rb:16
{noformat}

*Example 3*

{code:title=example_3.rb}
def example_3
  java.lang.StringBuilder.new(-1)
rescue Exception => ex
  puts ex.message
  puts ex.backtrace.join("\n")
end
example_3
{code}

Produces the following output:

{noformat}
jruby -rjava example_3.rb
  java.lang.NegativeArraySizeException: null
  java/lang/AbstractStringBuilder.java:45:in `<init>'
  java/lang/StringBuilder.java:80:in `<init>'
  sun/reflect/NativeConstructorAccessorImpl.java:-2:in `newInstance0'
  sun/reflect/NativeConstructorAccessorImpl.java:39:in `newInstance'
  sun/reflect/DelegatingConstructorAccessorImpl.java:27:in `newInstance'
  java/lang/reflect/Constructor.java:513:in `newInstance'
  org/jruby/javasupport/JavaConstructor.java:275:in `newInstanceDirect'
  
/home/teys/dev/jruby/lib/ruby/site_ruby/shared/builtin/javasupport/java.rb:51:in
 `new_proxy'
  example_3.rb:2:in `example_3'
  example_3.rb:7
{noformat}

Instead it should look like the below.

{noformat}
jruby -rjava example_3.rb
  java.lang.NegativeArraySizeException: null
  java/lang/AbstractStringBuilder.java:45:in `<init>'
  java/lang/StringBuilder.java:80:in `<init>'
  example_3.rb:2:in `new_proxy'
  example_3.rb:2:in `example_3'
  example_3.rb:7
{noformat}

Whether or not 'new_proxy' should be included in the backtrace is debatable.

*Example 4*

Finally example 4 will presently crash JRuby.

{code:title=Bar.java}
package org.jruby.test;

public class Bar
{
  public static void throwExceptionWithDeepStackTrace(int depth)
  {
    foo(depth);
  }
  
  private static void foo(int depth)
  {
    if (depth == 0) throw new RuntimeException("foo");
    foo(--depth);
  }
}
{code}

{code:title=example_4.rb}
def example_4
  Java::org.jruby.test.Bar.throwExceptionWithDeepStackTrace(1025)
rescue Exception => ex
  puts ex.message
  puts ex.backtrace.join("\n")
end

example_4
{code}

To run the above example I had to copy *Bar.java* to 
*jruby/test/org/jruby/test/Bar/java* and *example_4.rb* to the *jruby* folder 
and then run the following commands:

{noformat}
ant clean compile compile-test
jar cf build/jruby-test-classes.jar -C build/classes/test .
bin/jruby -J-cp build/jruby-test-classes.jar -rjava example_4.rb
NativeException.java:121:in `trimStackTrace': 
java.lang.ArrayIndexOutOfBoundsException: 1024
        from RaiseException.java:99:in `createNativeRaiseException'
        from JavaSupport.java:199:in `createRaiseException'
        from JavaSupport.java:195:in `handleNativeException'
        from JavaCallable.java:170:in `handleInvocationTargetEx'
        from JavaMethod.java:459:in `invokeDirectWithExceptionHandling'
        from JavaMethod.java:356:in `invokeStaticDirect'
        from StaticMethodInvoker.java:48:in `call'
        from CachingCallSite.java:310:in `cacheAndCall'
        from CachingCallSite.java:149:in `call'
        from example_4.rb:2:in `method__0$RUBY$example_4'
        from example_4#example_4:-1:in `call'
        from example_4#example_4:-1:in `call'
        from CachingCallSite.java:290:in `cacheAndCall'
        from CachingCallSite.java:109:in `call'
        from example_4.rb:8:in `__file__'
        from example_4.rb:-1:in `load'
        from Ruby.java:628:in `runScript'
        from Ruby.java:550:in `runNormally'
        from Ruby.java:396:in `runFromMain'
        from Main.java:272:in `run'
        from Main.java:117:in `run'
        from Main.java:97:in `main'
{noformat}


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to