Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress .java sources from exceptions on JRuby #213

Closed
headius opened this issue Jul 23, 2013 · 4 comments
Closed

Suppress .java sources from exceptions on JRuby #213

headius opened this issue Jul 23, 2013 · 4 comments

Comments

@headius
Copy link

headius commented Jul 23, 2013

On JRuby, exception traces can often have .java sources in them. We provide this as a service to help JRuby users know when the error passes through "native" code. These files are presented using JRuby's own package structure as their path, and I believe this confuses the Rake output.

However, on Rake these lines show whenever there's a failing build, since the logic for suppressing uninteresting exception lines does not filter out sources from our Java package.

An example:

For a simple error-causing task:

@@ -38,3 +45,7 @@ task :gen do
   system 'javac -cp lib/jruby.jar build/src_gen/*.java'
   system 'jar -uf lib/jruby.jar -C build/src_gen .'
 end
+
+task :error do
+  fail
+end

The following output on JRuby:

system ~/projects/jruby $ rake error
rake aborted!

org/jruby/RubyProc.java:268:in `call'
org/jruby/RubyArray.java:1614:in `each'
org/jruby/RubyArray.java:1614:in `each'
org/jruby/RubyKernel.java:1101:in `load'
Tasks: TOP => error
(See full trace by running task with --trace)

The org/jruby/ lines from the backtrace are not filtered out, and are displayed even without --trace.

The logic is from application.rb:

    # Display the error message that caused the exception.
    def display_error_message(ex)
      trace "#{name} aborted!"
      trace ex.message
      if options.backtrace
        trace ex.backtrace.join("\n")
      else
        trace Backtrace.collapse(ex.backtrace).join("\n")
      end
      trace "Tasks: #{ex.chain}" if has_chain?(ex)
      trace "(See full trace by running task with --trace)" unless
        options.backtrace
    end

Which calls backtrace.rb:

module Rake
  module Backtrace
...
    def self.collapse(backtrace)
      pattern = Rake.application.options.suppress_backtrace_pattern ||
                SUPPRESS_PATTERN
      backtrace.reject { |elem| elem =~ pattern }
    end
  end
end

Which uses the following pattern on my system (SUPPRESS_PATTERN):

/(\A(\/Users\/headius\/projects\/jruby|\/Users\/headius\/projects\/jruby\/lib|\/Users\/headius\/projects\/jruby\/lib\/ruby|\/Users\/headius\/projects\/jruby\/lib\/ruby\/1\.9|\/Users\/headius\/projects\/jruby\/lib\/ruby\/shared|\/Users\/headius\/projects\/jruby\/lib\/ruby\/1\.9\/site_ruby|\/Users\/headius\/projects\/jruby\/lib\/ruby\/gems\/shared\/gems\/rake\-10\.1\.0\/lib)|bin\/rake:\d+)/i

Obviously this logic is intending to filter out system files from the backtrace, but it only considers Ruby's core load paths.

On JRuby, we have fixed this in our own Rakefile by adding these lines:

# Suppress .java lines from non-traced backtrace
begin
  Rake.application.options.suppress_backtrace_pattern =
    /(#{Rake::Backtrace::SUPPRESS_PATTERN})|(^org\/jruby)/
rescue
end

But this is not foolproof since there may be code in other packages that shows up in our backtrace (and our users would have to also add it to their Rakefiles).

I'm not sure what the best fix would be. Rake versions used to use #caller's backtrace for this output, which JRuby scrubs of all .java lines (for compatibility). We could potentially provide a utility that can turn an Exception backtrace into a caller backtrace, but it would not be standard. Alternatively, we could filter out all .java lines, but that would filter out user code that calls through Java (which I believe this new pattern was designed to allow through).

Thoughts?

@drbrain
Copy link
Collaborator

drbrain commented Mar 10, 2014

Does backtrace_locations help implement this?

@drbrain drbrain added this to the Future milestone Mar 10, 2014
@drbrain
Copy link
Collaborator

drbrain commented Apr 1, 2014

Looks like backtrace_locations is too new.

@headius how about this patch, does org/jruby/ have anything that doesn't match \w+\.java?

diff --git a/lib/rake/backtrace.rb b/lib/rake/backtrace.rb
index 63d2532..439255d 100644
--- a/lib/rake/backtrace.rb
+++ b/lib/rake/backtrace.rb
@@ -9,6 +9,9 @@ module Rake
       map { |f| File.expand_path(f) }.
       reject { |s| s.nil? || s =~ /^ *$/ }
     SUPPRESSED_PATHS_RE = SUPPRESSED_PATHS.map { |f| Regexp.quote(f) }.join("|")
+    SUPPRESSED_PATHS_RE << "|^org\\/jruby\\/\\w+\\.java" if
+      Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby'
+
     SUPPRESS_PATTERN = %r!(\A(#{SUPPRESSED_PATHS_RE})|bin/rake:\d+)!i

     def self.collapse(backtrace)

@drbrain
Copy link
Collaborator

drbrain commented Apr 1, 2014

With the above patch I get this output:

$ ~/.rubies/jruby-1.7.11/bin/jruby -Ilib bin/rake -f jruby.rake error
rake aborted!

/Users/drbrain/Work/git/rake/jruby.rake:2:in `(root)'
Tasks: TOP => error
(See full trace by running task with --trace)

@drbrain
Copy link
Collaborator

drbrain commented Apr 1, 2014

And with --trace:

$ ~/.rubies/jruby-1.7.11/bin/jruby -Ilib bin/rake -f jruby.rake error --trace
** Invoke error (first_time)
** Execute error
rake aborted!

/Users/drbrain/Work/git/rake/jruby.rake:2:in `(root)'
org/jruby/RubyProc.java:271:in `call'
/Users/drbrain/Work/git/rake/lib/rake/task.rb:240:in `execute'
org/jruby/RubyArray.java:1613:in `each'
/Users/drbrain/Work/git/rake/lib/rake/task.rb:235:in `execute'
/Users/drbrain/Work/git/rake/lib/rake/task.rb:179:in `invoke_with_call_chain'
/Users/drbrain/.rubies/jruby-1.7.11/lib/ruby/1.9/monitor.rb:211:in `mon_synchronize'
/Users/drbrain/Work/git/rake/lib/rake/task.rb:172:in `invoke_with_call_chain'
/Users/drbrain/Work/git/rake/lib/rake/task.rb:165:in `invoke'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:150:in `invoke_task'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:106:in `top_level'
org/jruby/RubyArray.java:1613:in `each'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:106:in `top_level'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:115:in `run_with_threads'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:100:in `top_level'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:78:in `run'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:176:in `standard_exception_handling'
/Users/drbrain/Work/git/rake/lib/rake/application.rb:75:in `run'
bin/rake:33:in `(root)'
Tasks: TOP => error

@drbrain drbrain modified the milestones: 10.3, Future Apr 1, 2014
@drbrain drbrain closed this as completed in bb75fec Apr 1, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants