Giter VIP home page Giter VIP logo

cocaine's Introduction

Cocaine has been renamed to Terrapin

Please track further development on the Terrapin project page.

The final version of this gem simply requires Terrapin. It should not function any differently from previous versions.

Upgrading to Terrapin

Upgrading to Terrapin is expected to be as simple as replacing the Cocaine constant with Terrapin. That is

Cocaine::CommandLine.new("echo", "hello")

should become

Terrapin::CommandLine.new("echo", "hello")

and should continue to work fine.

License

Copyright 2011-2018 Jon Yurek and thoughtbot, inc. This is free software, and may be redistributed under the terms specified in the LICENSE file.

cocaine's People

Contributors

alindeman avatar arunagw avatar baldowl avatar bitgangsta avatar brixen avatar citrus avatar cthulhu666 avatar gabebw avatar gpg0 avatar hron avatar jjb avatar jneander avatar joshuaclayton avatar ka8725 avatar kirs avatar ktdreyer avatar mike-burns avatar miohana avatar nifarius avatar nixpulvis avatar radarek avatar sapslaj avatar sikachu avatar sshaw avatar tanner avatar tapajos avatar viseztrance avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cocaine's Issues

How to obtain command output with Cocaine?

Hello there,

Not sure if I'm missing something crazy obvious here.

If I run a simple command in terminal like: ls blah, then I get the following output: ls: blah: No such file or directory, given that the 'blah' does not exist in my case, of course.

Yet, when running Cocaine::CommandLine.new('ls', 'blah').run - I see no way to access the error message above. The ExitStatusError exception gives me a message like:

Cocaine::ExitStatusError: Command 'ls blah' returned 1. Expected 0
Here is the command output:


    from /Users/james/.rvm/gems/ruby-1.9.2-p320/gems/cocaine-0.5.4/lib/cocaine/command_line.rb:96:in `run'
    from (irb):3
    from /Users/james/.rvm/rubies/ruby-1.9.2-p320/bin/irb:16:in `<main>'

The output of the run command gives me nil.
And when using the :logger option, all I get is:

# Logfile created on 2014-05-21 06:27:32 +0100 by logger.rb/25413
I, [2014-05-21T06:27:32.336104 #81036]  INFO -- : Command :: ls blah

This is for a script I'm written, where I want to log the actual output of the failed command, otherwise I've got little to work with when reviewing logs later.

So, what to do?

Thanks for a great Gem by the way, it's otherwise a joy to use.

cheers,
James

Commit 94dbfa3 causes hanging on executing a process (OSX 10.7.4)

I just upgraded to cocaine 0.3.0 and tracked down code hanging from commit 94dbfa3. I'm running optipng to compress an image that I save using paperclip. Here's the output from paperclip after running convert. I added some puts() so you can see what's going on.

Executing convert /var/folders/5y/ln69d3vd6p39pdh7ksj6jkjr0000gn/T/jonathan20120831-8061-1mektr9.png

/var/folders/5y/ln69d3vd6p39pdh7ksj6jkjr0000gn/T/jonathan20120831-8061-1mektr920120831-8061-1coei2w.png in {"PATH"=>"/Users/jonathan/.rvm/gems/ruby-1.9.3-p125/bin:/Users/jonathan/Android/android-sdk-macosx/platform-tools:/Users/jonathan/Android/android-sdk-macosx/tools:/Users/jonathan/.rvm/gems/ruby-1.9.3-p125@global/bin:/Users/jonathan/.rvm/rubies/ruby-1.9.3-p125/bin:/Users/jonathan/.rvm/bin:/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:~/.rvm/bin:/usr/local/mongo/bin:/usr/local/git/bin:/usr/local/bin/"}

Finished

Executing optipng -zc1-9 -zm1-9 -zs0-2 -f0-5 /var/folders/5y/ln69d3vd6p39pdh7ksj6jkjr0000gn/T/jonathan20120831-8061-1mektr920120831-8061-1coei2w.png in {"PATH"=>"/Users/jonathan/.rvm/gems/ruby-1.9.3-p125/bin:/Users/jonathan/Android/android-sdk-macosx/platform-tools:/Users/jonathan/Android/android-sdk-macosx/tools:/Users/jonathan/.rvm/gems/ruby-1.9.3-p125@global/bin:/Users/jonathan/.rvm/rubies/ruby-1.9.3-p125/bin:/Users/jonathan/.rvm/bin:/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:~/.rvm/bin:/usr/local/mongo/bin:/usr/local/git/bin:/usr/local/bin/"}

The last command hangs. If I run the command myself in a console, it works fine. If I bump down to 2cfec9c, it works fine.

Cocaine 0.3.0 works great on my Mountain Lion 10.8.1 Macbook Pro, but our build agents are on Mac Minis that are still on Lion, OS X 10.7.4.

@jyurek, any thoughts on what could be causing this? If I do ps aux | grep optipng, I see the optipng process there but it's not doing anything.

License missing from gemspec

RubyGems.org doesn't report a license for your gem. This is because it is not specified in the gemspec of your last release.

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Including a license in your gemspec is an easy way for rubygems.org and other tools to check how your gem is licensed. As you can imagine, scanning your repository for a LICENSE file or parsing the README, and then attempting to identify the license or licenses is much more difficult and more error prone. So, even for projects that already specify a license, including a license in your gemspec is a good practice. See, for example, how rubygems.org uses the gemspec to display the rails gem license.

There is even a License Finder gem to help companies/individuals ensure all gems they use meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough issue that even Bundler now generates gems with a default 'MIT' license.

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue with a nice message. In either case, I'll follow up. Thanks for your time!

Appendix:

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), GitHub has created a license picker tool. Code without a license specified defaults to 'All rights reserved'-- denying others all rights to use of the code.
Here's a list of the license names I've found and their frequencies

p.s. In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :). See the previous link or my blog post about this project for more information.

Rails 4 Paperclip 4.1 Ruby 2.1.1 Cover Paperclip::Errors::NotIdentifiedByImageMagickError

I was merrily chatting to my self over on #28 when i realised the ticket was closed. so reposted here. Appologies if that was the wrong thing to do.

I'm using paperclip 4.1 and rails 4.0.2 & ruby 2.1.1 - i get the error

Cover Paperclip::Errors::NotIdentifiedByImageMagickError

I am running on osx 10.9, and i've checked my imagemagick by doing:

➜  rails git:(aa) ✗ which identify                          
/usr/local/bin/identify

I've got

Paperclip.options[:command_path] = "/usr/local/bin/"

set right at the top of my development.rb environment

Somebody saved themselves with this in the application.rb:

``Paperclip.options[:command_path] = "/usr/local/bin/identify"`

but that didn't work for me.

I saw that somebody found running:

brew install libtool --universal
brew link libtool
or 
brew unlink libtool && brew link libtool
Unlinking /usr/local/Cellar/libtool/2.4.2... 0 symlinks removed
Linking /usr/local/Cellar/libtool/2.4.2... 17 symlinks created

helped them out, but it didn't make any difference for me.

I tried

brew install --force jpeg
brew update && brew upgrade `brew outdated`

from thoughtbot/paperclip#1205

which all happened 1st time except:
Error: Permission denied - /usr/local/Cellar/libiconv/1.14

Ill check that out and report back.

So i got past that with
sudo chown -R whoami /usr/local but the error persist.

Just found thoughtbot/paperclip#1289 ticket, where some people had issues with a custom geometry method. I don't have one of those, so not that.

I turned on the logs

Paperclip.options[:log] = true 
Paperclip.options[:log_command] = true 

and here is the output:

Started PATCH "/helm/providers/10-test-87" for 127.0.0.1 at 2014-05-15 15:57:29 +1000
Processing by Helm::ProvidersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"NsoEuLpef3Lst9T6QRSRO4N61Haixt3HwIPO9vql36s=", "provider"=>{"name"=>"test 87", "description"=>"", "address"=>"Level 1, 27 Belgrave Street", "suburb"=>"Manly", "state"=>"New South Wales", "postcode"=>"2095", "phone"=>"61424366468", "website"=>"http://www.theraceguide.com.au", "cover"=>#<ActionDispatch::Http::UploadedFile:0x00000108491c78 @tempfile=#<Tempfile:/var/folders/qt/cvfl_0892yb625qkq7ppt14h0000gq/T/RackMultipart20140515-32533-1pm40me>, @original_filename="happydog.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"provider[cover]\"; filename=\"happydog.jpg\"\r\nContent-Type: image/jpeg\r\n">, "delete_cover"=>"0"}, "commit"=>"Save Settings", "id"=>"10-test-87"}
  AdminUser Load (0.8ms)  SELECT "admin_users".* FROM "admin_users" WHERE "admin_users"."id" = 2 ORDER BY "admin_users"."id" ASC LIMIT 1
  User Load (0.7ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 18 ORDER BY "users"."id" ASC LIMIT 1
  Provider Load (4.1ms)  SELECT "providers".* FROM "providers" WHERE "providers"."id" = $1 ORDER BY "providers"."id" ASC LIMIT 1  [["id", 10]]
   (0.2ms)  BEGIN
Command :: file -b --mime-type '/var/folders/qt/cvfl_0892yb625qkq7ppt14h0000gq/T/1ac677d46634f25fd48ab67499e3d1e720140515-32533-17br10g'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/qt/cvfl_0892yb625qkq7ppt14h0000gq/T/c7528087ad463bffc45a3f587db01e0420140515-32533-jzu2d3[0]' 2>/dev/null
[paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/qt/cvfl_0892yb625qkq7ppt14h0000gq/T/c7528087ad463bffc45a3f587db01e0420140515-32533-jzu2d3[0]' 2>/dev/null
[paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
Command :: file -b --mime-type '/var/folders/qt/cvfl_0892yb625qkq7ppt14h0000gq/T/eebe1f6bcaba7765c8e20cc93c4fd8b420140515-32533-sfvsxj'

NoMethodError - undefined method `tty?' for ActiveSupport::BufferedLogger

On the 19th we upgraded our cocaine gem version from 0.4.0 to 0.4.1. We then started getting this error in our application...

NoMethodError (undefined method tty?' for #<ActiveSupport::BufferedLogger:0x00000100a5f540>): cocaine (0.4.1) lib/cocaine/command_line.rb:98:incolored'
cocaine (0.4.1) lib/cocaine/command_line.rb:75:in run' paperclip (2.7.1) lib/paperclip.rb:102:inrun'
paperclip (2.7.1) lib/paperclip/geometry.rb:22:in from_file' paperclip (2.7.1) lib/paperclip/thumbnail.rb:35:ininitialize'
paperclip (2.7.1) lib/paperclip/processor.rb:33:in new' paperclip (2.7.1) lib/paperclip/processor.rb:33:inmake'
paperclip (2.7.1) lib/paperclip/attachment.rb:441:in block in post_process_style' paperclip (2.7.1) lib/paperclip/attachment.rb:440:ineach'
paperclip (2.7.1) lib/paperclip/attachment.rb:440:in inject' paperclip (2.7.1) lib/paperclip/attachment.rb:440:inpost_process_style'
paperclip (2.7.1) lib/paperclip/attachment.rb:433:in block in post_process_styles' paperclip (2.7.1) lib/paperclip/attachment.rb:432:ineach'
paperclip (2.7.1) lib/paperclip/attachment.rb:432:in post_process_styles' paperclip (2.7.1) lib/paperclip/attachment.rb:425:inblock (2 levels) in post_process'
paperclip (2.7.1) lib/paperclip/callback_compatibility.rb:23:in call' paperclip (2.7.1) lib/paperclip/callback_compatibility.rb:23:inrun_paperclip_callbacks'
paperclip (2.7.1) lib/paperclip/attachment.rb:424:in block in post_process' paperclip (2.7.1) lib/paperclip/callback_compatibility.rb:23:incall'
paperclip (2.7.1) lib/paperclip/callback_compatibility.rb:23:in run_paperclip_callbacks' paperclip (2.7.1) lib/paperclip/attachment.rb:423:inpost_process'
paperclip (2.7.1) lib/paperclip/attachment.rb:120:in assign' paperclip (2.7.1) lib/paperclip.rb:349:inblock in has_attached_file'

We are running rails v 2.3.14. Please advise on how to resolve this.
Thanks!

posix-runner won't accept timeout

Currently posix-runner runs the command like this

POSIX::Spawn.spawn(*args)

posix-runner actually supports timeout option, but you can't pass it in like that. You gotta run it like this instead

POSIX::Spawn::Child.new(*args)

Difference being that the latter will buffer all the process output instead of streaming it. This is not a big deal for most use cases.

So in order to make it possible to use timeout in cocaine, I propose one of two solutions, which I can work on: either change current posix-runner, or add a new runner: posix-child-runner. Please give me the green light on one of these and I'll try to submit a patch soon. It will also help me switch Skeptick to use cocaine internally: maxim/skeptick#3

How can i get the pid of opening process?

Commonly we use ctrl+c to terminate a process,but I've googled,it's not STDIN ,but using pid to terminate the process.
There is no pid returned from the run,seems not exposed.

Can't pass UTF-8 file names from paperclip

Because the base string literals are US-ASCII and trying to interpolate UTF-8 strings into it?

Let me know if you need more information.

ArgumentError: invalid byte sequence in US-ASCII
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:121:in `gsub'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:121:in `block in interpolate'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:120:in `each'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:120:in `inject'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:120:in `interpolate'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:66:in `command'
[GEM_ROOT]/gems/cocaine-0.4.2/lib/cocaine/command_line.rb:74:in `run'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/helpers.rb:31:in `run'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/processor.rb:39:in `convert'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/thumbnail.rb:77:in `make'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/processor.rb:33:in `make'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:410:in `block in post_process_style'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:409:in `each'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:409:in `inject'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:409:in `post_process_style'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:402:in `block in post_process_styles'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:401:in `each'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:401:in `post_process_styles'
[GEM_ROOT]/gems/paperclip-3.3.0/lib/paperclip/attachment.rb:394:in `block (2 levels) in post_process'

Gem not available to install

Not sure if this is the right place to log this - please scold me if it's not.

My bundle install is failing with this error:

An error occurred while installing cocaine (0.3.2), and Bundler cannot continue.
Make sure that gem install cocaine -v '0.3.2' succeeds before bundling.

Running gem install cocaine -v '0.3.2' results in:

ERROR: Could not find a valid gem 'cocaine' (= 0.3.2) in any repository
ERROR: Possible alternatives: cocaine

On this page: https://rubygems.org/gems/cocaine, the link to download the cocaine gem (https://rubygems.org/downloads/cocaine-0.3.2.gem - redirects to https://s3.amazonaws.com/production.s3.rubygems.org/gems/cocaine-0.3.2.gem) is broken; it results in:

<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>gems/cocaine-0.3.2.gem</Key>
<RequestId>0D60305A44D07C89</RequestId>
<HostId>
r39FLKYs/ElHqoAPMuDd8UAaSjyAzAWnfZweyCJUwm1r5bf9q0EwHiWrKd/w4o13
</HostId>
</Error>

Not getting CommandNotFound error

Hi there, just thought I'd let you know I was getting a nil return code (and the usual message regarding non-matching return codes) rather than the CommandNotFound. Adding a manual path to find the command (it was pdftk in /usr/local/bin on Mac) via the Paperclip configuration it returned 0 and all was well. I spent a bit of time trying to figure out what was wrong because I wasn't expecting that it couldn't actually find the command :)

Not sure where to look in terms of finding a fix for this that would properly inform the user.

Interpolated arguments not working as intended

First, thanks for the gem!

Please have a look at the following gist:

[1] pry(main)> require 'cocaine'
=> true
[2] pry(main)> parse = Cocaine::CommandLine.new(
[2] pry(main)*   "knife job start",
[2] pry(main)*   %q|:job -s :query --timeout 1200 --quorum 10% --no-wait|,
[2] pry(main)*   swallow_stderr: true
[2] pry(main)* )
=> #<Cocaine::CommandLine:0x007ffb72369190
 @binary="knife job start",
 @environment={},
 @expected_outcodes=[0],
 @logger=nil,
 @options={},
 @params=":job -s :query --timeout 1200 --quorum 10% --no-wait",
 @runner=#<Cocaine::CommandLine::PosixRunner:0x007ffb722396d0>,
 @runner_options={},
 @swallow_stderr=true>
[3] pry(main)> parse.command(job: 'uptime', query: 'name:loadbalancer-i*', swallow_stderr: true)
=> "knife job start 'uptime' -s 'name:loadbalancer-i*' --timeout 1200 --quorum 10% --no-wait 2>/dev/null"
[4] pry(main)> parse.run
Cocaine::ExitStatusError: Command 'knife job start :job -s :query --timeout 1200 --quorum 10% --no-wait 2>/dev/null' returned 100. Expected 0
Here is the command output:

invalid search query: ':query'
from /Users/scalp/.rvm/gems/ruby-2.2.1@gzbot/gems/cocaine-0.5.7/lib/cocaine/command_line.rb:92:in `run'`

Where I would expect parse.run to run the following:

"knife job start 'uptime' -s 'name:loadbalancer-i*' --timeout 1200 --quorum 10% --no-wait 2>/dev/null"

it appears to run without interpolating:

Cocaine::ExitStatusError: Command 'knife job start :job -s :query --timeout 1200 --quorum 10% --no-wait 2>/dev/null' returned 100. Expected 0

Any idea @jyurek ?

Thanks in advance!

Suggest to prioritize supplemental_path before ENV path

Apologies in advance if I'm missing something there...

In command_line.rb, line 12, currently this:

@supplemental_environment['PATH'] = [ENV['PATH'], *supplemental_path].join(File::PATH_SEPARATOR)

I propose to switch the order of supplemental_path and ENV path, like so:

@supplemental_environment['PATH'] = [*supplemental_path, ENV['PATH']].join(File::PATH_SEPARATOR)

The reason for this change is to more closely mimic how Window/Linux/Mac cmd shells behave, i.e. your CommandLine.path takes first priority over your env path.

(The exact problem I had was C:\Windows\System32\convert.exe was trumping C:\Program Files\ImageMagick\convert.exe when running paperclip, and seems there's no way currently to force Cocaine to look somewhere other than system path at a higher priority)

Thanks for the great gem.

Multi threading support?

Hey there,

I'm a heavy user of Sidekiq and Paperclip. We get an absolute ton of errors come through like this:

Errno::EINVAL: Invalid argument - identify -format %wx%h '/tmp/stream20120911-6678-1uwdq83.txt[0]'

I'm talking thousands. While in theory I could be running 1000 workers (which would be ideal as I need to process just over 1m images) I find that things run slightly smoother if I run just 50.

Disclaimer: Now I'm a total amateur, really my knowledge stops dead at Ruby/Rails, I know my way around a shell but I wont be winning any awards any time soon.

I never used to get this error with Resque and Paperclip, and so I'm wondering if its a volume thing (back then we only ran 20 workers) and they all worked very well, this was never an issue. Is there something at play here? I wonder if cocaine is struggling to speak to ImageMagick quick enough, (or something, I know thats not too technical!).

I don't know if you recall but I actually asked this question before and you pointed me at a certain commit:

gem "cocaine", :git => "http://github.com/thoughtbot/cocaine.git", :ref => "26a64a9d67a6fcac76349c13167dcddb6596f702"

Would appreciate any pointers... is where my gemfile pointed still valid? I recall you were pondering bumping the version.

Thanks in advance, getting these images processing would be amazing!

Regards,

Geoff

Optimization proposal for Cocaine::CommandLine::PosixRunner.available?

Hi.

I was profiling my app and I noticed that Cocaine::CommandLine::PosixRunner.available? method is taking relatively long time. I looked at the sources and it looks like this:

def self.available?
  require 'posix/spawn'
  true
rescue LoadError
  false
end

This method calls require "posix/spawn" every time is called. This makes it quite slow. The worst case scenario is when gem "posix/spawn" is not available (for example in my environment). require in this case is the slowest (because every time it tries to find file in known paths).

> puts Benchmark.measure { 100.times { Cocaine::CommandLine::PosixRunner.available? } }
  0.140000   0.100000   0.240000 (  0.241006)

What is also important is that you can't actually predict what is performance of require method. For example Rails framework overrides it with it's own implementation and performance is quite different between 4.0.2 and 4.2.0 version.

> puts Rails::VERSION::STRING, Benchmark.measure { 100.times { Cocaine::CommandLine::PosixRunner.available? } }
4.0.2
  0.150000   0.100000   0.250000 (  0.257626)
> puts Rails::VERSION::STRING, Benchmark.measure { 100.times { Cocaine::CommandLine::PosixRunner.available? } }
4.2.0
  0.320000   0.110000   0.430000 (  0.442123)

I suggest to add simple memoization to prevent calling require on every call like this (we can't use ||= operator because of false value):

diff --git a/lib/cocaine/command_line/runners/posix_runner.rb b/lib/cocaine/command_line/runners/posix_runner.rb
index 9cc6a63..2418c4a 100644
--- a/lib/cocaine/command_line/runners/posix_runner.rb
+++ b/lib/cocaine/command_line/runners/posix_runner.rb
@@ -4,10 +4,15 @@ module Cocaine
   class CommandLine
     class PosixRunner
       def self.available?
-        require 'posix/spawn'
-        true
-      rescue LoadError
-        false
+        return @available if [email protected]?
+
+        @available =
+          begin
+            require 'posix/spawn'
+            true
+          rescue LoadError
+            false
+          end
       end

       def self.supported?

In this case only first call will be relatively slow (which is reasonable) but other will be much faster:

> bm { Cocaine::CommandLine::PosixRunner.available? }
  0.020000   0.000000   0.020000 (  0.015084)
> bm { 100.times { Cocaine::CommandLine::PosixRunner.available? } }
  0.000000   0.000000   0.000000 (  0.000019)

Incorrect replacement of command options with same prefix

While working around this I came across the following:

line  = Cocaine::CommandLine.new("echo", ":file1 :file11")
puts line.run(:file1 => "one", :file11 => "eleven") # echo 'one' 'one'1

After a wee bit of head scratching and source browsing I realized the problem --and the solution: wrap my interpolations with :{}. I didn't see this mentioned in the docs so my concern is that it's an undocumented feature and may be removed at some point. Please clarify.

Also why not just throw a word boundary at the end of the regex? I can submit a patch if needed.

Deadlock when spawned process writes to stderr

When a process spawned by Cocaine writes sufficient data to stderr, both the processes will hang indefinitely. This is because Cocaine is blocked reading from stdin, while the process eventually blocks writing to stderr when the internal buffer for the pipe becomes full.

The issue can be reproduced with the following trivial script:

#!/usr/bin/env ruby

1000.times do
  STDERR.puts "*" * 1000
end

Called via Cocaine, it blocks:

Cocaine::CommandLine.new("./hang.rb").run # hangs forever

Using strace, you'll be able to see that the invoked process is blocked in a write syscall on the STDERR file descriptor. The other giveaway is that this does not block:

Cocaine::CommandLine.new("./hang.rb", "", swallow_stderr: true).run

Obviously that's not ideal, since we may want to capture both stdout and stderr.

This Zendesk blog post touches on the issue briefly in the section entitled "Bonus round: avoiding deadlocks." The solution is to avoid making blocking calls like read, and using IO::select in a loop to figure out which file descriptors are ready to be read from. Here is how it is implemented in the subprocess gem.

I see potentially fixing this in Multipipe#read, or by adding a new runner that uses the subprocess gem. Thoughts?

Use RbConfig instead of deprecated Config

When checking for RbConfig::CONFIG['host_os'] it is recommended you use RbConfig instead.

On Ruby 1.9.3 and head (trunk) you receive a warning because of that:

Use RbConfig instead of obsolete and deprecated Config.

How to deal with paths containing special characters?

Do path names to be manually quoted, or will Cocaine take care of that? Currently passing #{my_filename} where my_filename = "test(c).c" then it won’t be found on the command line.

Do I need to manually do '#{my_filename}'?

Cocaine gem giving error

When i'm adding gem "cocaine", "0.3.2" and run this application.then getting this error.....

"/usr/local/lib/ruby/gems/1.9.1/gems/coffee-filter-0.1.1/lib/coffee-filter/coffeescript.rb:8:in <module:Coffeescript>': undefined methodlazy_require' for Coffee::Filter::Coffeescript:Module (NoMethodError)
from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-filter-0.1.1/lib/coffee-filter/coffeescript.rb:5:in <module:Filter>' from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-filter-0.1.1/lib/coffee-filter/coffeescript.rb:4:inmodule:Coffee'
from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-filter-0.1.1/lib/coffee-filter/coffeescript.rb:3:in <top (required)>' from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:251:inrequire'
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:251:in block in require' from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:236:inload_dependency'
from /usr/local/lib/ruby/gems/1.9.1/gems/activesupport-3.2.12/lib/active_support/dependencies.rb:251:in require' from /usr/local/lib/ruby/gems/1.9.1/gems/coffee-filter-0.1.1/lib/coffee-filter.rb:1:in<top (required)>'
from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:68:in require' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:68:inblock (2 levels) in require'
from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:66:in each' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:66:inblock in require'
from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:55:in each' from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/runtime.rb:55:inrequire'
from /usr/local/lib/ruby/gems/1.9.1/gems/bundler-1.2.3/lib/bundler.rb:128:in require' from /home/pht-20/projects/my_family_histree/config/application.rb:13:in<top (required)>'
from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:53:in require' from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:53:inblock in <top (required)>'
from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:50:in tap' from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.2.12/lib/rails/commands.rb:50:in<top (required)>'
from script/rails:6:in require' from script/rails:6:in

'

Command Time out

Howdy, I was wondering how hard it would be to extend this library to include a timeout feature. When set it would raise an exception if a command took longer than the allotted amount of time (a parameter).

It would also need to detach or kill the subshell (not sure what the correct action is there, perhaps this should be a parameter too).

cocaine adds [0] at the end of the command

I'm using paperclip 4.2.1, cocaine 0.5.7
I get this command executed:

[INFO ] Command :: PATH=/usr/local/bin/ffmpeg:$PATH; file -b --mime '/var/folders/43/t8s11k6d145c4wtwfpnbxh640000gn/T/56cf3d660d43b439e0cc2106d426e71320150410-32412-eq25u1.png'
[INFO ] Command :: PATH=/usr/local/bin/ffmpeg:$PATH; identify -format '%wx%h,%[exif:orientation]' '/var/folders/43/t8s11k6d145c4wtwfpnbxh640000gn/T/56cf3d660d43b439e0cc2106d426e71320150410-32412-qpsg0.png[0]' 2>/dev/null
[INFO ] [paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
[INFO ] Command :: PATH=/usr/local/bin/ffmpeg:$PATH; identify -format '%wx%h,%[exif:orientation]' '/var/folders/43/t8s11k6d145c4wtwfpnbxh640000gn/T/56cf3d660d43b439e0cc2106d426e71320150410-32412-qpsg0.png[0]' 2>/dev/null
[INFO ] [paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
[INFO ] Command :: PATH=/usr/local/bin/ffmpeg:$PATH; identify -format '%wx%h,%[exif:orientation]' '/var/folders/43/t8s11k6d145c4wtwfpnbxh640000gn/T/56cf3d660d43b439e0cc2106d426e71320150410-32412-qpsg0.png[0]' 2>/dev/null
[INFO ] [paperclip] An error was received while processing: #<Paperclip::Errors::NotIdentifiedByImageMagickError: Paperclip::Errors::NotIdentifiedByImageMagickError>
#<Paperclip::Attachment:0x007fda88fde4f8 @name=:profile_picture, @instance=#<User id: nil, email: "[email protected]", encrypted_password: "$2a$10$...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, firstname: "Golf", lastname: nil, profile_picture_file_name: "Capture_d’écran_2014-03-13_à_16.42.58.png", profile_picture_content_type: "image/png", profile_picture_file_size: 14077, profile_picture_updated_at: "2015-04-10 08:12:35", cover_picture_file_name: nil, cover_picture_content_type: nil, cover_picture_file_size: nil, cover_picture_updated_at: nil, provider: nil, uid: nil, username: nil, oauth_token: nil, oauth_secret: nil, oauth_expires_at: nil, city: nil, country_id: nil, from_country_id: nil, club_id: 12643, handicap: nil, work: nil, admin: false, points: 0, latitude: nil, longitude: nil, job: nil, sex: nil, authentication_token: nil, enable_notifications: true, agency_id: nil, birthdate: nil, notification_token: nil, mixpanel_distinct_id: nil, slug: nil, is_club: true>, @options={:convert_options=>{}, :default_style=>:original, :default_url=>"/:attachment/:style/missing.png", :escape_url=>true, :restricted_characters=>/[&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/, :filename_cleaner=>nil, :hash_data=>":class/:attachment/:id/:style/:updated_at", :hash_digest=>"SHA1", :interpolator=>Paperclip::Interpolations, :only_process=>[], :path=>":rails_root/public:url", :preserve_files=>false, :processors=>[:thumbnail], :source_file_options=>{}, :storage=>:filesystem, :styles=>{:thumb=>"50x50#", :fit=>"250x250#", :resized=>"600x600>"}, :url=>"/system/:class/:attachment/:id_partition/:style/:filename", :url_generator=>Paperclip::UrlGenerator, :use_default_time_zone=>true, :use_timestamp=>true, :whiny=>true, :validate_media_type=>true, :check_validity_before_processing=>true}, @post_processing=true, @queued_for_delete=[], @queued_for_write={:original=>Paperclip::AttachmentAdapter: Capture_d’écran_2014-03-13_à_16.42.58.png}, @errors={:processing=>["Paperclip::Errors::NotIdentifiedByImageMagickError", "Paperclip::Errors::NotIdentifiedByImageMagickError", "Paperclip::Errors::NotIdentifiedByImageMagickError"]}, @dirty=true, @interpolator=Paperclip::Interpolations, @url_generator=#<Paperclip::UrlGenerator:0x007fda88fde318 @attachment=#<Paperclip::Attachment:0x007fda88fde4f8 ...>, @attachment_options={:convert_options=>{}, :default_style=>:original, :default_url=>"/:attachment/:style/missing.png", :escape_url=>true, :restricted_characters=>/[&$+,\/:;=?@<>\[\]\{\}\|\\\^~%# ]/, :filename_cleaner=>nil, :hash_data=>":class/:attachment/:id/:style/:updated_at", :hash_digest=>"SHA1", :interpolator=>Paperclip::Interpolations, :only_process=>[], :path=>":rails_root/public:url", :preserve_files=>false, :processors=>[:thumbnail], :source_file_options=>{}, :storage=>:filesystem, :styles=>{:thumb=>"50x50#", :fit=>"250x250#", :resized=>"600x600>"}, :url=>"/system/:class/:attachment/:id_partition/:style/:filename", :url_generator=>Paperclip::UrlGenerator, :use_default_time_zone=>true, :use_timestamp=>true, :whiny=>true, :validate_media_type=>true, :check_validity_before_processing=>true}>, @source_file_options={}, @whiny=true, @normalized_styles={:thumb=>#<Paperclip::Style:0x007fda81732dd8 @name=:thumb, @attachment=#<Paperclip::Attachment:0x007fda88fde4f8 ...>, @geometry="50x50#", @format=nil, @other_args={}>, :fit=>#<Paperclip::Style:0x007fda81732c20 @name=:fit, @attachment=#<Paperclip::Attachment:0x007fda88fde4f8 ...>, @geometry="250x250#", @format=nil, @other_args={}>, :resized=>#<Paperclip::Style:0x007fda81732b08 @name=:resized, @attachment=#<Paperclip::Attachment:0x007fda88fde4f8 ...>, @geometry="600x600>", @format=nil, @other_args={}>}, @file=Paperclip::AttachmentAdapter: Capture_d’écran_2014-03-13_à_16.42.58.png>

You can see the [0] at the end of: 56cf3d660d43b439e0cc2106d426e71320150410-32412-qpsg0.png[0]

I think that is the cause of the following error:

ActiveRecord::RecordInvalid - Validation failed: Profile picture Paperclip::Errors::NotIdentifiedByImageMagickError, Profile picture Paperclip::Errors::NotIdentifiedByImageMagickError, Profile picture Paperclip::Errors::NotIdentifiedByImageMagickError:
  activerecord (4.1.9) lib/active_record/validations.rb:57:in `save!'

Cocaine::ExitStatusError when I switch from paperclip-ffmpeg 1.0.1 to 1.2.0

Everything is fine with the paperclip-ffmpeg version 1.0.1 but when I switch to version 1.2.0 I get this stack:

Command :: PATH=/usr/local/bin/ffmpeg:$PATH file -b --mime '/var/folders/43/t8s11k6d145c4wtwfpnbxh640000gn/T/6c84cbd30cf9350a990bad2bcc1bec5f20150205-9509-104fieg.MOV'
sh: -c: line 0: syntax error near unexpected token `then'
sh: -c: line 0: `PATH=/usr/local/bin/ffmpeg:$PATH if command -v ffprobe 2>/dev/null; then echo "true"; else echo "false"; fi'
Could not log "process_action.action_controller" event. Encoding::UndefinedConversionError: "\xEA" from ASCII-8BIT to UTF-8 [...]

Cocaine::ExitStatusError - Command 'PATH=/usr/local/bin/ffmpeg:$PATH if command -v ffprobe 2>/dev/null; then echo "true"; else echo "false"; fi' returned 2. Expected 0
Here is the command output:

:
  cocaine (0.5.5) lib/cocaine/command_line.rb:92:in `run'
  paperclip-ffmpeg (1.2.0) lib/paperclip_processors/ffmpeg.rb:249:in `detect_command'
  paperclip-ffmpeg (1.2.0) lib/paperclip_processors/ffmpeg.rb:233:in `detect_ffprobe_or_avprobe'
  paperclip-ffmpeg (1.2.0) lib/paperclip_processors/ffmpeg.rb:183:in `identify'
  paperclip-ffmpeg (1.2.0) lib/paperclip_processors/ffmpeg.rb:36:in `initialize'
  paperclip (4.2.1) lib/paperclip/processor.rb:33:in `make'
  paperclip (4.2.1) lib/paperclip/attachment.rb:522:in `block in post_process_style'
  paperclip (4.2.1) lib/paperclip/attachment.rb:521:in `post_process_style'
  paperclip (4.2.1) lib/paperclip/attachment.rb:512:in `block in post_process_styles'
  paperclip (4.2.1) lib/paperclip/attachment.rb:511:in `post_process_styles'
  paperclip (4.2.1) lib/paperclip/attachment.rb:503:in `block (2 levels) in post_process'

If i try to execute the command in my terminal:

$ PATH=/usr/local/bin/ffmpeg:$PATH if command -v ffprobe 2>/dev/null; then echo "true"; else echo "false"; fi
bash: syntax error near unexpected token `then'

I'm on a mac

Cannot open command as pipe

There does not seem to be able to execute command as pipe source or sink. Can this feature to be added?

Idea would be that you could get a file handle that you could for reading or writing.

ENV not fully replicated to commands

With the change to Runners, the ENV isn't always replicated in full to commands. Only the changes are passed to the runner, and they are not merged with the full ENV before they're executed.

ANSI color codes should check for tty first

When using ANSI color codes, the correct thing to do is check if the output device is a tty? because stdout is often redirected to a file. For example:

logger = Logger.new(STDOUT)
logger.use_ansi = STDOUT.tty?

When I enable command logging through Paperclip, syslog fills up with this:

Oct 15 20:26:49 dt3 sidekiq[24443]: #033[32mCommand#033[0m :: file -b --mime :file

Can't install Cocaine Gem

andyl@ison ~> gem install cocaine
ERROR: Could not find a valid gem 'cocaine' (>= 0) in any repository
ERROR: Possible alternatives: cocaine
aleak@ison ~> gem list cocaine --remote

*** REMOTE GEMS ***

cocaine (0.3.2)
andyl@ison ~> gem install cocaine 0.3.2
ERROR: Could not find a valid gem 'cocaine' (>= 0) in any repository
ERROR: Possible alternatives: cocaine
ERROR: Could not find a valid gem '0.3.2' (>= 0) in any repository
andyl@ison ~>

How to deal with command line option that takes a list of arguments

To be specific, I couldn't find a way to run the following command:

pdftk in1.pdf in2.pdf in3.pdf cat output out.pdf

with a line like this:

@line = Cocaine::CommandLine.new("pdftk", ":in cat output :out")

calling

@line.run(:in => "in1.pdf in2.pdf", :out => "out.pdf") 

will not work, because the produced command looks like this:

pdftk 'in1.pdf in2.pdf in3.pdf' cat output 'out.pdf'

and pdftk takes the entire first string as a file name (which sure doesn't exist).

Is there any option / way to go I missed?

Shellquotes not working

Shell quotes not working

I'm not sure why, and it cost me a few days a year ago . But when trying to use paperclip and a processor for ghostscript I have to overwrite the shellquotes. I have found this fix on the internet and I believe it is used quite sometime. This week I updated a lot of gems and I was hoping that I good remove this dirty fix..

  # receives a pdf to convert to png
  has_attached_file :poster,
    :styles => { :thumb => ['180', :png], :medium => ['x720', :png] },
    :processors => [:ghostscript, :thumbnail],
    :validate_media_type => false,
    :convert_options => { :all => '-colorspace CMYK -flatten -quality 100 -density 8' }
module Paperclip
  class Ghostscript < Processor

    attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options, :source_file_options

    def initialize file, options = {}, attachment = nil
      super
      @file                = file
      @format              = options[:format]

      @current_format      = File.extname(@file.path)
      @basename            = File.basename(@file.path, @current_format)
    end

    def make
      src = @file
      dst = Tempfile.new([@basename, @format ? ".#{@format}" : ''])
      dst.binmode

      begin
        parameters = []
        parameters << '-dNOPAUSE -dBATCH -sDEVICE=pngalpha -r144 -dUseCIEColor'
        parameters << '-sOutputFile=:dest'
        parameters << ':source'

        parameters = parameters.flatten.compact.join(' ').strip.squeeze(' ')

        success = Paperclip.run('gs', parameters, :source => "#{File.expand_path(src.path)}", :dest => File.expand_path(dst.path))
      rescue PaperclipCommandLineError => e
        raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
      end
      dst
    end
  end
end

But unfortunately I get the dreaded NotIdentifiedByImageMagick error. But I scouerd the internet and found this which fixes my problem;

Cocaine::CommandLine.module_eval do

  def run(interpolations = {})
    @exit_status = nil
    begin
      full_command = command(interpolations)
      log("#{colored("Command")} :: #{full_command}")
      @output = execute(full_command)
    rescue Errno::ENOENT => e
      raise Cocaine::CommandNotFoundError, e.message
    ensure
      @exit_status = $?.respond_to?(:exitstatus) ? $?.exitstatus : 0
    end

    if @exit_status == 127
      raise Cocaine::CommandNotFoundError
    end

    unless @expected_outcodes.include?(@exit_status)
      message = [
        "Command '#{full_command}' returned #{@exit_status}. Expected #{@expected_outcodes.join(", ")}",
        "Here is the command output: STDOUT:\n", command_output,
        "\nSTDERR:\n", command_error_output
      ].join("\n")
      raise Cocaine::ExitStatusError, message
    end

    command_output
  end

  private
  def interpolate(pattern, interpolations)
    interpolations = stringify_keys(interpolations)

    pattern.gsub(/:\{?(\w+)\b\}?/) do |match|

      key = match.tr(":{}", "")

      if interpolations.key?(key)
        "'#{interpolations[key]}'"
      else
        match
      end
    end
  end
end

Well the upperpart is just that cocaine uses my interpolate but why is this still a problem using paperclip?

Thread safety?

Is it safe to assume that cocaine is not meant to be used in a thread safe environment? with_modified_environment looks unsafe.

Use RbConfig instead of obsolete and deprecated Config.

Hi Guys,

While i work with his gem, i got the following error:

/path/gem/cocaine-0.2.0/lib/cocaine/command_line.rb:94: Use RbConfig instead of obsolete and deprecated Config.

This error appears when i executed my test suite with cucumber

This gem is use for paperclip

My current environment is:
Ruby 1.9.3
Rails 3.1.3

I solved the issue with the suggestion that appear on console, in others words i change the function Config by RbConfig at line indicated

I hope this help he for better his gems

Documentation on usage during testing (how-to mock, etc)

I'm looking for some guidance on how best to test usage of cocaine in specs...

Mainly, I've got some calls that call multiple command line functions in a row. Usually the spec runs fine, but sometimes (especially under guard/drb) the cocaine dummy backend seems to get lost and it fails because it is trying to run commands that don't work in tests.

I've mostly figured out how to mock/expect around a single call, but I'm having trouble when expecting multiple calls.

Thanks.

How to combine commands?

How do you combine commands?

ls = Cocaine::CommandLine.new('ls', ':dir').command(dir: '/foo/bar/baz')
ssh = Cocaine::CommandLine.new('ssh', ':server :command').command(server: 'root@my-server', command: ls)
ssh_2 = Cocaine::CommandLine.new('ssh', %(:server "#{ls}")).command(server: 'root@my-server')

puts ls # ls '/foo/bar/baz'
puts ssh # ssh 'root@my-server' 'ls '\''/foo/bar/baz'
puts ssh_2 # ssh 'root@my-server' "ls '/foo/bar/baz'"   // But there could be problems with the double qoute

0.4.0 breaks paperclip and imagemagick

Hi guys,

I did an bundle update today and seems like Cocaine 0.4.0 breaks paperclip & imagemagick on my rails app :

/tmp/xxxxxxx is not recognized by the 'identify' command.

identify: no decode delegate for this image format `' @ error/constitute.c/ReadImage/544.

paperclip 2.7.1
rails 3.2.3
ImageMagick 6.7.7-6 on Mountain Lion

Cannot load such file -- posix/spawn

Since 0.5.6 I get "cannot load such file -- posix/spawn" when using the gem with paperclip.

This change changed rescue LoadError to simply rescue. But LoadError is not a StandardError. Hence the detection is broken.

Jruby 1.6.7.2 and Cocaine 0.3.2: Errno::ECHILD: No child processes - No child processes

Hi guys,

I have come to the following problem with jruby 1.6.7.2 and the latest version of the gem:

     Failure/Error: photo.generate_version_for!(style_name)
     Errno::ECHILD:
       No child processes - No child processes
     # org/jruby/RubyProcess.java:512:in `waitpid'
     # org/jruby/RubyProcess.java:497:in `waitpid'
     # org/jruby/RubyArray.java:1615:in `each'
     # org/jruby/RubyEnumerable.java:830:in `inject'
     # org/jruby/RubyHash.java:1186:in `each'
     # org/jruby/RubyBasicObject.java:1698:in `__send__'
     # org/jruby/RubyKernel.java:2097:in `send'
     # org/jruby/RubyBasicObject.java:1704:in `__send__'
     # org/jruby/RubyKernel.java:2101:in `send'
     # org/jruby/RubyBasicObject.java:1698:in `__send__'
     # org/jruby/RubyKernel.java:2097:in `send'
     # org/jruby/RubyBasicObject.java:1704:in `__send__'
     # org/jruby/RubyKernel.java:2101:in `send'

The problem is also discussed here http://stackoverflow.com/questions/12387405/paperclip-with-jruby and a monkey-patch is proposed in the answers section.

shell_quote exploitable

shell_quote as it is now is broken and can be exploited. I strongly suggest that you at the very least use shellwords from stdlib, which does the same job a lot better.
But even better would be if you use one of the spawning methods which bypass the shell entirely. See Kernel#spawn for 1.9 and IO.popen for 1.8. Those accept forms where you can pass arguments individually, which means no escaping is needed at all.

can't dup NilClass

I get TypeError: can't dup NilClass when doing
Cocaine::CommandLine.new('some command', nil).run
Could we have an error message that's more descriptive like a Cocaine error that says "nil is not a valid argument"?

Can't run a command

I'm trying to run the following code:

ffprobe = Cocaine::CommandLine.new("ffprobe", "-i :path -show_entries format=duration -v quiet -of csv='p=0'")
ffprobe.run(path: "/Users/szimek/Downloads/whirr.mp3")

When I run it, I'm getting the following error:

Cocaine::ExitStatusError: Command 'ffprobe -i '/Users/szimek/Downloads/whirr.mp3' -show_entries format=duration -v quiet -of csv='p=0'' returned 1. Expected 0
Here is the command output: STDOUT:



STDERR:

from /usr/local/bundle/gems/cocaine-0.5.8/lib/cocaine/command_line.rb:91:in `run'

If I run exactly the same command from terminal it works fine:

$ ffprobe -i '/Users/szimek/Downloads/whirr.mp3' -show_entries format=duration -v quiet -of csv='p=0'
0.548563

If I run ffprobe without any parameters:

ffprobe = Cocaine::CommandLine.new("ffprobe")
ffprobe.run

it works fine as well and returns a help message in STDERR.

I tried with and without posix-spawn gem. I'm using MacOS 10.13, Ruby 2.4.1 and Cocaine 0.5.8. Any idea what can be wrong?

Would it be valuable to have Cocaine use Process.spawn if available?

I'd like to be able to do some file descriptor juggling. I haven't done a lot of research but it looks like spawn isn't fully there yet on JRuby, and obviously didn't exist on 1.8.7, so I'm assuming that whatever features that a switch to Process.spawn might enable would have to disable themselves on an environment where it's not.

Later on, could look into integrating posix-spawn to get the love spread a little further around, but I don't know the maturity of that project either.

Please let me know if a (very simple for now) pull request that adds basic, optional, file descriptor redirection capabilities would be useful as I decide how badly to hack the functionality I need.

No way to supply an ENV for one command

The ENV is only modifiable via the Cocaine::CommandLine.environment hash. There should be a way to supply individual changes for a single command without having to modify what is essentially a global.

Cocaine fails under JRuby + Torquebox

I originally encountered the error when using Paperclip but it seems related to Cocaine.

Command :: identify -format %wx%h "C:/Users/Tom/AppData/Local/Temp/rails121215-6332-1o1oxtk-30333.png[0]"
Completed 500 Internal Server Error in 277ms

NoMethodError (undefined method `exitstatus' for nil:NilClass)

with the last call in the backtrace being: cocaine (0.4.2) lib/cocaine/command_line.rb:80:in `run'

If I attempt to try and execute a simple test:

line = Cocaine::CommandLine.new("echo", "hello world")
line.run

in one of the instances of the JRuby interpreter running inside the JBoss AS it throws the following:

org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `exitstatus' for nil:NilClass
    com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrow(DefaultMBeanServerInterceptor.java:839)
    com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.rethrowMaybeMBeanException(DefaultMBeanServerInterceptor.java:852)
    com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:821)
    com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:791)
    org.jboss.as.jmx.PluggableMBeanServerImpl$TcclMBeanServer.invoke(PluggableMBeanServerImpl.java:498)
    org.jboss.as.jmx.PluggableMBeanServerImpl.invoke(PluggableMBeanServerImpl.java:246)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:601)
    org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:425)
    org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:292)
    org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:44)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:296)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:72)
    org.jruby.ast.CallManyArgsNode.interpret(CallManyArgsNode.java:59)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:197)
    org.jruby.runtime.Interpreted19Block.call(Interpreted19Block.java:128)
    org.jruby.runtime.Block.call(Block.java:89)
    org.jruby.RubyProc.call(RubyProc.java:261)
    org.jruby.internal.runtime.methods.ProcMethod.call(ProcMethod.java:64)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
    org.jruby.RubyClass.finvoke(RubyClass.java:630)
    org.jruby.RubyBasicObject.send19(RubyBasicObject.java:1665)
    org.jruby.RubyKernel.send19(RubyKernel.java:2090)
    org.jruby.RubyKernel$INVOKER$s$send19.call(RubyKernel$INVOKER$s$send19.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:356)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:213)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:217)
    org.jruby.ast.CallSpecialArgBlockPassNode.interpret(CallSpecialArgBlockPassNode.java:66)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.ast.RescueNode.executeBody(RescueNode.java:224)
    org.jruby.ast.RescueNode.interpret(RescueNode.java:119)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:112)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:154)
    org.jruby.javasupport.util.RuntimeHelpers$MethodMissingMethod.call(RuntimeHelpers.java:473)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
    org.jruby.runtime.callsite.CachingCallSite.callMethodMissing(CachingCallSite.java:401)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:323)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.DAsgnNode.interpret(DAsgnNode.java:110)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.ast.RescueNode.executeBody(RescueNode.java:224)
    org.jruby.ast.RescueNode.interpret(RescueNode.java:119)
    org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:197)
    org.jruby.runtime.Interpreted19Block.call(Interpreted19Block.java:128)
    org.jruby.runtime.Block.call(Block.java:89)
    org.jruby.RubyProc.call(RubyProc.java:261)
    org.jruby.internal.runtime.methods.ProcMethod.call(ProcMethod.java:64)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
    org.jruby.RubyMethod.call(RubyMethod.java:118)
    org.jruby.RubyMethod$INVOKER$i$call.call(RubyMethod$INVOKER$i$call.gen)
    org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrNBlock.call(JavaMethod.java:261)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
    org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:64)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:197)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:180)
    org.jruby.runtime.Block.yieldNonArray(Block.java:141)
    org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1781)
    org.jruby.RubyBasicObject.specificEval(RubyBasicObject.java:1805)
    org.jruby.RubyBasicObject.instance_eval19(RubyBasicObject.java:1691)
    org.jruby.RubyBasicObject$INVOKER$i$instance_eval19.call(RubyBasicObject$INVOKER$i$instance_eval19.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
    org.jruby.ast.FCallNoArgBlockPassNode.interpret(FCallNoArgBlockPassNode.java:27)
    org.jruby.ast.FCallTwoArgNode.interpret(FCallTwoArgNode.java:38)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:161)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:180)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
    org.jruby.ast.FCallNoArgBlockPassNode.interpret(FCallNoArgBlockPassNode.java:27)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
    org.jruby.runtime.Interpreted19Block.yieldSpecific(Interpreted19Block.java:133)
    org.jruby.runtime.Block.yieldSpecific(Block.java:99)
    rubyjit.Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552.block_1$RUBY$__file__(C:/torquebox/jruby/lib/ruby/gems/shared/gems/sinatra-1.2.6/lib/sinatra/base.rb:758)
    rubyjit$Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552$block_1$RUBY$__file__.call(rubyjit$Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552$block_1$RUBY$__file__)
    org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:139)
    org.jruby.runtime.Block.yield(Block.java:130)
    org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
    org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1181)
    org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1174)
    org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:336)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:179)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
    rubyjit.Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552.chained_0_ensure_1$RUBY$__ensure__(C:/torquebox/jruby/lib/ruby/gems/shared/gems/sinatra-1.2.6/lib/sinatra/base.rb:755)
    rubyjit.Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552.__file__(C:/torquebox/jruby/lib/ruby/gems/shared/gems/sinatra-1.2.6/lib/sinatra/base.rb)
    rubyjit.Sinatra::Base$$process_route_D3C78586491B4FC19C081B8351B5DBE560878A341530044552.__file__(C:/torquebox/jruby/lib/ruby/gems/shared/gems/sinatra-1.2.6/lib/sinatra/base.rb)
    org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:281)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:376)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:247)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:256)
    org.jruby.ast.FCallThreeArgBlockNode.interpret(FCallThreeArgBlockNode.java:36)
    org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:123)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
    org.jruby.runtime.Block.yield(Block.java:130)
    org.jruby.RubyArray.eachCommon(RubyArray.java:1605)
    org.jruby.RubyArray.each(RubyArray.java:1612)
    org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    org.jruby.ast.CallNoArgBlockNode.interpret(CallNoArgBlockNode.java:64)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.IfNode.interpret(IfNode.java:116)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:139)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:172)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
    org.jruby.ast.FCallNoArgNode.interpret(FCallNoArgNode.java:31)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.ast.RescueNode.executeBody(RescueNode.java:224)
    org.jruby.ast.RescueNode.interpret(RescueNode.java:119)
    org.jruby.ast.EnsureNode.interpret(EnsureNode.java:96)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:139)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:172)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
    org.jruby.ast.FCallNoArgNode.interpret(FCallNoArgNode.java:31)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:197)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:180)
    org.jruby.runtime.Block.yieldNonArray(Block.java:141)
    org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1781)
    org.jruby.RubyBasicObject.specificEval(RubyBasicObject.java:1805)
    org.jruby.RubyBasicObject.instance_eval19(RubyBasicObject.java:1691)
    org.jruby.RubyBasicObject$INVOKER$i$instance_eval19.call(RubyBasicObject$INVOKER$i$instance_eval19.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
    org.jruby.ast.FCallNoArgBlockPassNode.interpret(FCallNoArgBlockPassNode.java:27)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
    org.jruby.runtime.Block.yield(Block.java:130)
    org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
    org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1181)
    org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1174)
    org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:336)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:179)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
    org.jruby.ast.FCallOneArgBlockNode.interpret(FCallOneArgBlockNode.java:34)
    org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:123)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:161)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:180)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    org.jruby.ast.FCallNoArgBlockNode.interpret(FCallNoArgBlockNode.java:32)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.MultipleAsgn19Node.interpret(MultipleAsgn19Node.java:104)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.IfNode.interpret(IfNode.java:118)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.MultipleAsgn19Node.interpret(MultipleAsgn19Node.java:104)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.ast.RescueNode.executeBody(RescueNode.java:224)
    org.jruby.ast.RescueNode.interpret(RescueNode.java:119)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.MultipleAsgn19Node.interpret(MultipleAsgn19Node.java:104)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.MultipleAsgn19Node.interpret(MultipleAsgn19Node.java:104)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
    org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
    org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
    org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
    org.jruby.runtime.Interpreted19Block.yieldSpecific(Interpreted19Block.java:133)
    org.jruby.runtime.Block.yieldSpecific(Block.java:99)
    org.jruby.ast.ZYieldNode.interpret(ZYieldNode.java:25)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.ast.IfNode.interpret(IfNode.java:118)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:161)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:180)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
    org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    org.jruby.ast.FCallNoArgBlockNode.interpret(FCallNoArgBlockNode.java:32)
    org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:112)
    org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:126)
    org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:163)
    org.jruby.RubyClass.finvoke(RubyClass.java:734)
    org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:533)
    org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:361)
    org.jruby.javasupport.JavaEmbedUtils.invokeMethod(JavaEmbedUtils.java:264)
    org.torquebox.core.util.RuntimeHelper$3.call(RuntimeHelper.java:88)
    org.torquebox.core.util.RuntimeHelper.withinContext(RuntimeHelper.java:249)
    org.torquebox.core.util.RuntimeHelper.call(RuntimeHelper.java:86)
    org.torquebox.core.component.AbstractRubyComponent._callRubyMethod(AbstractRubyComponent.java:64)
    org.torquebox.core.component.AbstractRubyComponent._callRubyMethod(AbstractRubyComponent.java:73)
    org.torquebox.web.component.RackApplicationComponent.call(RackApplicationComponent.java:38)
    org.torquebox.web.servlet.RackFilter.doRack(RackFilter.java:113)
    org.torquebox.web.servlet.RackFilter.doFilter(RackFilter.java:101)
    org.torquebox.web.servlet.RackFilter.doFilter(RackFilter.java:72)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:372)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:679)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931)
    java.lang.Thread.run(Thread.java:722)

I can only seem to get a Java stacktrace here. However, in the console that JBoss is running in the following is printed:

16:00:14,351 INFO [stdout] (Thread-130) hello world

I noticed that had been some previous issues with JRuby so I tried using Cocaine::CommandLine.runner = Cocaine::CommandLine::BackticksRunner.new but this results in:

Errno::EINVAL (Invalid argument - =ExitCode)

Using JRuby version:
jruby 1.7.1 (1.9.3p327) 2012-12-03 30a153b on Java HotSpot(TM) 64-Bit Server V 1.7.0-b147 [Windows 7-amd64] and Torquebox version 2.2.0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.