我有一个通常会执行的Java文件
java -jar jarname.jar arguments
我希望能够以最不依赖系统的方式从R运行此文件。我当前的管道部分依靠rJava来标识JAVA_HOME并通过运行JAR
# 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'))
这确实很好,但是我想知道是否存在一种可靠的方法来通过rJava本身复制jar的执行。我想这样做是因为
.jinit
isn't undoable This是我正在使用的文件。取自https://gitlab.com/pdftk-java/pdftk/tree/master
答案 0 :(得分:1)
执行JAR
文件实际上是运行嵌入在JAR
中的类文件。
您可以执行以下操作,而不是调用系统并将其作为外部应用程序执行:
JAR
文件添加到CLASSPATH
rJava::.jaddClassPath(pathToJar)
JAR
文件中的主要类是什么。查看META-INF/MANIFEST.MF
文件以识别主类。 (在这种情况下,com.gitlab.pdftk_java.pdftk
)newObj = rJava::.jnew('com/gitlab/pdftk_java/pdftk')
更新
运行JAR
文件(调用Main-class的main
方法)与调用基于Java的类中的任何其他方法一样。请注意,main
方法将字符串数组作为参数。在这里查看示例:http://www.owsiak.org/running-jar-file-from-r-using-rjava-without-spawning-new-process/
newObj$main(rJava::.jarray('--version'))
在这种情况下,如果您查看此类的源代码,将会看到它终止了会话
public static void main(String[] args) {
System.exit(main_noexit(args));
}
这还将终止您的R会话。由于所有main
函数都执行此操作以调用main_noexit
然后退出,因此可以在上面的代码中将main
替换为main_noexit
。
newObj$main_noexit(rJava::.jarray('--version'))