Including gems in a bundle with Rawr (Jruby)

  • Thread starter Eric Christopherson
  • Start date
E

Eric Christopherson

I'm able to make a jar/.exe/.app out of a simple script with Rawr, but
I can't seem to run one that uses a gem. It complains that it can't
find the gem at runtime. I've read
<http://kenai.com/projects/monkeybars/pages/UseRubyGemsInYourApplication>
and tried to follow the instructions, but without success. Might
anyone be able to help?

I'm not sure if I should just paste my source files here, or use a
pastebin or something. The script is very short, but everything taken
together still requires scrolling. Please let me know how I should
post my code. Thanks.
 
E

Eric Christopherson

I'm able to make a jar/.exe/.app out of a simple script with Rawr, but
I can't seem to run one that uses a gem. It complains that it can't
find the gem at runtime. I've read
<http://kenai.com/projects/monkeybars/pages/UseRubyGemsInYourApplication>
and tried to follow the instructions, but without success. Might
anyone be able to help?

I'm not sure if I should just paste my source files here, or use a
pastebin or something. The script is very short, but everything taken
together still requires scrolling. Please let me know how I should
post my code. Thanks.

All right, I'm just going to paste my code. It's possible no one
responded because no one here is that familiar with Rawr (or at least
its internals), but I might as well ask anyway.

My script runs just fine with Jruby. It uses the Barby (bar code
generator) gem, which I unpacked into lib/ruby. I renamed the unpacked
directory to just barby. Here is the script, main.rb:

require 'rubygems'

puts 'Load path:'
$LOAD_PATH.each { |dir| puts dir }
puts

require 'barby'

puts 'Hello, world.'
__END__


My build_configuration.rb is:

configuration do |c|
c.project_name = 'RawrTest'
c.output_dir = 'package'
c.main_ruby_file = 'main'
c.main_java_file = 'org.rubyforge.rawr.Main'

# Compile all Ruby and Java files recursively
# Copy all other files taking into account exclusion filter
c.source_dirs = ['src', 'lib/ruby']
c.source_exclude_filter = []

# Location of the jruby-complete.jar. Override this if your jar
lives elsewhere.
# This allows Rawr to make sure it uses a compatible jrubyc when compiling,
# so the class files are always compatible, regardless of your system JRuby.
#c.jruby_jar = 'lib/java/jruby-complete.jar'
c.compile_ruby_files = true # I have also tried setting this to false
#c.java_lib_files = []
c.java_lib_dirs = ['lib/java']
#c.files_to_copy = Dir['other_files/dir/**/*']

c.target_jvm_version = 1.5
#c.jars[:data] = { :directory => 'data/images', :location_in_jar =>
'images', :exclude => /bak/}
#c.jvm_arguments = "-server"
#c.java_library_path = "lib/java/native"

# Bundler options
# c.do_not_generate_plist = false
end
__END__

Finally, my src/manifest.rb:

Dir.glob(File.expand_path(File.dirname(__FILE__) +
'/**/*').gsub('%20', ' ')).each do |directory|
next if directory =~ /\/barby\//
$LOAD_PATH << directory unless directory =~ /\.\w+$/
#File.directory? is broken in current JRuby for dirs inside jars
end

# Not sure what to put in the middle of this file

require 'resolver' # I've also tried it without this

case Monkeybars::Resolver.run_location
when Monkeybars::Resolver::IN_FILE_SYSTEM

# assorted stuff omitted

when Monkeybars::Resolver::IN_JAR_FILE
add_to_load_path "barby/lib"
end
__END__

I believe all the other files in the directory are the ones created by
'rawr install'. When I run the program, my load path is listed, and
then there is an exception:

Exception in thread "main"
file:/Users/eric/Sources/RawrTest/package/jar/lib/java/jruby-complete.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require': no such file to load -- barby (LoadError)
from file:/Users/eric/Sources/RawrTest/package/jar/lib/java/jruby-complete.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in
`require'
from src/main.rb:7:in `require'
from <script>:1
...internal jruby stack elided...
from Kernel.require(file:/Users/eric/Sources/RawrTest/package/jar/lib/java/jruby-complete.jar!/META-INF/jruby.home/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31)
from Kernel.require(src/main.rb:7)
from Kernel.require(<script>:1)
from (unknown).(unknown):)1)

Thanks in advance.
 
J

James Britt

Eric said:
I'm able to make a jar/.exe/.app out of a simple script with Rawr, but
I can't seem to run one that uses a gem. It complains that it can't
find the gem at runtime. I've read
<http://kenai.com/projects/monkeybars/pages/UseRubyGemsInYourApplication>
and tried to follow the instructions, but without success. Might
anyone be able to help?

Is the gem installed on all system were the rawr-packaged app will run?

If you are not assured of that then having code that expects a gem is
asking for trouble.


Also, the instructions on the page you gave has this:

"You need to unpack the gem into lib/ruby"

The reason for that is so that you do not need to use rubygems to load
anything. You should be using 'require <filename>', and all paths
should be relative to your app. rubygems messes with the load path,
making life difficult for self-contained apps.

If you have code that is attempting to load a gem instead of trying to
load files out of your bundled app then something is likely wrong.

(Note that the example code on that help page never makes use of
rubygems. Only plain old 'require'.)

Some gems contain code that makes a call to "require 'rubygems'".
(There was a previous thread on ruby-talk about how inane this is.)

I usually hate to tell people "don't do that" when they ask how do do
something, but trying to use rubygems from inside an app packaged up
with rawr is just asking for trouble. One of the purposes of rawr is
create self-sufficient apps.

Grep you code for any reference to rubygems and delete it. :)


--
James Britt

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development
 
E

Eric Christopherson

Thanks for your response.

Is the gem installed on all system were the rawr-packaged app will run?

No; the reason I want to use Rawr is to deliver a program where no
Ruby installation exists.
If you are not assured of that then having code that expects a gem is ask= ing
for trouble.


Also, the instructions on the page you gave has this:

"You need to unpack the gem into lib/ruby"

The reason for that is so that you do not need to use rubygems to load
anything. =A0You should be using 'require <filename>', and all paths shou= ld be
relative to your app. =A0rubygems messes with the load path, making life
difficult for self-contained apps.

OK. I was able to get it to load Barby, but I had to add
'lib/ruby/barby/lib' to my $LOAD_PATH. I don't understand the purpose
of unpacking the gem into lib/ruby specifically, when it could reside
anywhere within the hierarchy.
 
J

James Britt

Eric said:
OK. I was able to get it to load Barby, but I had to add
'lib/ruby/barby/lib' to my $LOAD_PATH. I don't understand the purpose
of unpacking the gem into lib/ruby specifically, when it could reside
anywhere within the hierarchy.

Wherever you want to place it, you have to be sure that the load path
includes it. The rawr build_config has lib/ruby by default, I believe.
(You need to indicate what local paths to set for $: in your code, but
also what folders should be packaged up by rawr, and how they should be
structured in any resulting jar file.)

Technically, you can set this up as you like, but it's far easier to use
and to explain using some rawr conventions then saying, abstractly, you
can set up your sub-dirs and load path almost any way you like.
Because, as it happens, you have to be careful, since (as the page
explains) code inside gems sometimes makes assumptions about it's parent
directories and such.

For example, I had trouble using the 'builder' code. It came down to
there being 2 builder.rb files. One would load the other. But if $: is
not set up correctly, then the wrong one may be found first, with
annoying results. (And I'm pretty sure I wrote an earlier version of
the page under discussion precisely because of these issues.)
Yes, and I see now that prawn (which I also need) does just that. :(

GREG! on noes ... :)
That's what I want to do: make a program (that uses some gems) and
package them all together so they don't need to be installed
separately. I must be misunderstanding the intention of the page we're
discussing; I thought it was about doing that.

The page is setting up unpacked gem files in an app. (The larger
premise of rawr is that the app has a main file, with all other required
files being included in subdirectories or jars, all bundled up in such a
way that Java can execute it. )

rawr can build installers for your app that makes sure all the related
files get put in place.

But you have to unbundle any gems used by your code. And at that point,
you should thinking of them as gems, and simply as libs that live in a
subdirectory of your application folder.

--
James Britt

www.jamesbritt.com - Playing with Better Toys
www.ruby-doc.org - Ruby Help & Documentation
www.rubystuff.com - The Ruby Store for Ruby Stuff
www.neurogami.com - Smart application development
 
E

Eric Christopherson

Wherever you want to place it, you have to be sure that the load path
includes it. The rawr build_config has lib/ruby by default, I believe. (Y= ou
need to indicate what local paths to set for $: in your code, but also wh= at
folders should be packaged up by rawr, and how they should be structured = in
any resulting jar file.)

OK. I put this at the top of my script:

$LOAD_PATH << 'lib/ruby/barby/lib'
$LOAD_PATH << 'lib/ruby/prawn/lib'
$LOAD_PATH << 'lib/ruby/prawn-core/lib'
$LOAD_PATH << 'lib/ruby/prawn-layout/lib'
$LOAD_PATH << 'lib/ruby/prawn-security/lib'

This allows the jarred script to run -- but I later realyzed that it's
still reading the files from the filesystem. If I run the jar from a
different directory, or if I move or delete the lib directory, it is
unable to load them.

Questions:
1. How do I add libraries *inside the jar* to my $LOAD_PATH?
2. Is there a more elegant way to add them than to just list each one
at the top of my script? I thought the manifest.rb file was supposed
to take care of this, but it doesn't.
3. What is actually supposed to go in manifest.rb?
Technically, you can set this up as you like, but it's far easier to use = and
to explain using some rawr conventions then saying, abstractly, you can s= et
up your sub-dirs and load path almost any way you like. Because, as it
happens, you have to be careful, since (as the page explains) code inside
gems sometimes makes assumptions about it's parent directories and such.

For example, I had trouble using the 'builder' code. =A0It came down to t= here
being 2 builder.rb files. =A0One would load the other. =A0But if $: is no= t set
up correctly, then the wrong one may be found first, with annoying result= s.
=A0(And I'm pretty sure I wrote an earlier version of the page under
discussion precisely because of these issues.)
OK.


GREG! =A0on noes ... =A0:)

Interestingly, prawn works just fine as long as the prawn directories
are available on the file system -- even though it does a "require
'rubygems'". (I've even uninstalled the actual prawn gems and it still
works.)
 
R

Rob Biedenharn

OK. I put this at the top of my script:

$LOAD_PATH << 'lib/ruby/barby/lib'
$LOAD_PATH << 'lib/ruby/prawn/lib'
$LOAD_PATH << 'lib/ruby/prawn-core/lib'
$LOAD_PATH << 'lib/ruby/prawn-layout/lib'
$LOAD_PATH << 'lib/ruby/prawn-security/lib'

(Disclaimer: This answer is based solely on Ruby knowledge, not JAR
behavior or JRuby)

Does it work if you do:

$LOAD_PATH.unshift 'lib/ruby/prawn-security/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn-layout/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn-core/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn/lib'
$LOAD_PATH.unshift 'lib/ruby/barby/lib'

this puts your directories at the front

-Rob
This allows the jarred script to run -- but I later realyzed that it's
still reading the files from the filesystem. If I run the jar from a
different directory, or if I move or delete the lib directory, it is
unable to load them.

Questions:
1. How do I add libraries *inside the jar* to my $LOAD_PATH?
2. Is there a more elegant way to add them than to just list each one
at the top of my script? I thought the manifest.rb file was supposed
to take care of this, but it doesn't.
3. What is actually supposed to go in manifest.rb?


Interestingly, prawn works just fine as long as the prawn directories
are available on the file system -- even though it does a "require
'rubygems'". (I've even uninstalled the actual prawn gems and it still
works.)

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
E

Eric Christopherson

Does it work if you do:

$LOAD_PATH.unshift 'lib/ruby/prawn-security/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn-layout/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn-core/lib'
$LOAD_PATH.unshift 'lib/ruby/prawn/lib'
$LOAD_PATH.unshift 'lib/ruby/barby/lib'

this puts your directories at the front

-Rob

I'm not sure at this point; I seem to have messed something else up in
the script. I am guessing it won't help, though; when I used << to
append the paths, my script ran, but it turned out that it was looking
on the filesystem instead of within the jar.

Hi,
i have no manifest file.
I which file i have to place $LOAD_PATH?

I placed it in my main script, but then put it in a secondary script
that the main script requires. However, it didn't help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top