Using Java from JRuby and Jython

Java has good reputation and rich framework for wide range of uses, mostly related to B2B. Well said, although this collection of libraries are good, the Java language is sometimes “too hard“ for those who enjoys dynamic and interpreted languages, like Ruby and Python.

There is hope at the end of the road. JRuby and Jython are complete implementation of Ruby and Python that works on the top of JVM, so you can have a two-way bridge between Java and Ruby/Python.

Important notice: neither JRuby or Jython comes installed on Mac OS X. I've just download them and installed under ~/Library/ folder without using the version number in the name part. Feel free to install anywhere you want.

In this article, I will teach how to use Apache log4j logging library directly in JRuby (and Jython). Please, keep Apache Log4j 1.2.16 API opened to follow this explanation.

The example as it follows:

# test-log4j.rb

require "java"
require "log4j-1.2.16.jar"

The first require allows JRuby to use the core Java functionalities. The second require loads classes, methods and everything else from the JAR file.

org.apache.log4j.BasicConfigurator.configure

Call static method configure() from BasicConfigurator class. This method setup a standard log format to output messages to the screen.

log = org.apache.log4j.Logger.getLogger "jruby"

Call constructor method getLogger() from Logger with parameter jruby. The result of this call is a instance and handler saved into log variable. We need this handler to write log messages with specific log level. We also defined jruby (the argument of getLogger) to print in every log message.

log.trace "This is my trace message"
log.debug "This is my debug message"
log.info "This is my info message"
log.warn "This is my warning message"
log.error "This is my error message"
log.fatal "This is my critical error message"

For each log level (trace, debug, info, warn, error, fatal) there is a method in log to call. Every call has a string argument – the message that we want to log.

Running the script gives the following output:

$ ~/Library/JRuby/bin/jruby teste-log4j.rb
0 [main] DEBUG jruby  - This is my debug message
1 [main] INFO jruby  - This is my info message
1 [main] WARN jruby  - This is my warning message
1 [main] ERROR jruby  - This is my error message
2 [main] FATAL jruby  - This is my critical error message

Note the TRACE message was not displayed on screen, because the default configuration only allow messages from DEBUG level to higher (FATAL).

The same example written in Jython is:

$ ~/Library/Jython/bin/jython 
Jython 2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54) 
[Java HotSpot(TM) 64-Bit Server VM (Apple Inc.)] on java1.6.0_20
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path.append("log4j-1.2.16.jar")
>>> import org.apache.log4j            
*sys-package-mgr*: processing new jar, '/Users/ruda/log4j-1.2.16.jar'
>>> org.apache.log4j.BasicConfigurator.configure
<java function configure 0x1>
>>> org.apache.log4j.BasicConfigurator.configure()
>>> log = org.apache.log4j.Logger.getLogger("jython")
>>> log.info("Hello from Jython!")
0 [main] INFO jython  - Hello from Jython!