Why does jruby-openssl gem have strange folder structure? - ruby

From my understanding, a gem's folder structer is supposed to have a folder called lib and inside that folder have a <gem-name>.rb file. However, when I used jruby 1.6.8 and do bundle install to install jruby-openssl, I open up C:\jruby-1.6.8\lib\ruby\gems\1.8\gems\jruby-openssl-0.8.2 and instead of seeing an rb file, I see more sub folders that look like this:
jruby-openssl-0.8.2\
+---lib\
| +---1.8\
| | +---openssl\
| | +---openssl.rb
| +---1.9\
| | +---openssl\
| | +---openssl.rb
| +---ruby\
| | +---shared\
| +---shared\
| +---jopenssl\
| +---openssl\
| +---openssl.rb
+---test\
+---java\
Is there a reason that jruby-openssl isn't following the standard gem folder structure? Specifically, I seem to be having trouble with a gem 'jruby-openssl' command working. Should the gem command find and load the gem correctly if the jruby-openssl folder is in the LOAD_PATH?
ERROR DETAILS:
Here is the error that appears in C:\apachetomcat632\logs\MyWebapp.log
--- Backtrace
LoadError: OpenSSL::Cipher requires the jruby-openssl gem
(root) at file:/C:/apachetomcat632/shared/lib/jruby-complete.jar!/META-INF/jruby.home/lib/ruby/site_ruby/shared/jruby/openssl/autoloads/cipher.rb:8
MessageEncryptor at file:/C:/apachetomcat632/shared/lib/jruby-complete.jar!/META-INF/jruby.home/lib/ruby/site_ruby/shared/jruby/openssl/autoloads/cipher.rb:24
ActiveSupport at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/message_encryptor.rb:12
(root) at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/message_encryptor.rb:4
require at org/jruby/RubyKernel.java:1062
require at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:251
load_dependency at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:236
require at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/dependencies.rb:251
eager_autoload! at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/message_encryptor.rb:43
each at org/jruby/RubyArray.java:1620
eager_autoload! at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/activesupport-3.2.11/lib/active_support/dependencies/autoload.rb:43
Bootstrap at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/application/bootstrap.rb:20
instance_exec at org/jruby/RubyKernel.java:2091
run at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/initializable.rb:30
run_initializers at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/initializable.rb:55
each at org/jruby/RubyArray.java:1620
run_initializers at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/initializable.rb:54
initialize! at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/application.rb:136
send at org/jruby/RubyKernel.java:2105
method_missing at file:C:/apachetomcat632/shared/lib/cfe-gems.jar!/gems/railties-3.2.11/lib/rails/railtie/configurable.rb:30
(root) at C:/apachetomcat632/webapps/Bank62P/WEB-INF/rails/config/environment.rb:5
require at org/jruby/RubyKernel.java:1062
load_environment at C:/apachetomcat632/webapps/Bank62P/WEB-INF/rails/config/environment.rb:23
load_environment at file:/C:/apachetomcat632/shared/lib/jruby-rack.jar!/jruby/rack/rails_booter.rb:65
(root) at <script>:1
And here is entire cipher.rb file:
require 'rubygems'
# try to activate jruby-openssl gem for OpenSSL::SSL, raising error if gem not present
begin
gem 'jruby-openssl'
require 'openssl.rb'
rescue Gem::LoadError => e
raise LoadError.new("OpenSSL::Cipher requires the jruby-openssl gem")
end

To add to tadman's answer, if you look in the gemspec (gems/1.8/specifications/jruby-openssl-0.8.2.gemspec), you'll see this line:
s.require_paths = ["lib/shared"]
When you require 'openssl' in your code, it'll load the one in the shared dir. I believe that file will determine whether to load the 1.8 or 1.9 version.
With that said...
When I try to require 'openssl' with 0.8.2, I get an error:
LoadError: no such file to load -- openssl/dummy
When I use the latest (0.8.8) it works fine. Try upgrading.

Prior to version 1.7.0 of JRuby, 1.9 support was so incomplete that you'd be better off using 1.8 code. This is probably why there needs to be two separate implementations of that particular library.
Bundling them together like this is a little unusual, often 1.8 installations will just lock to an older version of the gem. JRuby presents a challenge here, and this looks like a fairly reasonable solution.

Related

Load unbuilt gem into irb from that gem's dir

I'm developing a gem, and I need to load that gem's code into irb for testing purposes without building/publishing the gem and then installing it onto my system the traditional way via gem install <gem's name>.
To illustrate:
$ pwd
Users/me/development/gem_name/
$ irb
2.2.2 :001 > require 'gem_name'
=> true
The problem is that irb isn't loading the gem's code from my working dir because I added a method to the gem in the working dir and it's not available in the version of the gem that irb loaded above.
How can I load the version of the gem that is in the dir that I'm currently working in (i.e. the gem's dir)?
You could use require_relative to manually load the source code of your gem, for example require_relative './lib/gem_name/gem_name' assuming you have a file located at ./lib/gem_name/gem_name.rb that loads your gem. This guarantees that it is the version you have in your source code.

Mysterious LoadError on installed gem with bundler

The following terminal session explains the problem. I don't understand how it's possible that I'm getting a load error on an installed gem.
The sailthru gem which isn't loading is something I installed today, which may be relevant. I verified it was installed to the same location as my other gems, and I also tried restarting the Terminal app. I'm using rbenv on a mac. However, I have not installed a new version of ruby for at least a few weeks, and have been using it daily until now without any issues.
Thanks for any help.
$ gem list | grep sailthru
sailthru (1.1.2)
sailthru-client (4.0.1, 2.0.0)
$ cat Gemfile | grep sailthru
gem 'sailthru'
$ cat Gemfile.lock | grep sailthru
sailthru (1.1.2)
sailthru
$ bundle exec thin start
Using rack adapter
/Users/jg/Dropbox/sinatra/app.rb:5:in `require': cannot load such file -- sailthru (LoadError)
$ irb
irb(main):001:0> require 'sailthru'
=> true
irb(main):002:0>
There is no sailthru file to require.
You should take a look at the project page.
require 'sailthru'
should be
require 'sailthru/client'
Hope this helps.
EDIT
Just noticed the last part where you gave irb output.
The sailthru.rb file is part of the sailthru-client gem. It is working through irb because irb is not loaded via bundle exec. This means that every gem installed is available in irb.
To fix this (if you need that sailthru-client gem in your app. Add gem 'sailthru-client' to your gem file. Do a bundle install, then run your bundle exec again.
You should not see that error after that. Keep in mind. bundle exec only uses gem libraries that are specified in your Gemfile.

Use ruby gem from git repo via Bundler

I have created a custom gem using bundler and checked it in a git repo.
custom_gem.rb
require "custom_gem/version"
require "custom_gem/custom_class"
module CustomGem
# Your code goes here...
end
custom_class.rb
require 'typhoeus'
module CustomGem
class CustomClass
def self.custom_method
#do stuff with typhoeus
end
end
end
Added it as a dependency to another project and installed it via bundler.
gem 'custom_gem', :git => 'git#bitbucket.org:dir/repo.git'
After that I try to use it by calling
CustomGem::CustomClass.custom_method
and I get the following error:
uninitialized constant CustomGem::CustomClass
Any suggestions?
Might be a small thing but just starting out with ruby so any advice would be great.
Two things to check :
What happens when you run Bundle install (is the gem listed as installed ?)
Did you require the gem properly (require 'custom_gem') ? Rails does a little magic there, but I'm not sure if you are in a rails application.
The file custom_gem.rb should be in lib/custom_gem.rb, and the file custom_class.rb should be in lib/custom_gem/custom_class.rb
lib/custom_gem/custom_class.rb
\_/ \________________________/
| |
| \_ comes from your code: `require "custom_gem/custom_class"`
|
|
\_ comes from custom_gem.gempsec (the line `s.require_paths = ["lib"]`)
For more about the load path, file hierarchy and naming, check out this gem guide.

How to install, require, and use a gem in ruby

I'm trying to use rake in my ruby script...(Ruby 1.8.6, JRuby 1.6.5)
Downloaded rake using gem install --remote rake, looks ok on install...
Fetching: rake-0.9.2.2.gem (100%)
Successfully installed rake-0.9.2.2
1 gem installed
I've got a simple ruby script which works fine, but when I import rake to using any of the following requires, it starts complaining....
require 'rake'
LoadError: no such file to load -- rake
or
require '/lib/rake'
LoadError: no such file to load -- lib/rake
After some searching, I found that adding require 'rubygems' just before rakefixes the issue....
require 'rubygems'
require 'rake'
Even though it's working, I've got some questions...
The gem spec on rake shows the require_path as lib, so why
doesn't require '/lib/rake' work? Am I misunderstanding the significance of require_path?
Why is it necessary to place require 'rubygems' before require
'rake'
Yes, you are misunderstanding the significance. The require_paths in the specification is an array of subdirectories of that gem's installation directory that should be searched for files belonging to the gem.
To find out where rake really is, try this:
$ gem which rake
You'll see that it is actually installed somewhere completely unrelated to /lib; on my system, it's under /var/lib/gems. Ruby gems, in general, live in their own directory structure; the only file in the standard Ruby include path ($:) is rubygems itself, which you used to have to explicitly require in order to make any actual gems visible. (Since Ruby 1.9, that has not been necessary.)
Gems are more complex than just libraries to load; you can have multiple versions of the same gem installed, and specify which one you want at a time, and do other things that wouldn't work if the gems were just dumped into the standard Ruby include path.
The require_path in the gemspec tells ruby where the files of this gem are located within the gem. It makes you able to type require 'rake', and ruby then knows it needs to look for /lib/rake within the gem installation folder.
In Ruby 1.8, rubygems (the mechanism responsible for making gems available to your app) is not loaded by default, and the default ruby isn't aware of any gem on your system. You need to load rubygems before being able to require any other gem. This is not the case anymore with Ruby 1.9.

no such file to load - require wordnet fails - troubleshoot gem installation

my ruby environment cant see an installed gem, at least the require fails
It's about the gem wordnet http://deveiate.org/projects/Ruby-WordNet I start an example script ( as user of course )
./meronymTree.rb
./meronymTree.rb:8:in `require': no such file to load -- wordnet (LoadError)
from ./meronymTree.rb:8
In some example scripts it'S called "WordNet" and in some it's lowercase, the error is same.
here's the scripts first lines
#!/usr/bin/ruby -w
$LOAD_PATH.unshift "lib"
require 'wordnet'
Check if gem is installed, as user root
gem list |grep word
wordnet (0.0.5)
root#auedv18:/var/lib/gems/1.8/gems/wordnet-0.0.5# ls
ChangeLog convertdb.rb examples lib LICENSE rake Rakefile Rakefile.local README spec utils.rb
Other gems are fine.
I am on current ubuntu and got ruby1.8 and rubygems-1.8.6 on it, (if that makes a difference).
hm and i downloaded the wordnet-0.0.5.gem file from above site and did
gem install wordnet-0.0.5.gem
Try this:
require 'rubygems'
require 'wordnet'

Resources