From 05f184e62edc7515f9c3685ed1a62e4abf7046f0 Mon Sep 17 00:00:00 2001 From: Ben Browning Date: Tue, 11 Dec 2012 11:55:43 -0500 Subject: [PATCH] Run the compiler in-process on JRuby The closure compiler runs significantly faster under JRuby when run in-process versus shelling out. Behavior on non-JRuby runtimes remains unchanged. --- lib/closure-compiler.rb | 1 + lib/closure/compiler.rb | 19 ++++++++++++------- lib/closure/jruby_runner.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 lib/closure/jruby_runner.rb diff --git a/lib/closure-compiler.rb b/lib/closure-compiler.rb index 9132116..653293f 100644 --- a/lib/closure-compiler.rb +++ b/lib/closure-compiler.rb @@ -13,3 +13,4 @@ module Closure end require 'closure/compiler' +require 'closure/jruby_runner' if defined?(JRUBY_VERSION) diff --git a/lib/closure/compiler.rb b/lib/closure/compiler.rb index 9005601..8b1923e 100644 --- a/lib/closure/compiler.rb +++ b/lib/closure/compiler.rb @@ -52,14 +52,19 @@ def compile(io) def compile_files(files) @options.merge!({js: files}) - begin - result = `#{command} 2>&1` - rescue Exception - raise Error, "compression failed: #{result}" - end + if defined?(JRUBY_VERSION) + args = serialize_options(@options) + result = JRubyRunner.run(args) + else + begin + result = `#{command} 2>&1` + rescue Exception + raise Error, "compression failed: #{result}" + end - unless $?.exitstatus.zero? - raise Error, result + unless $?.exitstatus.zero? + raise Error, result + end end yield(StringIO.new(result)) if block_given? diff --git a/lib/closure/jruby_runner.rb b/lib/closure/jruby_runner.rb new file mode 100644 index 0000000..f93ed20 --- /dev/null +++ b/lib/closure/jruby_runner.rb @@ -0,0 +1,32 @@ +require 'java' +module Closure + require COMPILER_JAR + class JRubyRunner < com.google.javascript.jscomp.CommandLineRunner + def self.run(args) + output_contents = java.io.ByteArrayOutputStream.new + output = java.io.PrintStream.new(output_contents) + error_contents = java.io.ByteArrayOutputStream.new + error = java.io.PrintStream.new(error_contents) + runner = JRubyRunner.new(args.to_java(:String), output, error) + runner.do_run + if !error_contents.to_s.empty? + raise Error, "compression failed: #{error_contents.to_s}" + end + output_contents.to_s + ensure + output.close + error.close + end + + def createCompiler + compiler = com.google.javascript.jscomp.Compiler.new(getErrorPrintStream()) + # It would be nice to leave threads enabled but if we do then + # any process using this must wait at least 60 seconds after + # using closure-compiler before the process will exit, due to + # the underlying JVM thread pool keeping threads alive until + # they time out, which is 60 seconds. + compiler.disable_threads + compiler + end + end +end