Showing posts with label JRuby. Show all posts
Showing posts with label JRuby. Show all posts

Wednesday, February 9, 2011

Posts on the Rise and Fall of JVM Dynamic Languages

In this post, I briefly reference two interesting posts that fall into the camp of The Rise and Fall of Dynamic Languages. The first referenced post focuses on dynamic languages on the JVM and the second referenced post focuses specifically on one Groovy developer's perception of Groovy's eventual demise.


Dynamic Languages on the JVM ... Growth or Demise

I first saw the post Dynamic Languages on the JVM ... Growth or Demise when it was referenced on Java.net on 6 February 2011 (Java.net editor Kevin Farnham has since posted more personal analysis on the post and provided this week's poll question based on that post). In Dynamic Languages on the JVM ... Growth or Demise, post author John Yeary references the Dr. Dobb's article The Rise And Fall of Languages in 2010, which itself is based on analysis of the Tiobe Programming Community Index statistics for 2010.

Yeary observes that dynamic languages are said to be in a decline and that JVM-based dynamic languages are said to be in the same decline with fellow dynamic languages. Yeary does not agree and asserts (emphasis is his): "I believe that the decline of dynamic languages is real EXCEPT on the JVM." Yeary speaks highly of Jython and has even more praise for JRuby because "it combines the ease of use in Ruby with the power and multitude of frameworks available in Java."


The Rise and Fall of the Groovy Language

Another really interesting post I ran across this week was Gavin Grover's "The Rise and Fall of the Groovy Language" (no direct link to it currently?). It is obvious from Grover's blogs and other postings that he has seriously invested time and energy into learning, using, and trying to improve Groovy. Despite that, there is obvious frustration in the post "The Rise and Fall of the Groovy Language."

Anyone who has read my blog probably knows that I really like Groovy for scripting. Colleagues also know of my interest in Groovy. Although I am growing increasingly comfortable with the language, I did learn several things about the history (he links to many earlier interesting forum threads related to Groovy development) and possible future of Groovy from Grover's post. Among other things Grover points out the early history of Groovy, the falling out with the project founder, and looks at the name change he believes is coming to the Groovy language.

Grover also outlines four major reasons he believes "[the Groovy] language has been failing." He articulates his reasons in much greater detail, but they can be summarized as follows:
  1. Developer focus on profit over capital development
  2. Too closely tied and dependent on Grails
  3. Groovy language community is really not a community at all
  4. Combination of first and third reason: Groovy "community" is not really such

I recommend this post to anyone interested in the future of Groovy. I don't know Gavin "Groovy" Grover or the other principals involved enough to formulate an opinion on the correctness of these observations and following conclusions. However, there is no doubt that I did learn several things about the earlier days of Groovy from this post and the post is a reminder that politics are in everything, even open source software development. It's also a reminder that there is often a tension between the legitimate desire to profit from previous work and the desire of other community members to continue focusing on the improvement of the product.

Saturday, July 4, 2009

2009 JavaOne: Groovy/JRuby

The 2009 JavaOne Conference included multiple opportunities to learn about and discuss Groovy. Bill Gloff provides a nice summary of the Groovy-related activities and mentions that Groovy won this year's edition of the Script Bowl. In this blog posting, I will be focusing on two Groovy-related presentations presented at 2009 JavaOne: What's New in Groovy 1.6? (TS-4215) and Comparing Groovy and JRuby (TS-4955).


What's New in Groovy 1.6?

In late 2008, SpringSource acquired G2One, bringing key Groovy developers such as Graeme Rocher and Guillaume Laforge into SpringSource. The latter, Guillaume Laforge, presented Groovy at the aforementioned Script Bowl and was the presenter of "What's New in Groovy 1.6?"

Laforge's presentation was not entirely new to me because I had previously read his article What's New in Groovy 1.6. He mentions in his presentation slides that the examples in the presentation come from the article and suggests reading the article for more detailed coverage of the topics covered in the presentation.

Groovy Overview

In his presentation, Laforge mentions some of the advantages of Groovy that I have significantly appreciated as I have worked with Groovy. I especially like Groovy because it is so easy to apply my years of Java development experience and to mix Java and Groovy; Laforge refers to this benefit as a "flat learning curve" coming from Java. I also like how Laforge refers to Groovy as having a "relaxed grammar derived from the Java 5 grammar."

The "Features at a Glance" slide is a single-slide overview of a subset of nice Groovy features such as Groovy's seamless integration with Java, Groovy's full object-orientation, and Groovy's support of operator overloading.

As part of the introduction to Groovy, the presentation uses the now-common approach of showing a simple Java program that runs as-is in Groovy and then as a much slimmer version that takes advantage of Groovy-specific features. This is the same approach I took in my blog posting Groovy: JVM-based Scripting with Less Ceremony. The ability to write Groovy scripts and applications with anywhere from largely 100% pure traditional Java to almost 100% pure Groovy features is one of the features of Groovy that I find most compelling.

This presentation also introduces the Groovy Web Console. Although I had been aware of this online tool for interactively trying out Groovy, I had never actually used it or even seen it because I had started learning and using Groovy using Groovy from the command line. I tried it out after seeing it in this presentation. Although it is not very difficult to use Groovy from the command line, the web console makes it particularly easy to start using Groovy. For example, I can write a variation of the now-famous one-line Groovy Hello World application and execute it easily within the Groovy Web Console as shown in the next screen snapshot.



As the image above demonstrates, a single line of Groovy can achieve the simple Hello World program that takes several lines in traditional Java.


Performance and Syntactic Improvements

One slide in the presentation focus on performance improvements from Groovy 1.5 to 1.6. According to the presenter, Groovy is now among the fastest of the JVM language implementations. There are a few syntax improvements discussed as well with my favorite being complete support of J2SE 5 features such as enums, annotations, and generics. The presentation points out that Groovy's support for annotations allows it to be used with annotation-driven frameworks and libraries such as Guice.


Groovy Metadata: Abstract Syntax Tree (AST) Transformations

A few slides are devoted to coverage of Groovy 1.6's support for AST Transformations that allow the creation of custom language syntax. Laforge focuses on @Singleton, @Immutable, @Lazy, and @Delegate in this presentation.


Groovy and JSR 223

One of the most exciting features I have enjoyed with Groovy 1.6 is its bundling of a built-in JSR 223-compliant script engine. In fact, I like this so much that I have previously blogged about it. This new feature makes using Groovy within Java code via JSR 223 almost as easy as using the Rhino JavaScript engine that comes with the HotSpot JVM.


Groovy and Java Management Extensions

As proven by the fact that I currently have 43 blog posts tagged as JMX, I really like to read about, write about, and use JMX. It is easy to use any Java APIs and libraries with Groovy, but Groovy 1.6 takes JMX ease of use a step further with the JMX Builder. This presentation devotes a couple of slides to JMX Builder. One slides outlines its main features and the other provides code snippets for each feature. It is a testament to the simplicity of JMX Builder syntax that all of this can be fit onto two slides! I have blogged previously on JMX Builder.


Groovy and OSGi

The last new topic in this presentation is Groovy's "OSGi readiness." OSGi has been a popular topic in recent years and SpringSource has been an early adopter of OSGi, so Groovy's support of it is not surprising.


Summary: What's New in Groovy 1.6?

As stated in his presentation and stated previously in this blog posting, most of the material presented in the presentation is available with different level of detail in the article What's New in Groovy 1.6. If you are interested in Groovy and have not read either, you might want to start with the presentation for a high-level overview and then go to the article for more details.



Comparing Groovy and JRuby

If you are a fan of the original Star Trek series, you will love the slides in this presentation. If you are not a fan of the original Star Trek series but want to learn more about how Groovy compares to JRuby, you will still find most of the slides informative and useful. There are many images from the original Star Trek series interspersed with the technical content of the presentation. I found these images to be not distracting and expect them to generally appeal to the technical crowd without any risk of being offensive as some slides have been recently deemed in at least two recent conferences (Ruby and Flash conferences).

I have been using both Groovy and JRuby in recent months and so was interested to read this presentation and see how Neal Ford's conclusions and observations aligned with mine. In general, he observed many of the similarities and differences I have observed and called out some that I realized were different but had not previously thought about.

I particularly like an early slide in his presentation where he presents an image of a scale with Groovy on the left side and JRuby on the right side and has a single sentence for each. I think these sentences succinctly describe the most important difference (to me) between these dynamic languages: their intent. Ford states that "Groovy dynamicizes the Java platform" while "JRuby brings Ruby to the Java platform." When I have been asked by colleagues about the main difference between the two languages, I have answered this same way, albeit not as elegantly as Ford does.

I have stated that I believe that Groovy appeals most to experienced Java developers who wish to leverage their skills and knowledge in Java and generally are happy with Java, but want to take advantage of some dynamic features, some newer language features (some of which may end up in Java SE 7), and of general script-friendly language attributes. On the other hand, I believe JRuby is more attractive to those developers who either are more comfortable with Ruby or wish to learn Ruby, but need access to the JVM for some reason (such as needing to take advantage of JVM benefits or to use the Java framework or one of its many libraries). Groovy, to me, is really more an extension of Java while JRuby, to me, really is "Ruby on the JVM."

Another interesting chart in this presentation also appears early and shows a horizontal axis representing the spectrum of dynamic to static and a vertical axis representing the spectrum of strongly typed to weakly typed. Although I don't see any notes to conclusively back up my interpretation of this slide, it does seem that the red and blue chips on the chart reflect the fact that both Groovy and (J)Ruby are strongly typed dynamic languages. Graeme Rocher has a similar but rotated slide in his Grails Exchange 2007 presentation Dynamic Groovy - Meta Magic!

This presentation has many slides covering different features that Groovy and JRuby offer as well as the often different approaches each language takes to the same features. Even without notes or the audio of the presentation, these are pretty easy to follow in the slides if you have basic familiarity with some of the key tenets of the dynamic languages.

Some of my favorite slides in this presentation occur in the "Summary" section where Ford outlines "the good" and "the bad" of each of these two languages. I am always suspicious of a presenter's credibility when he or she cannot think of much negative about whatever he or she is talking about. At the very least, nothing is perfect and there always should be situations in which a particular language is not the best fit or has disadvantages compared to another language.

Ford's "good" and "bad" for the two languages include several bullets each, but include the key differentiating characteristics of the languages. Although both will run on the JVM and allow use of Java libraries and JVM features, Groovy is closer to Java (for good or for bad) than is JRuby and JRuby is closer to Ruby. It really comes down to whether one prefers to use a Java-like language or to use Ruby on the JVM.

By the way, I couldn't help but laugh at the slide in this presentation that mentions Perl with an image of a man screaming. That's classic. Although I like both Groovy and JRuby, you won't catch me using Jperl or jPerl or any other form of Perl on the JVM anytime soon.

Sunday, May 31, 2009

Dustin's Bookmarks - 31 May 2009 (REST, Java, and JRuby)

I found four resources linked to from DZone to be particularly interesting this week. I am linking to them in this post as a form of glorified bookmark for my own future reference and in case someone else has not seen them already.


Five Things I Used to Forget About Java

The blog post Five Things I Used to Forget About Java could be useful to anyone returning to Java development, anyone new to Java development, or anyone who has not used one the items discussed for a while. The post covers Java approaches for converting String to Integer, use of the ternary operator, instanceof keyword versus Class.isInstance method, implementing comparators, and obtaining the number of command-line arguments passed into a main function.


Is It JRuby?

The useful online tool Is It JRuby? helps deal with the question of whether a particular Ruby gem will work with JRuby. Although many Ruby gems do work well with the JRuby implementation, some Ruby gems (especially the C-based ones) only run with other, non-JRuby implementations of Ruby. This community-driven site helps organize which Ruby gems work with JRuby. I plan to mention this resource in my Colorado Software Summit 2009 presentation Applied JRuby.


RESTGate - Web Client for REST Resources

The online tool RESTGate - Web-Based Client for REST-based Web Services appears to be an easy-to-use (no setup) browser-based client for performing simple testing of and interaction with REST-based web services. I will likely blog on this in more detail in the future and will almost certainly mention this tool in my Colorado Software Summit 2009 presentation RESTful Java.


sqlREST

The sqlREST project looks like an interesting one. This project benefits from use of Java standards, running on Java EE servlet containers and connecting to multiple databases via appropriate JDBC drivers. The goal of this project is to allow easy exposure of database entries via REST-style web services. Like the other Thomas Bayer tool mentioned above (RESTGate), I plan to mention sqlREST as part of my RESTful Java presentation.

Wednesday, May 20, 2009

JRuby's Ruby-Style Exception Handling

Both Java and Ruby have relatively sophisticated exception handling built-in to the respective languages. Their exception handling techniques have many similarities, but also have some differences in both keywords and in supported exception handling functionality. JRuby allows mixing of Java classes with Ruby code and so it is no surprise that JRuby supports handling of exceptions thrown by Java classes.

Ruby's equivalent of Java's try-catch-finally is begin-rescue-ensure, though Ruby throws in an additional clause with the else clause. The else clause is executed when no declared rescue block is exercised. In other words, if there was an equivalent in Java (there isn't), it would be a block of code that is executed only when none of the the declared catch blocks were executed. Note that the Ruby else is different from Ruby's ensure or Java's finally in that it is only executed if no rescue (equivalent of Java catch) statement is executed while Ruby's ensure and Java's finally are always executed no matter which exceptions were caught or not caught.

Speaking of catching exceptions, Ruby does not have an equivalent of Java's checked exceptions. JRuby (and Groovy by the way) emulate this as well. Java and Ruby throw exceptions in the first place in a very similar manner, though Java uses the keyword throw and Ruby uses the keyword raise.

With the idea that most of the concepts of Java exception handling are highly similar to Ruby exception handling (the notable exceptions being the keywords used, the use of checked exceptions only in Java, and the use of a block of code executed only when no declared exception condition is encountered only in Ruby), it is time to move on to an examples of catching exceptions thrown by a Java class in JRuby code.

Java exceptions, even checked exceptions, do not need to be rescued/caught in JRuby. This is demonstrated in the following code listing in which an SQLRecoverableException (a checked exception) might be thrown (and the called method is declared to throw its parent SQLException) but no explicit exception handling is implemented.

Listing 1 - JRuby Invocation of Java Method Throwing Exception

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

# 1. "Happy Path" query to demonstrate JRuby/Java interaction works fine
puts "ALL'S WELL"
accessor = GenericOracleDatabaseAccessor.new
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//localhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"


In the example above, there is a call to a custom Java class (GenericOracleDatabaseAccessor) and method (performDatabaseQuery). That class is shown in the next code listing.


Listing 2 - GenericOracleDatabaseAccessor.java

package dustin.examples.jruby;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import oracle.jdbc.pool.OracleDataSource;

/**
* Class used for demonstration purposes only and should not be used anywhere
* in which security or maintainability matter. The problems with this
* particular Java class include its being in the unnamed package, the extreme
* riskiness of supporting a generic query of any String passed into the method,
* lack of use of PreparedStatement, lack of verification of correct and
* non-null parameters before applying them, etc. In fact, this class is used
* here because its many problems make it easy to have it throw exceptions that
* the JRuby example code can catch and handle.
*/
public class GenericOracleDatabaseAccessor
{
final static String NEW_LINE = System.getProperty("line.separator");

/**
* Perform a generic database query. CAUTION: There are
* numerous reasons why this particular code sample should not be used in
* any real or production settings. It is used here only to demonstrate
* how JRuby supports handling of Java exceptions in a Ruby-like manner. It
* is not a good idea normally to pass in the JDBC URL. The JDBC exception
* handling is also intentionally poor in this example. See class description
* for other failings (mostly intentional) of this class and method..
*
* @param jdbcUrl The JDBC URL for the database connection; a default is
* attempted if this is null.
* @param queryString The query statement to be run against the database.
* @param columnNames Column Names whose values are to be returned in
* resulting String.
* @throws SQLException Checked exception related to use of JDBC.
*/
public String performDatabaseQuery(
final String jdbcUrl,
final String queryString,
final String[] columnNames) throws SQLException
{
final OracleDataSource datasource = new OracleDataSource();
final String url = jdbcUrl == null
? "jdbc:oracle:thin:@//localhost:1521/orcl"
: jdbcUrl;
datasource.setURL(url);
datasource.setUser("hr");
datasource.setPassword("hr");
final Connection connection = datasource.getConnection();
final Statement queryStatement = connection.createStatement();
final ResultSet resultSet = queryStatement.executeQuery(queryString);
final StringBuilder returnString = new StringBuilder();
while (resultSet.next())
{
for (final String columnName : columnNames)
{
returnString.append(resultSet.getObject(columnName)).append(" ");
}
returnString.append(NEW_LINE);
}
resultSet.close();
queryStatement.close();
connection.close();
return returnString.toString();
}
}


As the code listing for GenericOracleDatabaseAccessor above indicates, the main method that is called on that class is called performDatabaseQuery and its accepts three parameters. The JRuby code could have called this method in a traditional Java-style call, but I chose to use a more Ruby-stylistic method call with underscores separating the multiple words in the method name along with parameters passed to the method in Ruby style.

The Java method performDatabaseQuery is declared to throw SQLException (parent of SQLRecoverableException). However, the calling JRuby code did not need to explicitly handle the exception. The above code ran correctly, but how would the exception be handled if it did get thrown? The next JRuby sample code intentionally specifies a non-existent host to force an exception to be thrown.

Listing 3 - Java Exception Thrown But Not Explicitly Handled in JRuby

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

puts "EXCEPTION WITHOUT HANDLING"
accessor = GenericOracleDatabaseAccessor.new
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//unknownhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"


Running the above JRuby code leads to the following output.



Although the exception thrown from the Java class was never explicitly handled in the code, the JRuby output shown directly above indicates that the exception is ultimately "handled" by displaying stack trace information. Of particular interest is the NativeException, the JRuby exception that wraps Java exceptions.


Listing 4 - JRuby Code Explicitly Catching Java Exception

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

puts "RUBY CATCHING OF JAVA EXCEPTION"
accessor = GenericOracleDatabaseAccessor.new
begin
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//unknownhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"
rescue SQLRecoverableException => sqlRecoverableException
puts "#{sqlRecoverableException}"
puts "Message: #{sqlRecoverableException.message}"
puts "Backtrace: #{sqlRecoverableException.backtrace}"
end


The code in Listing 4 looks like Ruby code, but explicitly catches a Java exception (SQLRecoverableException). The output from running this is shown next.



The same exception can be caught with a Ruby-specific exception as well. This is shown with the next code listing (Listing 5).

Listing 5 - Catching Java Exception in JRuby as Ruby Exception

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

puts "CATCHING INTENTIONAL EXCEPTION WITH RUBY'S RUNTIME ERROR"
accessor = GenericOracleDatabaseAccessor.new
begin
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//unknownhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"
rescue RuntimeError => runtimeError
puts "#{runtimeError}"
puts "Message: #{runtimeError.message}"
puts "Backtrace: #{runtimeError.backtrace}"
end


The output for the above code listing is shown next.



Ruby provides the ability to catch multiple exceptions in the same rescue clause (a feature talked about for Java SE 7). With JRuby, we can leverage this functionality to use the same rescue clause to catch a Java-based exception and a Ruby-based exception. This is demonstrated with Listing 6.

Listing 6 - Catching Java and Ruby Exceptions in Same rescue Clause

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

puts "CATCHING/RESCUING RUBY/JAVA EXCEPTIONS IN SAME RESCUE BLOCK"
accessor = GenericOracleDatabaseAccessor.new
begin
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//unknownhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"
rescue RuntimeError, SQLRecoverableException => sqlError
puts "#{sqlError}"
puts "Message: #{sqlError.message}"
puts "Backtrace: #{sqlError.backtrace}"
end


The output for this code listing is now shown.



Ruby adds some extra possibilities to exception handling. Besides the rescue keyword, Ruby also provides the ability to execute a block of code if no rescue block is executed. This is indicated with the else keyword. This is different from ensure (Ruby's equivalent of Java's finally) because it only executes if none of the declared rescue blocks is executed.

The next code listing demonstrates this and the screen shot following the code listing shows what the output looks like upon execution.

Listing 7 - Demonstrating Ruby's else and ensure Keywords

#!/usr/bin/env jruby -w

include Java
import java.sql.SQLRecoverableException
require 'C:\app\Dustin\product\11.1.0\db_1\jdbc\lib\ojdbc6.jar'
require 'C:\java\examples\jrubyExamples\jrubyExceptionHandling\lib\Dustin.jar'
include_class Java::dustin.examples.jruby.GenericOracleDatabaseAccessor

puts "USING RUBY'S ELSE AND ENSURE"
accessor = GenericOracleDatabaseAccessor.new
begin
puts "#{accessor.perform_database_query \
'jdbc:oracle:thin:@//localhost:1521/orcl',
'select first_name, last_name from employees',
['FIRST_NAME', 'LAST_NAME'].to_java(:string)}"
rescue RuntimeError, SQLRecoverableException => sqlError
puts "#{sqlError}"
puts "Message: #{sqlError.message}"
puts "Backtrace: #{sqlError.backtrace}"
else
puts "ELSE: Data Access performed without exception!"
ensure
puts "ENSURE: I am always called whether rescue or else is invoked."
end




Conclusion

Exception handling is just one area in which JRuby makes it easy to mix Java and Ruby. This blog posting has covered different ways to handle exceptions thrown by Java classes in JRuby code. Additional resources with different and greater details are listed next.


Additional Resources

Handling Java Exceptions in JRuby (September 2006)

Dealing with Java Exceptions in JRuby (May 2007)

Java and Ruby Working Together (see "Exception handling" section)

Calling Java from JRuby (Wiki page that was last updated 21 March 2009 at time of this writing)

Using Java Classes in JRuby (September 2007)

Ruby Exceptions: Ruby Study Notes

Ruby's Exception Hierarchy (September 2006)

Programming Ruby: Exceptions, Catch, and Throw (2001)

Saturday, May 9, 2009

JRuby Supports Java and Ruby Method Names Conventions

Jeff Cohen's blog post Ruby 101: Naming Conventions does a nice job of covering conventions associated with the Ruby programming language. I like how he specifically writes to Java developers and .NET developers to call out differences in conventions from those respective worlds from what is conventional in Ruby.

Because JRuby supports use of Java classes within Ruby code running on the JVM, it is not surprising that differences of convention are more likely to be noticed in JRuby development. One area in which Java and Ruby differ in convention is the naming of methods. JRuby conveniently allows Ruby code calling Java classes to call methods on those Java classes using either a traditional Java method naming convention (with or without parentheses) or using Ruby-friendly syntax (all lowercase letters with underscores separating the different words).

The following simple JRuby script uses the Java System.getProperties() method to get all of the defined system properties. It uses both a traditional Java method name convention and the Ruby-centric equivalent get_properties. Note that I did not need to do anything special to get this support.


# The purpose of this JRuby script is to demonstrate that JRuby supports
# Ruby-consistent method name syntax even on standard Java classes.

# Will be calling Java classes from this JRuby script
include Java

# Need to import System to avoid "uninitialized constant System (NameError)"
import java.lang.System

separator = "=================================================================="

# Java-style:
# The first access of System.getProperties is implemented as would be done in
# 'traditional' Java. The parentheses are not required on getProperties()
# call because it has no parameters passed to it, but the parentheses are
# retained here as more conducive to Java style.
puts separator
puts "CLASSICAL JAVA"
puts separator
puts "#{System.getProperties()}"

# Ruby-style:
# Ruby convention tends to favor separating multiple words in method names
# with underscores rather than with uppercase first letters as is Java's
# convention.
puts separator
puts "RUBY-ED JAVA"
puts separator
puts "#{System.get_properties}"



When the above script is run, both calls to System.getProperties() work exactly the same.

The example so far called a Java method that did not accept any parameters. However, the same support for Ruby method naming convention, Java method naming convention, or some combination of these is supported with methods that accept parameters. The two examples printed to standard output from the next code listing display exactly the same information based on a call to System.getProperty(String).


# Java-style with parameters:
# Can use traditional Java style name and can use or not use parentheses.
# Truly traditional Java-style would employ parentheses, but I wanted to show
# that they are not necessary in JRuby even when using the camel case method
# naming convention.
puts separator
puts "Java Version (Java-style): #{System.getProperty 'java.version'}"
puts separator

# Ruby-style with parameters:
# I could have added parentheses here, but they are only necessary if the
# object returned from the method call needs to have something access on it
# in the same line, which I am not doing here.
puts separator
puts "Java Version (Ruby-style): #{System.get_property 'java.version'}"
puts separator


In this case, I intentionally left the parentheses out of the example that would have otherwise been compliant with Java method naming convention.

I have found it generally best to try to accommodate the conventions of a particular programming language because of the many benefits gained from doing so (improved ability to read and maintain others' code, improved reflection capabilities, improved opportunities for convention over configuration or configuration by exception, and so forth). However, it can be a little less clear sometimes with JRuby, particularly when calling Java classes and methods.

Outside of personal taste, there is nothing better or worse about Java's or Ruby's method naming conventions; rather, they are just different. I have a very slight preference for using the syntax that is compliant with Ruby convention in JRuby code because most of the surrounding JRuby code is Ruby and consistency is often a highly desirable goal. However, on the list of matters of personal tastes and preferences, this ranks way, way down there. It is far more important to me that I can leverage the benefits of Java and the JVM with the benefits of Ruby.

Monday, May 4, 2009

JRuby, jmx4r, GlassFish, and Viewing Logging Levels

I have blogged previously on using simple remote access of GlassFish via JMX. In this blog posting, I will look briefly at how jmx4r makes this very easy to do from JRuby.

Jeff Mesnil's jmx4r was formerly hosted on Google Code, but is now hosted on github. The jmx4r library is easily installed the Ruby way using Ruby Gems: jruby -S gem install jmx4r (the -S option is significant). The next screen snapshot shows how easy it is.



With the jmx4r gem downloaded and installed, it is now easy to apply jmx4r to "speak JMX" from JRuby. The following code snippet is based on an example available in JMX the Ruby Way with jmx4r.


require 'rubygems'
require 'jmx4r'

JMX::MBean.establish_connection :host => "localhost", :port => 8686
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
puts "There are #{logging.logger_names.size} loggers."
logging.logger_names.each do |logger_name|
puts "Logger named #{logger_name} set to logging level #{logging.get_logger_level logger_name}"
end


There aren't a lot of lines to review in this code example. The require 'jmx4r' statement demonstrates our use of jmx4r. The JMX::MBean.establish_connection statement connects to the host and port associated with Glassfish's JMX MBean exposure by default (and can be verified in GlassFish's console output when starting up a domain). The JMX::MBean.find_by_name statement is an MBean query on the MBean with an ObjectName of java.util.logging:type=Logging. This MBean can also be seen from JConsole as shown in the next screen snapshot.



We can also see logging levels in GlassFish's administrative console as shown in the next screen snapshot.



With the view of the logger levels seen in JConsole and in GlassFish's own web-based administrative console, it is now time to see them via our JRuby script. When I run the JRuby script shown above, however, I see a SecurityException.



I need to provide the username and password to avoid this security exception. The default credentials for GlassFish are "admin" for the username and "adminadmin" for the password. These can be added to the above JRuby code, to lead to the code shown next.


require 'rubygems'
require 'jmx4r'

JMX::MBean.establish_connection :host => "localhost", :port => 8686,
:username => "admin", :password => "adminadmin"
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
puts "There are #{logging.logger_names.size} loggers."
logging.logger_names.each do |logger_name|
puts "Logger named #{logger_name} set to logging level #{logging.get_logger_level logger_name}"
end


With the credentials properly provided, the JRuby script will now work correctly as demonstrated in the next screen snapshot.



One could use this JRuby+jmx4r to set log levels or to read/set other exposed JMX operations and attributes. This allows JRuby-powered scripts to be easily used in a wide variety of monitoring, management, and administrative roles.

Thursday, April 30, 2009

VisualVM: JRuby and the Ruby to JVM Spectrum

As I have worked with JRuby, it has been interesting to observe the intersection of the Java and Ruby communities. Because JRuby potentially combines with best of the JVM with the best of Ruby, it is perhaps not surprising that JRuby leads to a greater intersection of the Java community and the Ruby community. For example, because I have been working primarily in Java in recent months, I probably would not have been aware of the major controversy in the Ruby community surrounding a single presentation given recently at the Golden Gate Ruby Conference (GoGaRuCo).

Many Rubyists like to focus on the Ruby advantages that JRuby brings to Java, but there is no denying that JRuby also brings advantages of the JVM to Ruby. One particular area of interest here is the impact of the JVM on JRuby performance. In How JRuby makes Ruby Fast, Charles Nutter demonstrates how JRuby's performance improves as more JVM features (server mode, JIT compiling, and so forth) are employed. Some strict Ruby compliance must be sacrificed for some of the performance improvements, but this flexibility to selectively choose between the best features of Ruby and the JVM is one of the endearing features of JRuby.

As described in the JRubyWiki topic Performance Tuning, JRuby performance can be tweaked with JVM arguments and properties. Although these properties and JVM arguments can be set on the command-line, there are times you may want to know which ones are being used or what the default settings are. This is where VisualVM makes things really easy.

VisualVM is included with recent versions of Sun's implementation Java SE 6. It in many ways serves as a replacement for JConsole and a host of command-line tools provided with Sun's SDK. In his post Can Your Ruby Do This?, Ola Bini points out how JRuby is able to take advantage of the built-in JMX support in Java SE 6 for automatic detection, monitoring, and management. Similarly, VisualVM can be used to monitor JRuby processes by virtue of them running in the JVM.

To demonstrate this, I'll use VisualVM to monitor the running JIRB (JRuby's Interactive Ruby) tool. With jirb started on my local machine (it could also be accessed remotely, but local is slightly easier), I see the running process when I start Visual VM (jvisualvm at the command line) as shown in the next screen snapshot.



In this case, the only other Java process running on my local machine is VisualVM itself. This also provides evidence that JIRB does indeed run as a Java process (using class org.jruby.Main). When I click on the JRuby process, I can see the JVM arguments used in conjunction with running jirb as shown next.



Because I had downloaded and installed the JConsole-like MBeans plug-in for VisualVM earlier, the JMX-exposed MBeans for JIRB are available. These are shown in the next screen snapshot in the MBeans tab (this tab is not available in VisualVM until it is explicitly downloaded and installed using Tools-->Plugins).



As the last image indicates, the JRuby process exposes a long list of configuration items for viewing. This allows VisualVM, JConsole, or any other JMX-enabled client to see how the JRuby runtime is configured in that particular case.

JRuby brings together the Java world and the Ruby world both in technical aspects and in people/community/political aspects.

Wednesday, April 29, 2009

jirb: Gentle Introduction to JRuby

If you haven't had the opportunity to work with Ruby or JRuby, the jirb tool provides an easy approach to playing with JRuby basic syntax and features.

In the article Accessorize Oracle Database with Ruby, I used screen shots of IRB (Interactive Ruby) to introduce Ruby for scripting. JIRB is the equivalent tool running on JRuby. In fact, in this blog post I will use the same examples in JIRB that I used in that OTN article with IRB to demonstrate Ruby on the JVM with JRuby.

In the OTN article (Figure 3), I demonstrated accessing Ruby predefined constants RUBY_PLATFORM, RUBY_VERSION, and RUBY_RELEASE_DATE in IRB. The next screen snapshot shows the same constants in JIRB along with an additional JRuby-specific constant JRUBY_VERSION.



The fact that the RUBY_PLATFORM constant is set to "java" provides a good clue about this actually being JRuby, but the existence of the JRUBY_VERSION constant (1.2) confirms that it is JRuby 1.2 being used.

I used the first figure (Figure 1) of the OTN Ruby article to demonstrate using Ruby mathematical operators in IRB. The next screen snapshot demonstrates the same mathematical operators in JIRB.



Figure 2 of the OTN article on Ruby demonstrated Ruby String functions in IRB. The next screen snapshot shows these same String functions in JIRB.



Finally, in the Figure 4 of the OTN article on Ruby, I demonstrated (as best as can be done in a static article) how clicking on tab twice brings up completion information in IRB. The same feature works in JIRB:



Besides demonstrating the tab-tab completion functionality of JIRB, this also demonstrates that even an integer (0) is an object in Ruby.


Getting Started with JRuby and JIRB

JRuby can be downloaded here. There are source and binary (jruby-bin-1.2.0.zip) downloads available. When the binary download is complete, it can be unzipped or opened into a directory of choice (such as C:\jruby-1.2.0 in my case. I like to set an environment variable JRUBY_HOME to point to this directory and then place %JRUBY_HOME%\bin on the Path. You can confirm correct setup by entering "jruby -v" on the console. If you see a JRuby version (such as 1.2) and a Ruby version (such as 1.8.6), the setup is correct. Running JIRB is as easy as typing "jirb" at the console prompt.