Scripting on the Java platform

Using Groovy, Jython, and JRuby for Java development

1 2 3 4 5 Page 3
Page 3 of 5

Calling Java classes from scripts

Referencing Java classes within a script requires importing the Java classes before using them. For instance, JRuby defines a special statement include Java to access the built-in Java classes of the Java runtime. Other, non-bundled classes have to be prefixed with Java::. As you can see in Listing 7 the first statements of the JRuby script activate the Java support and define constants to shorten the path of the SSLContext class and the BlockingConnection class.

In contrast to JRuby, scripting runtimes like Jython use existing, native script statements to import Java classes. Like Python modules, Java packages can be imported by using the ordinary Python statement import <packagename>. Jython also supports the different variants of Python's import statement, such as from <packagename> import <class> . Groovy, which is explicitly designed to run on the Java platform, uses Java's import syntax.

Compact syntax means less code

The syntax of scripting languages is often more compact than the syntax of Java. For instance, neither Groovy, Ruby, nor Python requires you to write verbose getters and setters. To simplify JavaBeans property handling, the Java runtime of such scripting languages allows you to address the property in a direct, script-like way.

A Java method like <object>.getDefault() can also be addressed by calling <object>.default. Additionally, the JRuby runtime automatically maps Java's CamelCase naming convention to Ruby's convention. For instance, you could address the Java method <object>.activateSecuredMode() within a JRuby script by calling <object>.activate_secured_mode().

Based on such features, Java classes looks like ordinary script classes, as you can see in Listing 7. In this example a Java network library is used to implement a rudimentary SMTP client in JRuby.

Listing 7. Using Java classes within JRuby (rudimentary SMTP client)

include Java

# set up constants to shorten the paths
SSLContext = javax.net.ssl.SSLContext
BlockingConnection = Java::org.xsocket.stream.BlockingConnection


#performs new BlockingConnection(String, int, SSLContext.getDefault(), boolean)
bc = BlockingConnection.new('smtp.web.de', 25, SSLContext::default, false) 
 
bc.receive_timeout_millis = 60 * 1000 # performs setReceiveTimeoutMillis(long)
puts bc.read_string_by_delimiter("\r\n")  # performs readStringByDelimiter(String)

bc.write("STARTTLS\r\n")  
puts bc.read_string_by_delimiter("\r\n")
bc.activate_secured_mode()

bc.write('AUTH PLAIN ' + ["\000" + 'from.me' + "\000" + 'myPassword'].pack('m'))
puts bc.read_string_by_delimiter("\r\n")

bc.write("HELO Server\r\n")
puts bc.read_string_by_delimiter("\r\n")

bc.write("MAIL FROM: from.me@web.de\r\n")
puts bc.read_string_by_delimiter("\r\n")

bc.write("RCPT TO: itsyou@gmx.net\r\n")
puts bc.read_string_by_delimiter("\r\n")

bc.write("data\r\n")
puts bc.read_string_by_delimiter("\r\n")

mail =
'Message-ID: 46D957AF.2020804
Date: Sat, 01 Sep 2007 14:14:39 +0200
From: from.me@web.de
User-Agent: my mail client
MIME-Version: 1.0
To: itsyou@gmx.net
Subject: what I have to say
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

combining scripting languages with Java is great'

bc.write("#{mail}\r\n.\r\n")
puts bc.read_string_by_delimiter("\r\n")

bc.write("quit\r\n")
puts bc.read_string_by_delimiter("\r\n")
bc.close()

Running your scripting language on the top of the Java virtual machine allows you to seamlessly integrate Java code and scripts. By calling a method of an embedded Java object, the scripting runtime looks for a proper method signature of the Java class. By identifying a matching Java method, the runtime performs the method call. Script-specific data types of argument parameters are automatically converted to corresponding Java types and vice versa.

1 2 3 4 5 Page 3
Page 3 of 5