Search code examples
ruby-on-railsmultithreadingsidekiqrjb

How to use Ruby Java Bridge with threads (Sidekiq)


I wrote a small Java class to read embedded images from an xls file and would need to use it in a background process (using Sidekiq) of my Ruby on Rails application. But it looks like there is some issues with threading as the JVM throws an error guarantee(get_thread() == thread) failed: must be the same thread, quickly when the sidekiq process starts executing the method where the Rjb is used.

This is how I set it up.

I wrote an initializer to set up the the rjb

require 'rjb'

JARS = Dir.glob("#{Rails.root}/lib/java_libs/*.jar").join(':')
Rjb::load(JARS)
EXCEL_IMAGE_READER = Rjb::import('tools.ImageReader')

Then I use it in my background process

  def get_excel_images
    p 'Starting to get the images'
    images = []
    image_reader = EXCEL_IMAGE_READER.new(@excel_path)
    image_reader.get_file_names.each do |file_name|
      images << Attachment.new_from_bytes(image_reader.get_file(file_name), file_name)
    end
    images
  end

But as soon as the method is started to execute the JVM throws an exception. Here is the log from Sidekiq.

2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: Running in ruby 2.1.1p76 (2014-02-24 revision 45161) [i686-linux]
2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: See LICENSE and the LGPL-3.0 for licensing details.
2014-10-30T09:47:02Z 11748 TID-17e7qk INFO: Starting processing, hit Ctrl-C to stop
2014-10-30T09:47:31Z 11748 TID-19393k Sidekiq::Extensions::DelayedClass JID-08eac9ed686f8d6146cda67f INFO: start
"Starting to get the images"
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (threadLocalStorage.cpp:60), pid=11748, tid=2960567104
#  guarantee(get_thread() == thread) failed: must be the same thread, quickly
#
# JRE version: OpenJDK Runtime Environment (7.0_65-b32) (build 1.7.0_65-b32)
# Java VM: OpenJDK Client VM (24.65-b04 mixed mode, sharing linux-x86 )
# Derivative: IcedTea 2.5.3
# Distribution: Ubuntu 12.04 LTS, package 7u71-2.5.3-0ubuntu0.12.04.1
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/mika/projects/my_project/hs_err_pid11748.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   http://icedtea.classpath.org/bugzilla
#
Aborted (core dumped)

I tried to move the stuff from the initializer into the get_excel_images method but it didn't have any effect. The code works if I run it directly from console or through an rspec test.

Does anyone have any ideas how to solve this?


Solution

  • I found some information from Rjb Github issues https://github.com/arton/rjb/issues/24. It looks like downgrading to ruby 1.9.3 and rjb 1.4.9 might solve the issue, but it is not a good solution since ruby 1.9.3 is going to receive security patches only for a couple of months more. The issue being the how threads are created and how it has changed from ruby 1.9.3 to ruby 2.

    After trying many different solutions I moved to JRuby. Now java interactions work easily.

    UPDATE:

    After suffering a year for the slowness of JRuby I moved all my Java stuff into an independent daemon process and communicate with the daemon through a TCP Socket using JSON to transmit the data. Now I'm back in MRI Ruby and the development feels enjoyable again.