Forum: JRuby Unable to run Warbler-generated JAR on linux (bundler/index load error)

7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-07-30 22:21
(Received via mailing list)
I'm at a loss as to whether this is a Warbler, JRuby, or Bundler issue.
I'm
hoping someone else may have some insight. This is an extension of
https://github.com/jruby/warbler/issues/144

I have a sample app at https://github.com/doxavore/warbler144 with a JAR
generated on an Ubuntu machine. I get no errors when generating the JAR
on
Linux or OSX. Regardless of where the JAR was generated, it runs fine on
OSX (tested on 1.8.4) and fails every time on my Ubuntu 13.04 laptop and
Ubuntu 12.04 server, all 64-bit.

The trace looks just the same regardless of the linux machine I run this
JAR on.

Does anyone have any suggestions where I might even look to try to
resolve
this issue?

doug@qa2:~$ java -jar myapp.jar
LoadError: no such file to load -- bundler/index
      fetch_specs at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/source/rubygems.rb:165
            specs at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/source/rubygems.rb:67
  __materialize__ at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/lazy_specification.rb:52
      materialize at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/spec_set.rb:88
             map! at org/jruby/RubyArray.java:2393
      materialize at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/spec_set.rb:85
            specs at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/definition.rb:114
        specs_for at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/definition.rb:159
  requested_specs at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/definition.rb:148
  requested_specs at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/environment.rb:18
            setup at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/runtime.rb:13
            setup at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler.rb:120
           (root) at
jar:file:/home/doug/myapp.jar!/gems/bundler-1.3.5/lib/bundler/setup.rb:7
          require at org/jruby/RubyKernel.java:1027
           (root) at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1
          require at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:60
          require at org/jruby/RubyKernel.java:1027
           (root) at
file:/home/doug/myapp.jar!/warbler144/config/boot.rb:13
           (root) at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1
          require at org/jruby/RubyKernel.java:1027
          require at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36
           (root) at
file:/home/doug/myapp.jar!/warbler144/config/application.rb:1
             load at org/jruby/RubyKernel.java:1046
           (root) at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:1
          require at org/jruby/RubyKernel.java:1027
          require at
jar:file:/tmp/jruby8823182374008356699extract/jruby-stdlib-1.7.2.jar!/META-INF/jruby.home/lib/ruby/shared/rubygems/custom_require.rb:36
           (root) at file:/home/doug/myapp.jar!/warbler144/bin/myapp:3


Thanks,

Doug
666badca71c452ae51c999971419b506?d=identicon&s=25 Joe Kutner (Guest)
on 2013-07-30 22:48
(Received via mailing list)
Try setting this in your warble.rb

  config.override_gem_home = true

By default, warbler will use your $GEM_HOME env if it's set, which means
you might not be using the same gem path on both system.  This will
probably change in v1.4.0.
7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-07-30 23:00
(Received via mailing list)
Hi Joe,

Thanks for the fast response. I've tried adding that config value but
still
have no luck running it on either linux machine. Also, I just checked
and
neither machine has a GEM_HOME env variable. When I try to dump out the
Gem.dir and $: just before the call to require "bundler/setup" I get
this:

Gem.dir = "file:/home/doug/projects/warbler144/myapp.jar!"
LOAD_PATHS:
file:/home/doug/projects/warbler144/myapp.jar!/storage/lib
file:/tmp/jruby7252491188195959077extract/jruby-stdlib-1.7.4.jar!/META-INF/jruby.home/lib/ruby/1.9/site_ruby
file:/tmp/jruby7252491188195959077extract/jruby-stdlib-1.7.4.jar!/META-INF/jruby.home/lib/ruby/shared
file:/tmp/jruby7252491188195959077extract/jruby-stdlib-1.7.4.jar!/META-INF/jruby.home/lib/ruby/1.9

I've tried this with Warbler 1.3.8 and current master@cb4910, both in
JRuby
1.7.4 and 1.7.2. Every config I try gives me the same error.
7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-07-30 23:07
(Received via mailing list)
Also, for what it's worth, generating a simple Rails app into a WAR file
and running that works perfectly on all the machines I've tested it on.
So
it appears to be related to how any linux machine I can get my hands on
interacts with the Warbler-generated JARs, not WARs.
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos Caro (Guest)
on 2013-07-31 03:11
(Received via mailing list)
Hi.

I had a similar case trying to package a jar file using another tool.
Take's place when i embedded a Jruby compIete jar on the jar. The
problem was at execution time too. The program cant find a Jruby
resource into the jar internal path because is looking at another
location different where's really placed...

Provisionaly I edited content using a compresor to mitigate the problem.
Dont know how to solve it on Warbler but hope this can help.

Regards
7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-07-31 17:40
(Received via mailing list)
I've managed to track down what I believe is odd behavior, but hopefully
I'm just doing something wrong.

I tried running the jar on a new Mac (10.8.4), without rbenv/rvm
installed,
running the base system ruby:
  % java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
  % ruby -v
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]

Bundler failed while trying to autoload the bundler/index file. When I
put
1.9.3 (with chruby) on the same machine and ran it, it got past this
error
(and subsequently failed on trying to load a git repo). So, 1.8.7 fails
to
load Bundler, and 1.9.3 is likely something I can fix in how I warble.

What I don't quite understand is the following:
1) Why should the system's ruby matter when I'm running from a JAR that
includes the jruby-1.7.0 jars?
2) My linux machine's shell that runs the warbler-generated jar _is_
running JRuby 1.7.4 in a ruby-1.9.3 flavor, but it still fails when
trying
to autoload bundler/index. What's up with that?

Manuel - I'm not sure exactly what jruby-complete gives me compared to
using warbler + embedding the jruby lib jars. Warbler certainly has ease
of
use down, if only I could get it to work on all of my machines. :)

Can anyone weigh in on some of my slightly-more-refined questions above?
Any help would be greatly appreciated!

Thanks,
Doug


On Tue, Jul 30, 2013 at 8:10 PM, Manuel Ramos Caro <
Caa2df9372ffa0a9e95b2bab1e8fea34?d=identicon&s=25 Karol Bucek (Guest)
on 2013-07-31 18:38
(Received via mailing list)
Maybe a bit off but isn't this likely related to
https://github.com/jruby/warbler/commit/44246564a8...

One might try it out by manually editing the generated init.rb file...

K.
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos (Guest)
on 2013-07-31 20:12
(Received via mailing list)
There's not diference it can run on a not Jruby installed machine only
with
Jre on both. Its only another way to put Jruby on the jar. As i said
must
be a resource rb file thats onto jar maybe Jruby installation are
confusing
all and tried to use local install or a problem with resources onto
file.
Have you try to run it on a clean linux without Jruby or Ruby? Have you
get
same error?

Regards
El 31/07/2013 17:40, "Doug Mayer" <dougtmayer@gmail.com> escribi:
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos Caro (Guest)
on 2013-07-31 20:58
(Received via mailing list)
Hi again, i still thinking on that..

Did you take a look in the basement with a compresor? This can give you
a map of what's Warbler do with your rb required files and this can help
a lot.

I use Kde's ARK.

Regards.
7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-07-31 22:53
(Received via mailing list)
Karol - Thanks for the pointer. I tried manually editing the JAR's
META-INF/init.rb file to ALWAYS set ENV['GEM_HOME'] (instead of
conditionally), but it still fails when attempting to load bundler/index
with:
    error: org.jruby.embed.EvalFailedException: (LoadError) no such file
to
load -- bundler/index

Manuel - Nothing looks out of place in the Warbler-generated JAR. A
built
version I'm using for testing is at
https://github.com/doxavore/warbler144/blob/master/myapp.jar I've tried
putting it on a fresh Ubuntu 12.04 machine with literally nothing
installed
on it (though it seems to include ruby 1.8.7 by default) - it gets the
same
error.

The consensus seems to be, though, that I'm not losing my mind, and
particularly with the META-INF/init.rb file hard-setting (not
conditionally) all of its values, the "system ruby" shouldn't be
affecting
the packaged JRuby in my JAR at all.



On Wed, Jul 31, 2013 at 1:57 PM, Manuel Ramos Caro <
974b3d592f78510db0227e528841ccb9?d=identicon&s=25 Robin McKay (robin2)
on 2013-08-02 20:36
There would be no need for this discussion and all the time wasted
trying to figure things out if people didn't use Bundler and Warbler to
complicate what is (thanks to JRuby), essentially, a simple process.

...R
7dc8bd501ae009ef2d288d3e450fe42e?d=identicon&s=25 Doug Mayer (Guest)
on 2013-08-02 23:10
(Received via mailing list)
Hi Robin,

Is there any documentation outlining this simple process, or perhaps
you've
previously posted or blogged on the subject? This is the first time I've
attempted to deploy anything this way (not having much of a Java
background).

Nothing is marrying me to Warbler, except that it seems to be a common
solution that others in my situation use without issue.

Thanks,
Doug
974b3d592f78510db0227e528841ccb9?d=identicon&s=25 Robin McKay (robin2)
on 2013-08-03 08:42
Hi Doug,

You are the first person that has shown any interest and it's a while
since I did this so I will need to re-educate myself. I can't do this
today but will do my best to reply properly tomorrow.

As far as I recall there are different ways to do things if you want to
(i) make a JRuby program that can be easily distributed to other PCs
(which doesn't need a Jar), (ii) put everything in a Jar (but why
bother?) or (iii) put everything in a War - which I think is only needed
if you want to deploy with Tomcat.

Which are you interested in?

...R

PS my objection to Bundler and Warbler is that people spend time
debugging them (or trying to figure out how to use them) rather than
focusing on debugging the application.
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos (Guest)
on 2013-08-03 13:50
(Received via mailing list)
100% Agree using Warble failed for me to at the first try... And i didnt
have time to solve it. I have use Jrubyc + Java sdk tools + JarSplice to
created a fat static jar . Theres also a JavaFx documented process that
last week posted on mail list another user.
I didnt use JavaFx because this can be package on target system and i
wanna
be as wide as i can...

I think that on last years community as lost a little of the focus as
you
said the spirit is do easy and fast and complex tool do it harder.

Regards
El 03/08/2013 08:43, "Robin McKay" <lists@ruby-forum.com> escribi:
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos Caro (Guest)
on 2013-08-03 14:41
(Received via mailing list)
Android played me bad on before's mail...

Thats the link

https://github.com/jruby/jruby/wiki/Packaging-Nati...

Posted Before here...

https://www.ruby-forum.com/topic/4415944#1116844

Regards
C37cb1a6a19e23f067aae6ccb2d0de4b?d=identicon&s=25 Manuel Ramos Caro (Guest)
on 2013-08-03 14:53
(Received via mailing list)
974b3d592f78510db0227e528841ccb9?d=identicon&s=25 Robin McKay (robin2)
on 2013-08-06 17:28
Creating a War file without Warbler or Bundler.
-----------------------------------------------

I worked this out in the middle of 2012 and I haven't used it since so I
decided to build the demo project again from scratch following last
year's notes. Surprisingly it worked!

Because JRuby sits on the Java JVM it can be used in a very different
way from MRI Ruby. Generally a central copy of MRI Ruby is accessed by
all of the MRI applications on a PC. Tools like RVM and Bundler emerged
to make it easy to manage that system. But with JRuby it is trivially
easy for each application to have its own copy of JRuby so that there is
no need for management tools, no risk of different JRuby or Gem versions
becoming confused with each other and no risk of problems arising due to
the management tools. And if the application includes its own copy of
JRuby it can easily be copied to any other PC with the JVM. The
following DIY approach to War files builds on this idea that the
application has its own copy of JRuby.

When I looked at the output produced by Warbler it seemed to me that the
process of creating a War file for use with Tomcat is essentially
simple. Generally speaking you will only need to go through this process
once for every application so the total time involved will be a tiny
percentage of the time taken to develop an app. I don't believe it's
worth automating the process to save such a small amount of time. And if
you know how to build the War file then debugging problems will be
easier, or at least more transparent. And when you've done it once a lot
of the structure and files can simply be copied if you want to create
another app.

A War file is just a .zip file with a particular structure. The layout
of the directories and files before they are made into a War file is
like this. Everything in META-INF and WEB-INF will go into the War file.

/project
  /META-INF
    init.rb
    MANIFEST.MF

  /WEB-INF
    /lib (..all of the .jars)
    application files and folders
    config.ru
    web.xml


This demo is based on a small Sinatra app mostly following the advice
here
    http://padcom13.blogspot.co.uk/2011/05/running-sin...
except that I haven't use Warbler or Bundler. I have also omitted
sintra-reload to keep things simple.

The steps to produce the app are as follows:
(You can download all the
code here
https://docs.google.com/file/d/0B0hhHjM70n1TbHM0eE...
)

Create a directory for the project - call it "DemoWar"
In that directory create the directories META-INF and WEB-INF
In META-INF create the two files init.rb and MANIFEST.MF with contents
as in the example.
Create three directories within WEB-INF called "GemHome", "lib" and
"views". The name "lib" is mandatory.

Put a copy of jruby-completeXXX.jar into "lib". I've used
jruby-complete-1.7.0.jar. This file can be downloaded from the JRuby
website. This will be the JRuby that runs the app.

For convenience create two shell scripts called "LocalTerm.sh" and
"JRUBY" with the contents as in the example and make them executable.
Double clicking LocalTerm.sh will then open a terminal at the WEB-INF
directory after setting some environment variables. The JRUBY script is
just a convenience to avoid a lot of typing. You can check that JRuby is
working with "JRUBY -v". (Equivalent batch files will be needed if you
use Windows). If you want to use any of the internal JRuby commands such
as gem install remember to include -S (see examples below).

The purpose of using JRuby this way is so that the exact same version is
used for development and deployment and there are no cracks into which
something can slip. And, of course, Tomcat will be using jruby-complete
so you might as well use it for everything. (Because JRuby is not
installed in the usual way the lower-case "jruby" command won't work).

From the terminal install the Sinatra gem in the usual way "JRUBY -S gem
install sinatra". You also need "JRUBY -S gem install jruby-rack". The
gems will be stored within the GemHome directory.

Create the files for the Sinatra app. These are "hello.rb", "code.rb"
and "views/index.erb".

At this stage the app should work from your terminal with the usual
"JRUBY hello.rb". Sinatra should start a server running at
localhost:4567. This is all standard Sinatra stuff. You can develop and
test your app at this stage without bothering with Tomcat.

To be able to make our app into a War we need a couple of additional
files in WEB-INF "config.ru" and "web.xml". The contents of both are
straightforward, even if the xml file is tedious.

A War file requires all of the Jar files that are part of the project to
be in the "lib" directory. It doesn't matter if these are copies which
duplicate files within the gems. In a small application one could go
through all of the gem directories and manually find and copy the Jar
files. To save me time and to show I'm not in principle against
automation I have created a JRuby program to do this automatically. It
is called "findJars.rb". Run this in the usual way "JRUBY findJars.rb"
and it will do all the hard work. (Note that findJars.rb started life in
a somewhat different situation and may have bits that could be tidied
up).

Now we have the proper contents in the two directories META-INF and
WEB-INF and we just need to package them into a War file. The easiest
way is probably to change directory up one level to DemoWar and create
the war file with "jar -cvf DemoWar.war ." (the final dot is essential).
(You could also create a Zip file with Archive manager and just change
its name). And to deploy it with Tomcat just copy the file DemoWar.war
to the Tomcat webapps directory. On my Xunbutu it's at
/var/lib/tomcat7/webapps/.

I'm not claiming that this simple way of doing things will cover every
possibility. And I can't remember how the contents of some of the
configuration files came about - I probably got them from a War file
that was created by Warbler. Obviously the person who created Warbler
knows all about this stuff and I feel strongly that if s/he had just
taken the time to write an instruction note like this (a) it would be a
much better note, (b) it would only have taken him/her an hour or two
and (c) s/he would have shared his/her knowledge with the rest of us
rather than spending much longer hiding that knowledge in an app that is
totally obscure when it fails. (Read Joel Spolsky's "Law of Leaky
Abstractions").

And if your app doesn't work with a simple system like this at least you
only have to concern yourself with debugging your own stuff.
666badca71c452ae51c999971419b506?d=identicon&s=25 Joe Kutner (Guest)
on 2013-08-07 07:43
(Received via mailing list)
This similar to the approach Square took
with Jetpack <https://github.com/square/jetpack>
(but Jetty instead of Tomcat and no war)

I agree that it's a good way of doing things,
and probably something I would choose for
myself over Warbler.  But for folks who are
new to the JVM ecosystem it can be a lot to
swallow. For those people, I think Warbler
makes a nice gateway deployment-drug
(when it's not giving them problems like this!).

 Thanks for sharing this -- I think I will point
a lot of people to this post in the future :)



-Joe
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.