dcsimg
June 25, 2017
Hot Topics:

Using the rJava R Package to Do More

  • February 10, 2017
  • By Deepak Vohra
  • Send Email »
  • More Articles »

In "Getting Started with R Using Java," you learned how to initialize the JVM to use Java with R, set the classpath, and invoke a Java object you created. In "Using Java Strings and the Swing API in R," you learned to use Strings, create a Java Swing application, and find if an object is an instance of a class. In this tutorial, we shall discuss using the rJava R package for exception handling, arrays, collections, casting and comparing Java objects and also to get System properties. This tutorial has the following sections.

Checking for and Clearing Exceptions

As mentioned before, the .jnew(class, ..., check=TRUE, silent=!check) function has the provision to check for exceptions by setting the check arg to TRUE, which is the default. Because the "silent" arg is !check by default, an error message gets output if an error exists. As an example, create a new Java object from the non-existent class hello/world with check=TRUE.

> v <- .jnew("hello/world", check=TRUE)

The following output indicates an error.

Error in .jnew("hello/world", check = TRUE) :
   java.lang.ClassNotFoundException
>

The following functions are provided to check for exceptions and throw exceptions.

Function Description Usage
.jcheck Checks the JVM for any pending exceptions and clears them. The .jnew function calls the .jcheck function implicitly when check=TRUE, which is the default. .jcheck(silent = FALSE)
.jthrow Throws a Java exception. The "exception" in usage is the exception object. .jthrow(exception, message = NULL)
.jgetEx Polls for any pending exceptions and returns the exception object if any. .jgetEx(clear = FALSE)
.jclear Clears the pending exceptions. .jclear()

If check=FALSE in the .jnew function call, an error message is not generated, the exception is not cleared, and the exception object may be obtained. As an example, call .jnew with a non-existent class and check=FALSE. No error message is generated.

> v <- .jnew("hello/world", check=FALSE)

To find if a Java exception was raised, call the .jgetEx function on the implicit exception object e and, if the exception object is not null, output a message to indicate that an exception was raised.

> if (!is.null(e<-.jgetEx())) print("Java exception was raised")
[1] "Java exception was raised"

The exception message may be output.

> print(e)
[1] "Java-Object{java.lang.ClassNotFoundException}"
>

The .jcheck function clears the exception and, if called twice consecutively, an output of FALSE or 0 indicates the same.

> print(.jcheck(silent=TRUE))
[1] 1
> print(.jcheck(silent=TRUE))
[1] 0

Using Arrays

The rJava package provides the .jarray function to create a Java array reference from a vector or a list of Java references.

.jarray(x, contents.class = NULL, dispatch = FALSE)

The contents.class is used only if a list of Java references is used to create an array and indicates the Java class to use for the objects in the array. The default is the java.lang.Object class.

For example, the following creates an array of ints 1 to 5.

> a <- .jarray(1:5)
> print(a
[1] "Java-Array-Object[I:[I@27d16a7f"
>

The .jevalArray returns the contents or elements of an array. For example, output the elements in array "a". The ints 1 to 5 are output.

> .jevalArray(a)
[1] 1 2 3 4 5
>

The .jarray returns a Java array reference jarrayRef. As another example, create an array from a vector with the vector being created using the R function "c".

> b <- .jarray(c("hello","world"))

Subsequently, evaluate the array using .jevalArray to output the elements of the array.

> .jevalArray(b)
[1] "hello" "world"
>

Using Collections

Collections could be created just as any other Java objects. As an example, create a class reference for the java.util.Vector class using the J high-level API for Java.

> Vector <- J("java.util.Vector")
>

Create a Java object reference called "v" from the class reference using the "new" operator.

> v <- new(Vector)

Add elements to the Vector object.

> v$add( "item1" )
[1] TRUE
> v$add( "item2" )
[1] TRUE
> v$add( "item3" )
[1] TRUE
>

Output from the preceding function calls is shown in R Console (see Figure 1).

Output from the preceding function calls, shown in R Console
Figure 1: Output from the preceding function calls, shown in R Console

Print the first element using the Vector class method firstElement().

> print(v$firstElement())
[1] "item1"

Output the size of the array with the size() method.

> print(v$size())
[1] 3

Output the Object reference for the array using the toArray()) method of Vector.

> print(v$toArray())
[1] "Java-Array-Object[Ljava/lang/Object;
    :[Ljava.lang.Object;@36ed5ba6"

Output the Vector class as a Sting using the toString() method.

> print(v$toString())
[1] "[item1, item2, item3]"

Output the last element in the Vector reference with the lastElement() method.

> print(v$lastElement())
[1] "item3"

Find if the Vector is empty with the isEmpty() method.

> print(v$isEmpty())
[1] FALSE

Remove an element with the remove() method.

> print(v$remove("item1"))
[1] TRUE

Subsequently, if the first element is printed, "item2" is output and not "item1".

> print(v$firstElement())
[1] "item2"

Remove all elements with removeAllElements() method in the the Vector class.

> print(v$removeAllElements())
NULL

Subsequently, find if the Vector object is empty and TRUE is returned.

> print(v$isEmpty())
[1] TRUE
>

As another example of Collections create an object "h" of type java.util.HashMap.

> h <- new( J("java.util.HashMap") )

Put a few key/value pairs in the HashMap.

> h$put("1", "hello" )
> h$put("2", "world" )
> h$put("3",new( J("java.lang.Double"), "10.2" ) )

Print the size of the HashMap object using the size() method.

> print(h$size())
[1] 3

Output the values in the HashMap using the values() method in HashMap.

> print(h$values())
[1] "Java-Object{[10.2, world, hello]}"

Get the value for a key with the get() method.

> print(h$get("1"))
[1] "hello"
>

Casting a Java Object

The .jcast function casts a Java object to another class and has the following usage.

.jcast(obj, new.class = "java/lang/Object",
   check = FALSE, convert.array = FALSE)

The "obj" is the Java object to cast and the class is the class to cast to. If check=TRUE, a check is performed using the .jinstanceof function to verify that the object is an instance of the class. If check=FALSE, which is the default, a check is not performed and an error is generated if the object is not an instance of the class. The convert.array =FALSE does not convert an array object to a jarrayRef reference. As an example, create a Vector class object called "v".

> v <- .jnew("java/util/Vector")

Cast the object to class java/lang/Object using .jcast.

> .jcast(v, new.class = "java/lang/Object",
   check = TRUE, convert.array = FALSE)
[1] "Java-Object{[]}"

Output from the preceding function calls is shown in R Console, as shown in Figure 2.

Output from the preceding function calls, shown in R Console
Figure 2: Output from the preceding function calls, shown in R Console

Getting System Properties

The system properties may be output using the .jcall function by supplying the system property to get as an arg to the getProperty method of java/lang/System with the value returned as a String.

> .jcall("java/lang/System","S","getProperty",
   "os.name")
[1] "Windows 7"
> .jcall("java/lang/System","S","getProperty",
   "file.separator")
[1] "\\"
> .jcall("java/lang/System","S","getProperty","java.class.path")
[1] "C:/Users/Deepak Vohra/Documents/R/win-library/3.3/rJava/
   java/boot;C:\\OracleNoSQLDatabase\\kv-client-3.0.5\\kv-3.0.5\\
   lib\\kvclient.jar;C:\\"
> .jcall("java/lang/System","S","getProperty","java.home")
[1] "C:\\Program Files\\Java\\jdk1.7.0_55\\jre"
> .jcall("java/lang/System","S","getProperty","java.vendor")
[1] "Oracle Corporation"
> .jcall("java/lang/System","S","getProperty","java.version")
[1] "1.7.0_55"
> .jcall("java/lang/System","S","getProperty","line.separator")
[1] "\r\n"
> .jcall("java/lang/System","S","getProperty","os.arch")
[1] "amd64"
> .jcall("java/lang/System","S","getProperty","path.separator")
[1] ";"
> .jcall("java/lang/System","S","getProperty","user.dir")
[1] "C:\\Users\\Deepak Vohra\\Documents"
>

Comparing Java References

Java references could be compared by using binary comparison operators such as ==, <, >, <=, or >=. As an example, create three objects of type Double, two of which would be from the same double value 10.0 and one from double 5.0.

> Double <- J("java.lang.Double")
> d1 <- new( Double, 10.0 )
> d2 <- new( Double, 10.0 )
> d3 <- new( Double, 5.0 )
>

Find if d1 is equal to d2 with the == binary operator.

> d1==d2

The output is as follows.

[1] TRUE

Compare if d1 is less than d2 with <.

> d1 < d2

The output is as follows.

[1] FALSE

Compare d1 and d3 with <=.

> d1 <= d3

The output is as follows.

[1] FALSE

Compare d1 with d3 with >=.

> d1 >= d3

The output is as follows.

[1] TRUE

Find if d1 is less than d2 with <.

> d1 > d2

The output is as follows.

[1] FALSE
>

Conclusion

In this three-section tutorial, we discussed using Java from R. We discussed most of Java functionality, such as creating a Java object, calling a Java method, using Strings, creating a Swing application, finding if an Object is an instance of a Class, checking for exceptions, using Arrays, using Collections, casting a Java object, getting system properties, and comparing Java References in addition to initializing a JVM and setting the classpath.


Tags: Java, JVM, arrays, Exception handling, R, rJava, Java strings, Swing API, throw exceptions, binary comparison, classpath




Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date
Rocket Fuel