通过rJava复制Java -jar执行

时间:2019-07-16 20:31:10

标签: r rjava

我有一个通常会执行的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的执行。我想这样做是因为

  • 从JAVA_HOME查找java命令时,我想避免任何可能的系统相关问题
  • 我已经开始了rJava会话,只是为了获得JAVA_HOME。自.jinit isn't undoable
  • 起,我不妨使用它
  • 我不太熟悉通过-jar调用jar的方式,我很好奇。可以以jar独立的方式完成吗?如果不是这样,我应该在代码中寻找什么来知道如何做到这一点。

This是我正在使用的文件。取自https://gitlab.com/pdftk-java/pdftk/tree/master

1 个答案:

答案 0 :(得分:1)

执行JAR文件实际上是运行嵌入在JAR中的类文件。

您可以执行以下操作,而不是调用系统并将其作为外部应用程序执行:

  • 确保将您的JAR文件添加到CLASSPATH
rJava::.jaddClassPath(pathToJar)
  • 检查JAR文件中的主要类是什么。查看META-INF/MANIFEST.MF文件以识别主类。 (在这种情况下,com.gitlab.pdftk_java.pdftk
  • 实例化R中的类。
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'))