I have a java file that I would normally execute by doing
java -jar jarname.jar arguments
I want to be able to run this file from R in the most system agnostic way possible. My current pipeline partially relies on rJava do identify JAVA_HOME and run the jar by doing
# path for the example file below
pathToJar = 'pdftk-java.jar'
# start up java session
rJava::.jinit()
# find JAVA_HOME
javaPath = rJava::.jcall( 'java/lang/System', 'S', 'getProperty', 'java.home' )
# get all java files
javaFiles = list.files(javaPath,recursive = TRUE,full.names = TRUE)
# find java command
java = javaFiles[grepl('/java($|\\.exe)',javaFiles)]
# run the jar using system
system(glue::glue('{shQuote(java)} -jar {shQuote(pathToJar)} arguments'))
This does work fine but I was wondering if there was a reliable way to replicate execution of a jar through rJava itself. I want to do this because
.jinit
isn't undoableThis is the file in I am working with. Taken from https://gitlab.com/pdftk-java/pdftk/tree/master
Executing JAR
file is (essentially) running class file that is embedded inside JAR
.
Instead of calling system and executing it as external application, you can do following:
JAR
file to CLASSPATH
rJava::.jaddClassPath(pathToJar)
JAR
file what is the main class. Look into META-INF/MANIFEST.MF
file to identify the main class. (In this case com.gitlab.pdftk_java.pdftk
)newObj = rJava::.jnew('com/gitlab/pdftk_java/pdftk')
Update
Running JAR
file (calling main
method of Main-class) is the same things as calling any other method inside Java based class. Please note that main
method takes array of Strings as argument. Take a look here for sample: http://www.owsiak.org/running-jar-file-from-r-using-rjava-without-spawning-new-process/
newObj$main(rJava::.jarray('--version'))
For this specific case if you look at the source code for this class, you'll see that it terminates the session
public static void main(String[] args) {
System.exit(main_noexit(args));
}
This will also terminate your R session. Since all main
function does it to call main_noexit
then exit, you can replace main
with main_noexit
in the code above.
newObj$main_noexit(rJava::.jarray('--version'))