lib/childprocess/jruby/process.rb in childprocess-0.9.0 vs lib/childprocess/jruby/process.rb in childprocess-1.0.0

- old
+ new

@@ -44,27 +44,52 @@ stop_pumps @exit_code = @process.exitValue end end - # - # Only supported in JRuby on a Unix operating system, thanks to limitations - # in Java's classes - # - # @return [Integer] the pid of the process after it has started - # @raise [NotImplementedError] when trying to access pid on non-Unix platform - # - def pid - if @process.getClass.getName != "java.lang.UNIXProcess" - raise NotImplementedError, "pid is only supported by JRuby child processes on Unix" + # Implementation of ChildProcess::JRuby::Process#pid depends heavily on + # what Java SDK is being used; here, we look it up once at load, then + # define the method once to avoid runtime overhead. + normalised_java_version_major = java.lang.System.get_property("java.version") + .slice(/^(1\.)?([0-9]+)/, 2) + .to_i + if normalised_java_version_major >= 9 + + # On modern Javas, we can simply delegate through to `Process#pid`, + # which was introduced in Java 9. + # + # @return [Integer] the pid of the process after it has started + # @raise [NotImplementedError] when trying to access pid on platform for + # which it is unsupported in Java + def pid + @process.pid + rescue java.lang.UnsupportedOperationException => e + raise NotImplementedError, "pid is not supported on this platform: #{e.message}" end - # About the best way we can do this is with a nasty reflection-based impl - # Thanks to Martijn Courteaux - # http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193 - field = @process.getClass.getDeclaredField("pid") - field.accessible = true - field.get(@process) + else + + # On Legacy Javas, fall back to reflection. + # + # Only supported in JRuby on a Unix operating system, thanks to limitations + # in Java's classes + # + # @return [Integer] the pid of the process after it has started + # @raise [NotImplementedError] when trying to access pid on non-Unix platform + # + def pid + if @process.getClass.getName != "java.lang.UNIXProcess" + raise NotImplementedError, "pid is only supported by JRuby child processes on Unix" + end + + # About the best way we can do this is with a nasty reflection-based impl + # Thanks to Martijn Courteaux + # http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193 + field = @process.getClass.getDeclaredField("pid") + field.accessible = true + field.get(@process) + end + end private def launch_process(&blk)