Using RJB to use Java code in Ruby on Rails, parse brails
Before getting started
About this tutorial
Ruby on Rails (Rails) is a full-stack Web application framework written in Ruby, ruby is a rich, free, scalable, portable, and object-oriented scripting language. Rails is very popular among Web application developers. It allows you to quickly and effectively develop Web applications and deploy them in any Web container, such as IBM? WebSphere? Or Apache Tomcat.
Before Rails and similar Web application development frameworks appeared, the standard tools used for Web application development were Java language, because Java language was platform-independent, complete API sets are available. Many Java Web applications are still running, which leads to a lot of useful and well-written Java code (collectively known as legacy code in this tutorial) with good availability. The legacy Java code is usually packaged in a set of JAR files.
If you change the Web application development platform to Rails, You can reuse the legacy Java code. Ruby Java Bridge (RJB) is a toolkit that can load JAR files to Rails Applications and access methods and variables in Rail applications. This tutorial explains how to configure and use rjb in a Rails application.
Target
In this tutorial, you will learn how:
- Download, compile, and install RJB
- Set RJB to access the shared Java Library
- Load the legacy Java code into the Rails application and access it
This tutorial does not delve into the functions of Rails. Compared with other Web frameworks, Rails has many advantages, one of which is that the number and quality of documents used for this platform are high (see references ).
Prerequisites
This tutorial assumes that you are familiar with Java, Ruby, and Ruby on Rails.
System Requirements
This tutorial assumes that you are using Linux? System (however, in Windows? The steps are basically the same ). This tutorial assumes that you have a working Ruby on Rails. If not, find a link to the relevant documentation in the references section to help you install and configure Rails on your system.
RJB requires that Java SDK be installed on the system. If you need a Java SDK, you can download the latest Java se sdk for your platform and install it immediately.
RJB installation and Setup
This section describes how to download, install, compile, and set RJB.
Download RJB
You can download the standard Ruby Gem package or RJB in the form of source code archive files compiled by yourself. For demonstration purposes, I recommend downloading the source code archive file, so I will use this method. Now download the RJB 1.1.3 source. zip file (the latest RJB version is available at the time of this tutorial ).
Make sure that the following environment variables are set or updated, which are required for RJB installation:
- JAVA_HOME must point to the Java SDK installation directory.
- PATH must include $ JAVA_HOME/bin.
For example, in bash (for Linux only), if you have installed the Java SDK to/usr/local/jdk60, run the following command:
[root@san]# export JAVA_HOME=/usr/local/jdk60
[root@san]# export PATH=$PATH:$JAVA_HOME/bin
Compile and install RJB
The next step is to compile and install RJB by executing the following command:
[root@san]# unzip rjb-1.1.3.zip
[root@san]# cd rjb-1.1.3
[root@san]# ruby setup.rb config
[root@san]# ruby setup.rb setup
[root@san]# ruby setup.rb install
Confirm installation successful
To verify that RJB is successfully installed, call the Ruby interactive console irb:
[root@san]# irb
Then enter require 'rjb ':
irb(main):001:0> require 'rjb'
=> true
irb(main):002:0>exit
If the require 'rjb 'command returns true, it means that the Ruby installation recognizes the newly installed rjb library. Now you can start using RJB in the application.
Use legacy code through RJB
In this section, you will load and access the legacy Java code in the Rails application.
Sample project
Java Tar package from ICE Engineering is a good toolkit written in Java to process archive files. It provides local Java Implementation of the tar archive utility. When combined with the java.util.zip package, it can process .tar.gz files. It also utilizes the platform independence of the Java language. Can it be modified on all UNIX? Variant and run on Windows. As an exercise, you will use it to extract the content of a sample tar file. Using a similar method, you can use any legacy Java code in the Ruby on Rails application.
The goal of the exercise is:
- Load the tar. jar file to a Rails application.
- Load the classes required by the JAR file into the application.
- Decompress the content of the sample test.tar file using these classes.
Getting started
Obtain the sample file
First, you need to obtain the sample tar file (test.tar) and Java Tar package for the system:
- Download and save test.tar to a convenient location.
- Download and save javatar-2.5.tar.gz.
- Extract the javatar-2.5.tar.gz content to a convenient location. In this exercise, the only file used in this package is tar. jar, which is in the jars directory.
Access the Shared Library
RJB uses Java Native Interface (JNI) to implement its functions. Therefore, it needs to access some shared object files (shared libraries) attached to JDK installation ). You must use the following command to add the location of these files to the LD_LIBRARY_PATH environment variable:
[root@san]# export JAVA_HOME=/usr/local/jdk60
[root@san]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/i386
[root@san]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$JAVA_HOME/jre/lib/i386/client
If you plan to use RJB in an independent Ruby script, you only need to set these environment variables in the shell being processed. For your Ruby on Rails application, you must also set these variables in the environment. rb file of the Rails application.
Load RJB to a Rails Application
To load RJB to a Rails application and set it to call a Java class, two steps are required:
- Tell Ruby to include the rjb library in the code.
- Load the JVM and set the class path and other optional JVM parameters.
First, use the following command to initialize RJB:
require 'rjb'
Next, add all the legacy. jar files to be used in the Rails application-in this example, tar. jar-to the classpath variable:
Rjb: load (classpath = '.:/path/to/tar. jar', jvmargs = [])
You can leave jvmargs blank unless you want to specify additional parameters for JVM.
Now, you can import the Java classes to Ruby, instantiate these classes, and call the required methods.
Import the Java class to Ruby and instantiate it.
The Ruby code in Listing 1 imports the required Java classes from the tar. jar package, and creates a Ruby object from the imported class:
Listing 1. Import the Java class to Ruby and instantiate it
tararchive = Rjb::import('com.ice.tar.TarArchive')
fileinputstream = Rjb::import('java.io.FileInputStream')
file = Rjb::import('java.io.File')
file_instance = file.new_with_sig('Ljava.lang.String;','.')
fileinputstream_instance =
fileinputstream.new_with_sig('Ljava.lang.String;','test.tar')
tararchive_instance =
tararchive.new_with_sig('Ljava.io.InputStream;',fileinputstream_instance)
p "Let's verify that the objects created are indeed of the classes we
wanted..."
p "------------------------------"
p "For the File instance...."
p "Expecting: java.io.File , it is: " + file_instance._classname
p "------------------------------"
p "For the FileInputStream instance...."
p "Expecting: java.io.FileInputStream , it is: " +
fileinputstream_instance._classname
p "------------------------------"
p "For the TarArchive instance...."
p "Expecting: com.ice.tar.TarArchive , it is: " +
tararchive_instance._classname
Import Java class
The first three lines in Listing 1 call the RJB import method and import the required classes to the Ruby variables tararchive, fileinputstream, and file respectively. The full package path of the class must be specified. For example, the TarArchive class is com.ice.tar. TarArchive, And the FileInputStream class is java. io. FileInputStream-just like running the application using java commands.
Instantiate the imported class
Then, listing 1 creates an object for the import class. You can create a class by calling the new method of each class, just like creating any Ruby object (for example, tararchive. new ). However, this will call the default constructor of the TarArchive class (without parameters), and you do not want to do so.
After the constructor of the class is overloaded, you must modify the object creation method. In this case, you must create an object as follows:
object = Classname.new_with_sig('signature', parameter[,more parameters])
The first parameter defines the signature type of the parameter required by the constructor. It tells RJB to call its input parameter to match the constructor of the specified signature.
The 4th and 5th statements in Listing 1 create the object of the file and fileinputstream classes respectively, and they call the corresponding constructor. The parameter type is String.
In the 6th statements in Listing 1, one of the constructor of the TarArchive class accepts an InputStream object as a parameter. The signature type of this statement is a separate InputStream input parameter. Detailed details about these types of signatures are described in the Java SDK documentation of getName API (see references ). The second parameter is the InputStream type object created.
Test object Creation
The rest of the content in Listing 1 will check whether the object created by RJB is the object of the specified class. The method is to call the _ classname method added to each object. For example, calling tararchive_instance. _ classname will return com.ice.tar. TarArchive, which means that the class is correctly loaded and the class object is successfully created.
Call methods and capture results
After you load the class to Ruby and create an object from it, the next step is to call the required method and view the result. For example, you want to extract the content of the sample file (test.tar) to the current directory using the extractContents folder of the TarArchive class.
Like constructors, you can call methods in two ways. One way is to call the method directly, for example:
tararchive_instance.extractContents(file_instance)
When the method is overloaded, use _ invoke to call the type signature of each parameter of the specified method:
tararchive_instance._invoke('extractContents', 'Ljava.io.File;', file_instance)
This step allows RJB to know which methods should be called during method overloading.
Like normal Ruby code, you will capture the results returned by the object method (if any) and use the results in your own applications. The result returned by a method call is automatically converted to the corresponding object type. You only need to call the method directly within the object.
The functions implemented in the Java TarArchive class can now be used in your Ruby code. By using the same method, any functions implemented in Java code can be reused in your Ruby and Rails applications without modification.
Complete code
Listing 2 shows the complete Ruby code in the example in this tutorial (you can also download it ):
Listing 2. Complete example Ruby code
# Include 'rjb' library into your application
require 'rjb'
# Load the JVM specifying the jar files to include and any other optional JVM arguments
Rjb::load(classpath = '.:/path/to/tar.jar', jvmargs=[])
# Import the classes you want to use into a Ruby variable
# specify the full package path to the classes.
tararchive = Rjb::import('com.ice.tar.TarArchive')
fileinputstream = Rjb::import('java.io.FileInputStream')
file = Rjb::import('java.io.File')
# Create objects of the classes. Use the new method directly or use
# the 'new_with_sig' call to invoke overloaded constructors with arguments
# Directory you want to extract the files in this case, the current directory
file_instance = file.new_with_sig('Ljava.lang.String;','.')
# inputstream instance of the file to extract
fileinputstream_instance = fileinputstream.new_with_sig('Ljava.lang.String;','test.tar')
# tararchive instance of the file to be extracted.
tararchive_instance = tararchive.new_with_sig('Ljava.io.InputStream;'\
,fileinputstream_instance)
# Invoke the method from the class and capture the results.
# Use either the direct call of the method,
# or the '_invoke' call to invoke overloaded methods.
p 'Extracting file.....'
tararchive_instance.extractContents(file_instance)
p 'Done...'
Try the code, save the code in Listing 2 to a file with the extension. rb (or use the rjb-javatar.rb In the download), and then run it in the Ruby interpreter.
Conclusion
It is actually very easy to use the legacy Java code in the new Rails application by using the following method:
- Install Java SDK and RJB.
- Export the JAVA_HOME and LD_LIBRARY_PATH environment variables to the environment. rb file of your Rails application.
- Include the rjb library in the application.
- Load RJB and JVM by specifying the JAR file you want to use.
- Import the class to the Ruby variable from the JAR file you want to use and create the class object.
- Start to use the class just created in the Rails application, just like using any Ruby object.
To reuse the business logic that has been implemented using Java code in a Rails application, RJB is very useful and does not need to be re-implemented using Ruby. It also provides the advantages of Ruby on Rails and Java programming.
Alternative
You can also use an alternative method called JRuby to achieve the same goal as RJB. JRuby is a complete Ruby package implemented in the Java language, enabling Ruby to run on JVM (see references ). With JRuby, you can access all Java libraries. JRuby requires the installation of Ruby Gems specific to JRuby, because common Ruby Gems for non-Java Ruby cannot be compatible with JRuby.
RJB and JRuby have their own advantages and disadvantages. For JRuby, Ruby runs on JVM, and every Ruby call passes through JVM, which slows down execution. Similarly, if you have already set a Rails application, you need to set it from the beginning so that JRuby can access Java code. As a native Ruby package, RJB is easy to install and can be used in existing Rails settings. If you need to quickly call some Java code snippets in your Rails application, RJB is the best choice.
In general, it is very useful to reuse the legacy Java code in Rails Applications. Business logic that is well designed and written using the Java language will not be shelved. On the contrary, it can continue to provide useful functions in new Web applications.