JRuby로 Ruby와 Java 동시에 사용하기

개인적으로 BurpSuite의 Extender를 만들 때 Java를 사용했습니다. 당연히 Burp가 Java base이고, API 등의 사용성 때문에 Java로 개발하는 것이 일반적인데요, 오늘은 Jruby를 이용하여 Ruby와 Java를 혼용하여 사용하는 방법에 대해 이야기하려고 합니다.

Jruby

JRuby는 JVM 기반 루비 언어의 구현체입니다. 그래서 JRuby를 사용하면 Ruby와 Java간의 해석이 가능해지기 때문에 Ruby에서 Java function을 사용할 수 있고, 반대로 Java에서도 Ruby function을 사용할 수 있어집니다.

Ruby에서 Java 사용

require 'java'

frame = javax.swing.JFrame.new
frame.getContentPane.add javax.swing.JLabel.new('Hello, World!')
frame.setDefaultCloseOperation javax.swing.JFrame::EXIT_ON_CLOSE
frame.pack
frame.set_visible true

Java에서 Ruby 사용

//Example using JSR 233 Scripting for Java 6
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine rbEngine = mgr.getEngineByExtension("rb");
try {
  rbEngine.eval("puts 'Hello World!'");
} catch (ScriptException ex) {
  ex.printStackTrace();
}

Installation

우선 java gem 설치가 필요합니다.

gem install java

그리고 Jruby도 설치해줍니다.

# macos
brew install jruby

# ubuntu
apt-get install jruby

이제 irb를 통해 테스트해보면 Ruby 코드에서 Java를 사용할 수 있습니다.

irb
# 2.4.2 :003 >   require 'java'
# => true

Examples

간단하게 Java version 출력해주는 코드를 Java 단에서 불러와봅시다.

require java 
java_import java.lang.System
version = System.getProperties["java.runtime.version"]
puts version
jruby jtest.rb
# 1.8.0_111-b14

Java swing 을 이용해서 Gui 프로그램을 Jruby로 ruby 코드에서 구현해보면 이렇습니다.

require 'java'

# Java 코드에선.. import javax.swing.JFrame;
frame = javax.swing.JFrame.new("Window") # Creating a Java JFrame

# Java 코드에서 JLabel label = new Label(“Hello”); 와 같음
label = javax.swing.JLabel.new("Hello")

frame.add(label)  # 나머지 Java method 쓰는건 동일함
frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE)
frame.pack
frame.setVisible(true)
jruby jruby.rb

이미 만들어진 라이브러리(jar)를 가져오는건 쉽습니다. 그냥 ruby에서 라이브러리 불러오는 것처럼 jar 파일을 require 로 불러와주면 끝납니다.

require 'path/to/mycode.jar'