ruby-concurrency / concurrent-ruby

Modern concurrency tools including agents, futures, promises, thread pools, supervisors, and more. Inspired by Erlang, Clojure, Scala, Go, Java, JavaScript, and classic concurrency patterns.
https://ruby-concurrency.github.io/concurrent-ruby/
Other
5.7k stars 419 forks source link

Allow to install concurrent-ruby from master on JRuby #747

Closed pitr-ch closed 1 year ago

pitr-ch commented 6 years ago

When the concurrent-ruby is installed from master on JRuby it will not work because the java extensions are not compiled. Possible solutions:

  1. write extconf.rb which is able to compile java extension when missing.
prashantvithani commented 6 years ago

@pitr-ch Can you give more details about how to write extconf.rb to compile java extensions for concurrent-ruby? I've been trying to get this work with JRuby-9.2 on Java-10. But the error says Java extensions are required for JRuby

Stacktrace

LoadError:
  Java extensions are required for JRuby.
  no such file to load -- concurrent/concurrent_ruby
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/bundler/gems/concurrent-ruby-04101eec0bd7/lib/concurrent/utility/native_extension_loader.rb:35:in `load_native_extensions'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/bundler/gems/concurrent-ruby-04101eec0bd7/lib/concurrent/synchronization.rb:5:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/bundler/gems/concurrent-ruby-04101eec0bd7/lib/concurrent/map.rb:1:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/bundler/gems/concurrent-ruby-04101eec0bd7/lib/concurrent/map.rb:3:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/notifications/fanout.rb:1:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/notifications/fanout.rb:4:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:1:in `<class:(root)>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/notifications.rb:4:in `<module:(root)>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation/behaviors.rb:1:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation/behaviors.rb:3:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation.rb:1:in `<main>'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation.rb:18:in `Deprecation'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation.rb:8:in `block in ActiveSupport'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/activesupport-5.2.1/lib/active_support/deprecation.rb:5:in `(root)'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/factory_bot-4.10.0/lib/factory_bot.rb:1:in `block in (root)'
# /Users/prvithani/.rvm/gems/jruby-9.2.0.0/gems/factory_bot-4.10.0/lib/factory_bot.rb:3:in `(root)'
# ./spec/spec_helper.rb:1:in `(root)'
# ./spec/spec_helper.rb:3:in `(root)'
# ------------------
# --- Caused by: ---
# LoadError:
#   no such file to load -- concurrent/concurrent_ruby
#   /Users/prvithani/.rvm/gems/jruby-9.2.0.0/bundler/gems/concurrent-ruby-04101eec0bd7/lib/concurrent/utility/native_extension_loader.rb:35:in `load_native_extensions'
pitr-ch commented 6 years ago

Hi @prashantvithani, I wonder that myself. I was trying to find some guide for it but so far I did not. Currently we use Rake::JavaExtensionTask but we should really have an extconf.rb in the ext/concurrent-ruby dir which would create a Makefile compiling the Java extension. Would you be interested to look into it? It should also be verified that bundler tries to build extensions when installing gem from repo.

prashantvithani commented 6 years ago

@pitr-ch I surely will look into this to make bundler build the extensions. I also faced the issue while building gem locally with Rake::JavaExtensionTask as it uses the default source and target values 1.5.

error: Source option 5 is no longer supported. Use 6 or later.
error: Target option 1.5 is no longer supported. Use 1.6 or later.

I had to specify the version in Rakefile.

I will see if I can replace it with extconf.rb.

pitr-ch commented 6 years ago

Thanks! I think target 1.5 is no longer possible in java newer then 8. Please accept the collaboration invitation and I'll assign the issue to you.

prashantvithani commented 6 years ago

Thanks for the invitation! I have accepted it, you can now assign this to me :)

prashantvithani commented 4 years ago

@pitr-ch I was wondering if the jar file can be checked in as mentioned in this comment by @headius : https://github.com/jruby/jruby/issues/5292#issuecomment-428238827. I've seen that pattern in other gems with java extensions as well.

pitr-ch commented 4 years ago

That is a good and simple idea that would work. Unfortunately, it requires committing a binary blob into git which I'd like to avoid. I think the later comment https://github.com/jruby/jruby/issues/5292#issuecomment-594365949 sounds better. I appreciate you've looked into it. Please do not be discouraged by my late response for lack of time on my part.

eregon commented 1 year ago

Agreed we're definitely not committing a .jar in git as a workaround. It sounds like JRuby needs to make it easier to do this, and yes that means the user needs javac at least and a JDK not JRE but that's the only way. Closing as not planned, we can reopen if there is a PR or interest.

headius commented 1 year ago

It sounds like JRuby needs to make it easier to do this

There's nothing preventing this in JRuby, and there's nothing we could do to make it "easier".

A JRuby extension library can choose to support github-sourced gems by putting the extension build logic into the gemspec, but it must be able to do this in such a way that released gems still use a prebuilt jar file. This is entirely up to libraries, and no changes are needed to JRuby to make it work.

We do not encourage anyone to ship gems with uncompiled .java sources. JRuby users should be able to run on JVM installations that do not include command-line compilation tools.

The work to support is entirely on the library side.

eregon commented 1 year ago

Is there some documentation about how to setup a JRuby extension for a gem? Like how to use Rake::JavaExtensionTask and how to make the gem installable on JRuby from master. I know very little about that stuff.

My requirement for concurrent-ruby is this logic for installing from master needs to fit in less than 10 lines of code (for CRuby & TruffleRuby there is no extra line of code to support installing the gem from master AFAIK). If it's more than about 10 lines it likely becomes something annoying to maintain and hardcodes logic which doesn't belong there. Ideally it'd work in a single or a few lines, similar to https://github.com/ruby-concurrency/concurrent-ruby/blob/2ebf9de5eed2b040c39580d66dce37ea1e93747c/concurrent-ruby-ext.gemspec#L22 So it'd be able to reuse stuff like the JavaExtensionTask https://github.com/ruby-concurrency/concurrent-ruby/blob/2ebf9de5eed2b040c39580d66dce37ea1e93747c/Rakefile#L13-L16 Maybe an extconf.rb that just shells out to bundle exec rake compile would work?

Also I have asked for examples in https://github.com/jruby/jruby/issues/5292#issuecomment-1361319494 but I haven't seen anything reusable and simple.

Anyway, this doesn't seem high priority. I don't plan to spend time on it, but if someone else cares and want to make a PR I'll review it.

headius commented 1 year ago

I do not know enough about the :github mechanism in Bundler to provide an example.

The Java extension task should be sufficient to build-on-demand, if it can be triggered at install time. I do not know what is required to make Bundler run the Rakefile when installing from a git repository.