Проблема при вызове Java-класса из R - PullRequest
1 голос
/ 08 июня 2019

У меня есть следующий класс Java:

public class Processor {
    public String showMsg(String msg) {
        return "The message is : " + msg;
    }

    public static void main(String [] arg) {
        Processor pro = new Processor();
        System.out.println(pro.showMsg(arg[0]));
    }
}

Я хотел бы вызвать этот класс из следующего сценария R, который я впервые использую библиотеку rJava:

testJav <- function(){
  library(rJava)
  .jinit()
  obj <- .jnew("/home/adam/eclipse-workspace/TestMeProject/bin/Processor.class")
  xx <- .jcall(obj,"Say hi to her") #I'm not sure if this is the right way to pass the message as a String argument!
  xx
}

Когда я запускаю скрипт, я получаю следующую ошибку:

Error in .jnew("/home/adam/eclipse-workspace/TestMeProject/bin/Processor.class") : 
  java.lang.ClassNotFoundException: /home/adam/eclipse-workspace/TestMeProject/bin/Processor/class 

Я думаю, что проблема с Processor.class, но даже если я удаляю .class, я все равно получаю ту же ошибку.

Как я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 10 июня 2019

С вашим классом (хорошая идея иметь пакет)

package mypackage;

public class Processor {
    public String showMsg(String msg) {
        return "The message is : " + msg;
    }

    public static void main(String [] arg) {
        Processor pro = new Processor();
        System.out.println(pro.showMsg(arg[0]));
    }
}

хранится в файле src/mypackage/Processor

делать следующее

> mkdir target
> javac -d target src/mypackage/Processor.java
> export CLASSPATH=`pwd`/target
> R

тогда, внутри R, сделай следующее

testJav <- function(){
  library(rJava)
  .jinit()
  obj <- .jnew("mypackage/Processor")
  xx  <- .jcall(obj, returnSig="Ljava/lang/String;", method="showMsg", "Say hi to her")
}

как только у вас все будет на месте, вот что вы получите

> export CLASSPATH=`pwd`/target
> R
...
...
...
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> library(rJava)
> .jinit()
> obj <- .jnew("mypackage/Processor")
> xx  <- .jcall(obj, returnSig="Ljava/lang/String;", method="showMsg", "Say hi to her")
> xx
[1] "The message is : Say hi to her"
>

Веселитесь с R и JNI:)

Забавный факт

Знаете ли вы, что javap очень полезно, когда дело доходит до получения подписи метода?

> javap -s mypackage/Processor
Compiled from "Processor.java"
public class mypackage.Processor {
  public mypackage.Processor();
    descriptor: ()V

  public java.lang.String showMsg(java.lang.String);
    descriptor: (Ljava/lang/String;)Ljava/lang/String;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
}
0 голосов
/ 08 июня 2019

Вы пытаетесь передать путь к файлу .jnew, но .jnew не принимает путь к файлу.Как указано в документах , первый аргумент должен быть

полностью определенным именем класса в нотации JNI (например, "java / lang / String").

По сути, если вы импортируете свой класс в программе Java как com.mystuff.MyClass, тогда имя, которое вы должны передать .jnew, будет "com/mystuff/MyClass", независимо от того, где может находиться файл .class.

Вы можете заметить, что это не дает вам возможности сказать, где находится файл для класса.Это потому, что .jnew не там, где вы говорите rJava, где искать вещи..jpackage будет стандартным способом для пакета R добавить свои файлы Java в путь к классам Java.Если вы хотите добавить произвольные каталоги или файлы .jar в путь к классам, есть также функция .jaddClassPath.

...