Bundling gems in jars for jruby-complete

I’m using jruby-complete (1.7.2) to deploy an app to a client.

It runs fine on my development machine via

java -jar jruby-complete-1.7.2.jar my_script.rb

The problem is, I have jruby installed and all required gems.

When running on a vanilla box with nothing more than a JVM
(1.6.0_37-b06),

It complains with:

LoadError: load error: openssl – java.lang.NoClassDefFoundError:
org/bouncycastle/asn1/DERBoolean
require at org/jruby/RubyKernel.java:1027
require at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/my_script/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36
(root) at my_script.rb:13

So I followed Nick S.'s advice on bundling supporting gems in a jar:

http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar/

I named the jar ssl-gems. Now when I attempt to run the script like
this:

java -jar jruby-complete-1.7.2.jar -rssl-gems.jar my_script.rb

This returns with:

LoadError: no such file to load – ssl-gems
require at org/jruby/RubyKernel.java:1027
require at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/my_script/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36

ssl-gems.jar is indeed right there! I can run jar tf ssl-gems.jar and it
lists:

META-INF/
META-INF/MANIFEST.MF
cache/
cache/bouncy-castle-java-1.5.0146.1.gem
cache/jruby-openssl-0.8.2.gem
doc/
gems/
gems/bouncy-castle-java-1.5.0146.1/
gems/bouncy-castle-java-1.5.0146.1/lib/
gems/bouncy-castle-java-1.5.0146.1/lib/bcmail-jdk15-146.jar
gems/bouncy-castle-java-1.5.0146.1/lib/bcprov-jdk15-146.jar
gems/bouncy-castle-java-1.5.0146.1/lib/bouncy-castle-java.rb
gems/bouncy-castle-java-1.5.0146.1/LICENSE.html
gems/bouncy-castle-java-1.5.0146.1/README
gems/jruby-openssl-0.8.2/
gems/jruby-openssl-0.8.2/.gemtest
gems/jruby-openssl-0.8.2/History.txt
gems/jruby-openssl-0.8.2/lib/
gems/jruby-openssl-0.8.2/lib/1.8/
gems/jruby-openssl-0.8.2/lib/1.8/openssl/
gems/jruby-openssl-0.8.2/lib/1.8/openssl/bn.rb
<~ snip ~>

Am I missing a step? I can’t ask the client to download and install
jruby, that’s not an option. I have to package this as standalone or
rewrite the whole thing in Java…yuck.

-Jim

May I suggest a slightly different approach that makes life easier?

Instead of using jruby-complete use the regular jruby and then the gems
will be part of it without any extra work on your part.

In your project directory (pretend it’s myJRproj)
Download the JRuby binary (jruby-bin-1.7.2.zip) save it somewhere safe
and extract it into myJRtest

You will then have a directory structure like this (plus your own files)
myJRproj
jruby-1.7.2
bin
docs
etc…

In the directory myRJproj create a shell-script (call it
LocalTerminal.sh) with the following contents which will create the
minimal necessary PATH
#!/bin/bash

 x-terminal-emulator -e bash -c "
 export PATH=$PWD/jruby-1.7.2/bin:$PATH;

 /bin/bash"

Make the shell-script executable.

When you double-click the shell-script it should open a terminal at the
directory myJRtest and you should be able to do jruby -v in the usual
way.

In Windows it would be a batch file containing:
set path=%path%;%cd%\jruby-1.7.2\bin
cmd

From this terminal if you “gem install ggg” the gems will be placed
within the local copy of JRuby.

I guess you will know how to modify the shell script or batch file (call
it start.sh?) so it actually runs your JRuby app by adding something
like jruby startmyprog.rb in place of cmd.

Then all you have to do is give your client the whole project directory
with instructions to double click the shell script or batch file.

You can put the whole thing in .zip file if you like.

…R

Robin McKay wrote in post #1096751:

May I suggest a slightly different approach that makes life easier?

While I truly do appreciate you taking the time to suggest another
approach, I am more interested in finding out why I can’t bundle some
gems into a jar file and have java/jruby recognize them. This looks to
be a LOADPATH/CLASSPATH loading issue, but I can’t be sure. I’ve seen a
few success stories so I’m wondering what I’m doing wrong.

Again, I really do appreciate you answering.

Thanks,
-Jim

Hi Jim,

Some suggestions below.

On Feb 13, 2013, at 1:41 PM, Jim W. wrote:

require at org/jruby/RubyKernel.java:1027
require at

jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/my_script/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36

I don’t remember if this is how it manifested, but when I tried
embedding jruby-openssl in a jar, I know I had to expand the embedded
JARs into the top level of the gemjar. (I added support for this to
buildr-gemjar1.) Whether or not this is your current problem, you’ll
probably run into it eventually.

My project suite_authorization_source.rb2 creates a gemjar for its
integration tests that includes jruby-openssl. The script that requires
the gemjar it is visible in the source3. One different from your
efforts is that it uses the full path to the jar. I’m not sure what
search path JRuby would use when looking for required jars; this might
be an approach you could adopt.

Rhett

kristian wrote in post #1096770:

try adding the current directory where your ssl-gem.jar resides to the
load_path:

java -jar jruby-complete-1.7.2.jar -I . -rssl-gems.jar my_script.rb

  • Christian

That actually produces an interesting result:

C:\Documents and Settings\jwharton\My Documents\igpt_proxy>java -jar
jruby-complete-1.7.2.jar -I . -rgem_jar.jar igpt_proxy.rb
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant PKCS1_PADDI
NG
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant SSLV23_PADD
ING
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant NO_PADDING
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant PKCS1_OAEP_
PADDING
LoadError: no such file to load – openssl/dummy
(root) at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:24
require at org/jruby/RubyKernel.java:1027
(root) at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1
(root) at igpt_proxy.rb:14

(Yes, the script name is different than the initial post… there’s no
reason to use a generic name like my_script.rb… I’ve got nothing to
hide :wink: )

On Thu, Feb 14, 2013 at 3:38 AM, Jim W. [email protected]
wrote:

LoadError: no such file to load – openssl/dummy

looks more like an openssl issue right now. what about using
jruby-complete-1.7.1.jar there the whole openssl stuff is already
packed with the jruby !!! at least it could give you a start.

java -jar jruby-complete-1.7.1.jar igpt_proxy.rb

I am curious about that since I believe it was really neat to have
everything packed - at least for me it reduced a lot of headache the
jruby version.

  • Christian

try adding the current directory where your ssl-gem.jar resides to the
load_path:

java -jar jruby-complete-1.7.2.jar -I . -rssl-gems.jar my_script.rb

  • Christian

On Wed, Feb 13, 2013 at 8:41 PM, Jim W. [email protected]
wrote:

JRuby 1.1.6: Gems-in-a-jar

I named the jar ssl-gems. Now when I attempt to run the script like
this:

java -jar jruby-complete-1.7.2.jar -rssl-gems.jar my_script.rb

This is wrong.

Instead you should do this (note the ‘;’ in class path as you’re using
Windows):

java -cp jruby-complete-1.7.2.jar;ssl-gems.jar org.jruby.Main
-rubygems my_script.rb

Make sure you ssl-gems.jar contains the following structure (on top of
the jar/zip):

bin (if any) gems specifications


Christian

Jim, thank you very much for your kind words.

I am always intrigued that people prefer complicated courses through
life.

But, hey, each to his own.

Think about it this way - someone spent many many hours creating the
software “solution” that is causing you trouble.

…R

Jim W. wrote in post #1096759:
Robin McKay wrote in post #1096751:

May I suggest a slightly different approach that makes life easier?

While I truly do appreciate you taking the time to suggest another
approach, I am more interested in finding out why I can’t bundle some
gems into a jar file and have java/jruby recognize them. This looks to
be a LOADPATH/CLASSPATH loading issue, but I can’t be sure. I’ve seen a
few success stories so I’m wondering what I’m doing wrong.

Again, I really do appreciate you answering.

Thanks,
-Jim

On Thu, Feb 14, 2013 at 1:26 PM, Christian MICHON
[email protected] wrote:

java -cp jruby-complete-1.7.2.jar;ssl-gems.jar org.jruby.Main
-rubygems my_script.rb

this will search the openssl on Gem.path which depends on your system
and your GEM_PATH settings. so this might even work like this

$ java -cp jruby-complete-1.7.2.jar org.jruby.Main -rubygems
my_script.rb

depending on your environment setup.

On Thu, Feb 14, 2013 at 10:11 AM, kristian [email protected] wrote:

depending on your environment setup.

True. But when I use jruby-complete, my gems are always in a jar in
the same folder as jruby-complete, not expanded in a GEM_PATH (I do
not use it in Windows).

That is a sane rule to me. Normally what I gave to Jim should work out
of the box. He can choose to remove the ‘-rubygems’ switch.


Christian

Christian MICHON wrote in post #1096901:

On Thu, Feb 14, 2013 at 10:11 AM, kristian [email protected] wrote:

depending on your environment setup.

True. But when I use jruby-complete, my gems are always in a jar in
the same folder as jruby-complete, not expanded in a GEM_PATH (I do
not use it in Windows).

That is a sane rule to me. Normally what I gave to Jim should work out
of the box. He can choose to remove the ‘-rubygems’ switch.


Christian

That had the same result as above:

C:\Documents and Settings\jwharton\My Documents\igpt_proxy>java -cp
jruby-complete-1.7.2.jar;gem_jar.jar org.jruby.Main -rubygems
igpt_proxy.rb
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant PKCS1_PADDI
NG
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant SSLV23_PADD
ING
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant NO_PADDING
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:25
warning: already initialized constant PKCS1_OAEP_
PADDING
LoadError: no such file to load – openssl/dummy
(root) at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/openssl.rb:24
require at org/jruby/RubyKernel.java:1027
(root) at
jar:file:/C:/Documents%20and%20Settings/jwharton/My%20Documents/igpt_proxy/jruby-complete-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1
(root) at igpt_proxy.rb:14

The jar is laid out like you specified. OpenSSL issue maybe?

kristian wrote in post #1096815:

On Thu, Feb 14, 2013 at 3:38 AM, Jim W. [email protected]
wrote:

LoadError: no such file to load – openssl/dummy

looks more like an openssl issue right now. what about using
jruby-complete-1.7.1.jar there the whole openssl stuff is already
packed with the jruby !!! at least it could give you a start.

java -jar jruby-complete-1.7.1.jar igpt_proxy.rb

I am curious about that since I believe it was really neat to have
everything packed - at least for me it reduced a lot of headache the
jruby version.

  • Christian

Where can I find 1.7.1? It’s not available on their site anymore. They
have 1.6.8 but their “All Previous Releases” section doesn’t have 1.7.0
or 1.7.1.

-Jim

http://repo1.maven.org/maven2/org/jruby/jruby-complete/1.7.1/

let me know if that works for you or not !

  • Christian

kristian wrote in post #1096931:

http://repo1.maven.org/maven2/org/jruby/jruby-complete/1.7.1/

let me know if that works for you or not !

  • Christian

Very interesting. 1.6.8 works fine. 1.7.1 errors out just like 1.7.2.

Christian MICHON wrote in post #1096969:

On Thu, Feb 14, 2013 at 9:11 PM, Jim W. [email protected]
wrote:

kristian wrote in post #1096931:

http://repo1.maven.org/maven2/org/jruby/jruby-complete/1.7.1/

let me know if that works for you or not !

  • Christian

Very interesting. 1.6.8 works fine. 1.7.1 errors out just like 1.7.2.

I should have mentioned it: I’m still using 1.6.8 as
http://jira.codehaus.org/browse/JRUBY-6996 is a no go for me on
Windows.

So what I sent was for 1.6.8, not 1.7.x

I really suggest to use ‘-cp’ instead of ‘-jar’ : have a look at what
I did 2 years ago
jruby/bin/jruby.cmd at master · cmichon/jruby · GitHub


Christian

I’ll pass the -cp flag along in my documentation. 1.6.8 works well
enough for the little proxy program that this is. (TCP raw socket to
HTTP POST request proxy)

I appreciate you taking the time to sort this out with me.

-Jim

On Thu, Feb 14, 2013 at 9:11 PM, Jim W. [email protected]
wrote:

kristian wrote in post #1096931:

http://repo1.maven.org/maven2/org/jruby/jruby-complete/1.7.1/

let me know if that works for you or not !

  • Christian

Very interesting. 1.6.8 works fine. 1.7.1 errors out just like 1.7.2.

I should have mentioned it: I’m still using 1.6.8 as
http://jira.codehaus.org/browse/JRUBY-6996 is a no go for me on
Windows.

So what I sent was for 1.6.8, not 1.7.x

I really suggest to use ‘-cp’ instead of ‘-jar’ : have a look at what
I did 2 years ago


Christian