jruby/warbler

NoMethodError: undefined method `[]' for true:TrueClass while creating war file

pytong opened this issue · 8 comments

OSX: 10.13.4
Bundler 1.16.1
warbler 2.0.4
jruby 9.1.16.0
rails 4.2.10

I have no problem creating a war file as long as I don't add a proprietary gem to the Gemfile and hence an updated Gemfile.lock because bundler forces me to run bundle update. Once I add the gem, warbler starts to fail. Is it possible that the gem might be the cause of the errors below?

NoMethodError: undefined method `[]' for true:TrueClass (erb):8:in `<eval>' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/jar.rb:284:in `expand_erb' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/jar.rb:262:in `block in add_init_file' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/jar.rb:258:in `add_init_file' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/jar.rb:157:in `apply' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/task.rb:118:in `block in define_files_task' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/task.rb:94:in `block in define_main_task' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/task.rb:93:in `block in define_main_task' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/application.rb:79:in `run' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/lib/warbler/application.rb:74:in `run' /Users/ptong/.rvm/gems/jruby-9.1.16.0@tms/gems/warbler-2.0.4/bin/warble:11:in `<main>' Tasks: TOP => war:files

Content of warble.rb:

Warbler::Config.new do |config|

  config.dirs = %w(app config db lib vendor tmp)

  config.includes = FileList["Rakefile", "Gemfile", "Gemfile.lock"]

  config.excludes = FileList["tmp/**/*", "log/**/*"]

  config.java_libs = [] if ENV["CONTAINER_JRUBY"]

  config.webinf_files += FileList["webserver.xml"]

  config.webxml.jruby.rack.logging.name = 'something'
end

To debug more, I cloned warbler tag v.2.0.4 to my computer and used my local copy of warbler directly.
I then updated lib/warbler/jar.rb and updated expand_erb to

    def expand_erb(file, config)
      require 'erb'
      erb = ERB.new(File.read(file), nil, '-')
      puts "in expand_erb"
      puts "file: #{file}"
      puts "config: #{config.inspect}"
      puts "erb_binding(config): #{erb_binding(config).inspect}"
      puts "erb.result(erb_binding(config)): #{erb.result(erb_binding(config)).inspect}"
      StringIO.new(erb.result(erb_binding(config)))
    end

And this is what I see when I created the war file like this:

bundle exec /Users/ptong/src/services/warbler/bin/warble runnable executable war

Stack Trace (I didn't include the files it printed out as there are a lot of them):

erb_binding(config): #<Binding:0xf31b991>
warble aborted!
NoMethodError: undefined method `[]' for true:TrueClass
(erb):8:in `<eval>'
/Users/ptong/src/services/mobile-service/vendor/cache/warbler/lib/warbler/jar.rb:288:in `expand_erb'

line 288 of lib/warbler/jar.rb of my local copy of warbler is this line

puts "erb.result(erb_binding(config)): #{erb.result(erb_binding(config)).inspect}"
rsov commented

Is the gem you're trying to include comes from path? I don't believe warbler supports that. You'll have to host it on private git or find a differnet way to include it in your project

The gem doesn't come from path. It comes from GitLab.

The jruby version seems to make a difference. If I use jruby 9.1.16.0, warbler fails to create a war file. If I use jruby-1.7.26, I can create a war file successfully.

rsov commented

Please note that those will be two different versions of ruby and rubygems as well. 9.1.x is ruby 2.x and 1.7.26 is ruby 1.9.3

Although it does seem like the issue is coming from warbler. And in theory it should work file. How do you include in your gemfile? Have you tried printing the ENV['GEM_PATH'] and ENV['GEM_HOME']?

Digging into the log more, turned out war.erb was the file that was giving me issue.

Here is the content of war.erb

if $servlet_context.nil?
  ENV['GEM_HOME'] <%= config.override_gem_home ? '=' : '||=' %> File.expand_path(File.join('..', '..', '<%= config.gem_path %>'), __FILE__)
<% if config.override_gem_home -%>
<% # GEM_HOME/GEM_PATH are set as .war gets extracted (on java -jar ...)
   # ... thus setting `ENV['GEM_PATH'] = nil` would cause a boot failure
-%>
<% end -%>
<% if config.bundler && config.bundler[:gemfile_path] -%>
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path(File.join('..', '..', '<%= config.bundler[:gemfile_path] %>'), __FILE__)
<% end -%>
else
  ENV['GEM_HOME'] <%= config.override_gem_home ? '=' : '||=' %> $servlet_context.getRealPath('<%= config.gem_path %>')
<% if config.override_gem_home -%>
  ENV['GEM_PATH'] = nil
<% end -%>
<% if config.bundler && config.bundler[:gemfile_path] -%>
  ENV['BUNDLE_GEMFILE'] ||= $servlet_context.getRealPath('/<%= config.bundler[:gemfile_path] %>')
<% end -%>
end

My config.bundler[:gemfile_path] is probably not set because it looks like it is probably the cause of the error NoMethodError: undefined method `[]' for true:TrueClass. How can I set it properly?

rsov commented

Did some digging. The check the traits/bundler.rb file

it sets config.bundler ||= true in here:

def before_configure

And then in add_bundler_gems it should do config.bundler = {} if config.bundler == true

Put some breakpoints / prints to see what the actual variable is and why it's not being set

Turned out one of my coworkers monkey patched after_configure and hence config.bundler was not set to a hash.

puts method(:after_configure).source_location solved the mystery.

Thank you so much for your help!

kares commented

closing as invalid