Details
Description
Hpricot and other gems that include embedded Java code in jar files don't seem to work with the gems-in-jars feature.
$ java -jar jruby-complete-1.1.6.jar -S gem install -i ./hpricot hpricot --no-rdoc --no-ri
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Successfully installed hpricot-0.6.164-java
1 gem installed
[13:32:24][/tmp/hjar]
$ l
total 18224
drwxr-xr-x 6 nicksieger wheel 204 Jan 10 13:32 hpricot/
-rw-r--r-- 1 nicksieger wheel 9328431 Jan 10 13:31 jruby-complete-1.1.6.jar
[13:32:45][/tmp/hjar]
$ jar cf hpricot.jar -C hpricot .
[13:33:06][/tmp/hjar]
$ l
total 19336
drwxr-xr-x 6 nicksieger wheel 204 Jan 10 13:32 hpricot/
-rw-r--r-- 1 nicksieger wheel 568961 Jan 10 13:33 hpricot.jar
-rw-r--r-- 1 nicksieger wheel 9328431 Jan 10 13:31 jruby-complete-1.1.6.jar
[13:33:07][/tmp/hjar]
$ jar tf hpri
hpricot/ hpricot.jar
[13:33:07][/tmp/hjar]
$ jar tf hpricot.jar | more
META-INF/
META-INF/MANIFEST.MF
cache/
cache/hpricot-0.6.164-java.gem
doc/
gems/
gems/hpricot-0.6.164-java/
gems/hpricot-0.6.164-java/.require_paths
gems/hpricot-0.6.164-java/CHANGELOG
gems/hpricot-0.6.164-java/COPYING
...
specifications/
specifications/hpricot-0.6.164-java.gemspec
[13:33:16][/tmp/hjar]
$ l
total 19336
drwxr-xr-x 6 nicksieger wheel 204 Jan 10 13:32 hpricot/
-rw-r--r-- 1 nicksieger wheel 568961 Jan 10 13:33 hpricot.jar
-rw-r--r-- 1 nicksieger wheel 9328431 Jan 10 13:31 jruby-complete-1.1.6.jar
[13:33:16][/tmp/hjar]
$ java -jar jruby-complete-1.1.6.jar -rhpricot.jar -S irb
irb(main):001:0> require 'hpricot'
=> false
irb(main):002:0> h = Hpricot.parse(File.read("index.html"))
NameError: uninitialized constant Hpricot
from file:/private/tmp/hjar/jruby-complete-1.1.6.jar!/irb/ruby-token.rb:102:in `const_missing'
from (irb):3:in `irb_binding'
Maybe IRB bug!!
Attachments
Issue Links
| This issue relates to: | ||||
| JRUBY-4554 | Rails rake test much slower in 1.5.0.dev vs 1.4.0 |
|
|
|
I wanted to document some of my work in this area.
RedCloth (4.1.1) is a gem quite similar to hpricot. It was originally written by Why and when building the gem it uses ragel to produce wither Java or C. Jason Garber has taken over development:
When building redcloth under JRuby the Java classes are archived into lib/redcloth_scan.jar which is included with the JRuby version of the gem.
I chose RedCloth to work on first because it uses a somewhat simpler (and to me hackable) Rakefile for building the gem based on echoe.
I'm experimenting to see if I can get a gem that normally uses a jar to use the .class files instead. If this works I could package the gem with .class files instead of the jar and then more easily include it in with jruby-complete.jar (avoiding the jar within a jar problem).
I modified the Rake task so the classes are copied to lib/ also:
RedclothScanService implements BasicLibraryService – it's adding methods to RedCloth::TextileDoc
You can see the RedclothScanService.java code ragel generated here: http://gist.github.com/46177
When JRuby requires a jar and there is a class in that jar that implements BasicLibraryService then it's basicLoad method get's called. It looks like it's called from: LoadService.smartLoad which calls the private method: tryLoadingLibraryOrScript.
If the classes are made available in lib/ then this statement:
can be replaced by these and the gem operates and passes all it tests:
require 'jruby' $CLASSPATH << File.dirname(File.expand_path(__FILE__)) + '/' Java::RedclothScanService.new.basicLoad(JRuby.runtime)So at least for the redcloth gem which includes redcloth_scan.jar in it's lib/ dir – if you instead just put the class files in lib/ and replace: require 'redcloth_scan' with the three lines above it should work fine when embedded into a jar with the rest of JRuby.
It's not obvious to me yet how this could be adapted into a generalized solution which doesn't require changes to the gems.
- http://github.com/jgarber/redcloth/tree/master
When building redcloth under JRuby the Java classes are archived into lib/redcloth_scan.jar which is included with the JRuby version of the gem. I chose RedCloth to work on first because it uses a somewhat simpler (and to me hackable) Rakefile for building the gem based on echoe. I'm experimenting to see if I can get a gem that normally uses a jar to use the .class files instead. If this works I could package the gem with .class files instead of the jar and then more easily include it in with jruby-complete.jar (avoiding the jar within a jar problem). I modified the Rake task so the classes are copied to lib/ also:require 'jruby' $CLASSPATH << File.dirname(File.expand_path(__FILE__)) + '/' Java::RedclothScanService.new.basicLoad(JRuby.runtime)