class Closure::BeanShell

Closure Script will manage a single BeanShell to run the Java tools. This way we don't pay the Java startup costs on every compile job.

Constants

JAR
PROMPT

Public Class Methods

new(classpath=[]) click to toggle source

@param classpath (Array)<string>

# File lib/closure/beanshell.rb, line 26
def initialize(classpath=[])
  @semaphore = Mutex.new
  @classpath = classpath
  @@pipe ||= nil
end

Public Instance Methods

run(command) click to toggle source

Run any Java command that BeanShell supports. Recovers from error conditions when the Java process is killed.

# File lib/closure/beanshell.rb, line 34
def run(command)
  begin
    return execute command
  rescue Errno::EPIPE
    # Shut down broken pipe; another will be started.
    $stderr.print "#{self.class}: restarting Java.\n"
    @@pipe.close
    @@pipe = nil
  end
  # This "second chance" will not rescue the error.
  execute command
end

Protected Instance Methods

execute(command) click to toggle source

Executes a command on the REPL and returns the result.

# File lib/closure/beanshell.rb, line 50
def execute(command)
  out = ''
  @semaphore.synchronize do
    unless @@pipe
      classpath = [@classpath, JAR].flatten
      java_repl = "#{Closure.config.java} -classpath #{classpath.join(':').dump} bsh.Interpreter"
      @@pipe = IO.popen(java_repl, 'w+')
      eat_startup = ''
      eat_startup << @@pipe.readpartial(8192) until eat_startup =~ PROMPT
    end
    @@pipe << command
    out << @@pipe.readpartial(8192) until out =~ PROMPT
  end
  out.sub(PROMPT, '')
end