Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errno::ENOTDIR on Dir.chdir into jar #1026

Closed
svenfuchs opened this issue Sep 19, 2013 · 6 comments
Closed

Errno::ENOTDIR on Dir.chdir into jar #1026

svenfuchs opened this issue Sep 19, 2013 · 6 comments
Assignees
Milestone

Comments

@svenfuchs
Copy link

Warbler::Traits::Bundler packages gems into a jar.

Running require "bundler/setup" inside the jar will try to Dir.chdir into these directories in order to evaluate gemspecs in their respective local path context.

This fails ... and as far as I understand basically renders Warbler::Traits::Bundler useless?

pry(main)> File.directory?('file:/path/to/some.jar!/gems')
=> true
pry(main)> Dir.chdir('file:/path/to/some.jar!/gems')
Errno::ENOTDIR: Not a directory - file:/path/to/some.jar!/gems
from org/jruby/RubyDir.java:458:in `chdir'

Here's a related issue on bundler: rubygems/bundler#1865 (comment)

@mkristian
Copy link
Member

per default jruby places its gems into

jruby.home/lib/ruby/gems/shared

with an executable jar all the gems could be places there as well (that is what jbundler does when creating executable jars). then before adding the gems you could need to 'install' the gem so you have yaml gemspec file inside the specifications directory.

but I would say that is all more a warbler issue then jruby. chdir inside a jar or even inside jar inside war does not seems the right approach.

@jkutner
Copy link
Member

jkutner commented Sep 19, 2013

It seems the only reason bundler does a Dir.chdir is so that relative paths in gems work. Is there another way for bundler to "trick" the relative paths into working?

@svenfuchs
Copy link
Author

I think this isn't about warbler, but more about the general idea to use bundler within or with jar'ed gems.

Actually, it seems to me that getting bundler to work within a jar (e.g. requiring "bundler/setup" within jar-bootstrap.rb) leads to more issues. E.g. bundler tests for write permissions on the path and then assumes a user directory etc.

This would be neat though, and solve my usecase:

# Gemfile
gem 'my-gem', path: 'file:my-gem.jar!/'

It seems I got this working by patching bundler:

module Bundler
  module SharedHelpers
      def chdir(dir, &blk)
        @chdir_monitor.synchronize do
          Dir.chdir dir, &blk
        end
      rescue Errno::ENOENT => e
        yield
      end
  end
end

... which works for me because the gemspec doesn't rely on relative paths. Obviously I wouldn't want to ship this, so solving the issue in either Bundler or Jruby would be awesome.

@mkristian
Copy link
Member

so basically you have gem packed into a jar !

I would just unpack that jar and install the gem via 'cd into/my/gem; gem
build .., gem install -l ....; cd -' and use the installed with bundler,
i.e. without the path. IMO that can be done inside the Gemfile as well and
bundler will not try to go online for that gem since it is already locally
installed.

then your exectuable jar will just work.

but if you can pack your gem inside a jar you also can just build the gem
and install it on local repo server (I guess I could talk more about local
rubygems repository servers . . . .)

IMO Dir.chdir inside a zipfile just opens up a trail of new features,
usually tools just unzip it and work on the temporary exploded zip.

but that are just my thoughts about that issue !!!

  • christian

@jkutner
Copy link
Member

jkutner commented Sep 20, 2013

the problem with unpacking is that many folks won't have a local jruby/ruby installed, or a Rubygems installed, or the gem command on the path or a number of other things. Most people that package up their gems into a jar this way are deploying to an environment that may not know anything about Ruby.

I think the :path option in the Gemfile is cool, but I doubt that it would be accepted by the bundler team. Since the path to the jar doesn't actually matter, maybe a :jar => true option that the SharedHelper looks for instead of just bombing out and rescuing. But I wouldn't expect that to be excepted either :)

Let me know if there is anything we can do in Warbler. I would offer that it is possible to write some kind of run exploded option that would set up the jruby and gems that the warbler jar contains and do what christian described (even if your system is ruby-unaware).

On Sep 20, 2013, at 6:35 AM, mkristian wrote:

so basically you have gem packed into a jar !

I would just unpack that jar and install the gem via 'cd into/my/gem; gem
build .., gem install -l ....; cd -' and use the installed with bundler,
i.e. without the path. IMO that can be done inside the Gemfile as well and
bundler will not try to go online for that gem since it is already locally
installed.

then your exectuable jar will just work.

but if you can pack your gem inside a jar you also can just build the gem
and install it on local repo server (I guess I could talk more about local
rubygems repository servers . . . .)

IMO Dir.chdir inside a zipfile just opens up a trail of new features,
usually tools just unzip it and work on the temporary exploded zip.

but that are just my thoughts about that issue !!!

  • christian

    Reply to this email directly or view it on GitHub.

@kares
Copy link
Member

kares commented Jun 15, 2018

seems to have changed somewhere along the 9K releases, here a sample irb session output from 9.2 :

irb(main):003:0> require_jar 'commons-lang', 'commons-lang', '2.6'
=> true
irb(main):004:0> $CLASSPATH
=> ["file:/home/kares/workspace/oss/jruby/lib/ruby/stdlib/jline/jline/2.11/jline-2.11.jar", "file:/home/kares/workspace/oss/jruby/lib/ruby/stdlib/readline.jar", "file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar"]
irb(main):005:0> jar = "file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar"
=> "file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar"
irb(main):006:0> in_jar = "file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/org/apache"
=> "file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/org/apache"
irb(main):007:0> File.directory? in_jar
=> true
irb(main):008:0> Dir.chdir in_jar
=> 0
irb(main):009:0> Dir.pwd
=> "/home/kares/workspace/oss/jruby/file:/opt/local/maven-repo/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/org/apache"

... so while its not raising it does produces a "weird" prefix, which should be simple to fix
although it likely will show up failures on dependent places e.g. File.expand_path ...

@kares kares self-assigned this Jun 15, 2018
kares added a commit to kares/jruby that referenced this issue Jun 17, 2018
refactored - unshared chdir/mkdir dir resolution bits
resolves jrubyGH-1026
@kares kares added this to the JRuby 9.2.1.0 milestone Jun 17, 2018
@kares kares closed this as completed in 9397aa8 Jun 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants