Including gems in a bundle with Rawr (Jruby)

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.

On Sat, Feb 20, 2010 at 7:07 PM, Eric C.
[email protected] wrote:

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 :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(:1)
from (unknown).(unknown)(:1)

Thanks in advance.

Eric C. wrote:

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 ’, 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. :slight_smile:


James B.

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

Thanks for your response.

On Sun, Feb 21, 2010 at 3:32 PM, James B. [email protected]
wrote:

Eric C. wrote:

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?

No; the reason I want to use Rawr is to deliver a program where no
Ruby installation exists.

relative to your app. rubygems 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.

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.)

Yes, and I see now that prawn (which I also need) does just that. :frowning:

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.

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.

On Mon, Feb 22, 2010 at 12:28 AM, James B. [email protected]
wrote:

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?

(And I’m pretty sure I wrote an earlier version of the page under
discussion precisely because of these issues.)

OK.

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

Yes, and I see now that prawn (which I also need) does just that. :frowning:

GREG! on noes … :slight_smile:

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.)

On Feb 23, 2010, at 10:28 AM, Eric C. wrote:

$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

  1. What is actually supposed to go in manifest.rb?

gems sometimes makes assumptions about it’s parent directories and

rubygems.

up with
The page is setting up unpacked gem files in an app. (The larger

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.

Rob B. http://agileconsultingllc.com
[email protected]

Eric C. wrote:

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. :frowning:
GREG! on noes … :slight_smile:

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.

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 B.

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

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

Rob B. wrote:

On Feb 23, 2010, at 10:28 AM, Eric C. wrote:

$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

On Tue, Feb 23, 2010 at 9:48 AM, Rob B.
[email protected] wrote:

-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.

On Fri, Mar 5, 2010 at 5:17 AM, Malte Be [email protected] wrote:

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.

Eric C. wrote in post #890794:

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.

Example java code for generating barcode using jar
http://www.keepdynamic.com/java-barcode/