warbler
warbler copied to clipboard
running bundle exec in a runnable .war
How do I call bundle exec within a runnable .war file?
Our application here uses some local Git repos, so the data migration tool I've just written needs to be called with bundle exec, or else there will be require
's that fail.
However when I try java -jar thing.war -S bundle exec projects/remedium/document_loader
I get:
WARNING: `bundle exec' may drop out of the Warbler environment and into the system environment
Following files may not be writable, so sudo is needed:
uri:classloader:/WEB-INF/gems
uri:classloader:/WEB-INF/gems/bundler
uri:classloader:/WEB-INF/gems/gems
uri:classloader:/WEB-INF/gems/specifications
etc.
I tried doing a bundle install --binstubs
and including the bin directory in the .war file. I still get the same error. Or I can try java -jar thing.war -S bin/bundle exec projects/remedium/document_loader
, in which case I get:
bundler: not executable: projects/remedium/document_loader
ERROR: org.jruby.exceptions.RaiseException: (SystemExit) exit
Hello,
If the data migration tool that you wrote does not alter the application file structure, then you can change it to a rake
task. That way java -jar thing.war -S rake remedium:document_loader
will work.
When .war
is created, it bundles all the necessary libraries inside it. It cannot be altered afterwards. The way it works is: java unpacks the .war
contents into a temp directory, runs the code, and then deletes the exacted data. When doing bundle install --binstubs
, it will write them to a temp directory and then delete them. This is the reason why that warning exists.
Your git gems should be able to work provided you bundled them with :git
and not :local
directive inside them Gemfile.
@rsov Can you expand on what you mean by a "rake task"?
I mean, presumably --
task :document_loader do
sh 'document_loader'
end
...would fail in exactly the same way?
Is the document_loaded
a ruby script?
If so, put the source inside the rake task.
For example, here is one of the ones we have in our system:
lib/tasks/migrate.rake
namespace :migrate do
task :create_cases => :environment do
User.where(case_id: nil).each(&:create_case!)
end
end
java -jar app.war -S rake migrate:create_cases
will run the code inside the task
You can add require
on top of the file to load any libraries needed.
I can confirm that that works, although I'm not entirely sure what is going on here. Are we saying that we never need to type bundle exec rake
? That would definitely be an advantage I would like to have heard about before now...
Many thanks.
bundle exec rake
will execute the code in the context of current bundle. Meaning it will look up the version of rake specified by your application. Even though you may have multiple versions of rake installed on your system.
app.war
IS the bundle. It is an archive of all the dependencies and libraries. When doing java -jar app.war -S rake
there's only 1 version of rake, and it's the version that was specified by application when war
was created.
So yes, there's no need to use bundle exec
when executing commands from the war
application
So yes, there's no need to use bundle exec when executing commands from the war application
For rake, yes, okay. Otherwise there might well be. See the issue I raised above?