2016-04-20 15 views
0

Ich schreibe eine Java Anwendung in IntelliJ IDE. Die Anwendung verwendet Rserve(), um eine Verbindung zu R herzustellen und auf Skripts zuzugreifen. Ich habe ein Java-Skript, das einen Befehl an die Shell sendet, um Rserve() zu starten. Das Problem, das ich mit Blick auf bin jetzt ist das erste Mal, wenn ich die Anwendung ausführen, bekomme ich folgende Fehlermeldung:Rserve() Fehler in der ersten Instanz der Ausführung einer Java-Anwendung

Exception in thread "main" java.lang.NoSuchMethodError: org.rosuda.REngine.REngineException.<init>(Lorg/rosuda/REngine/REngine;Ljava/lang/String;Ljava/lang/Throwable;)V 
    at org.rosuda.REngine.Rserve.RserveException.<init>(RserveException.java:59) 
    at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:90) 
    at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:60) 
    at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:44) 
    at de.uni_jena.bioinformatik.RecalibrationGUI.Application.main(Application.java:40) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Und wenn ich das nächste Mal die Anwendung ausführen, es funktioniert perfekt. Von dem, was ich verstehen kann, im ersten Lauf, es nur die Rserve() Verbindung hergestellt und dann im zweiten Lauf funktioniert es. Kann mir jemand helfen, dies zu beheben, so dass die Anwendung in erster Linie an Rserve() anschließt und auch perfekt läuft?

Hier ist die Java-Klasse ist die Rserve()

public class InvokeRserve { 
    public static boolean invoke() { 
     try { 
      Process p = Runtime.getRuntime().exec("R CMD Rserve --vanilla"); 

      BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); 

      BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     } 
     catch (IOException e) { 
      System.out.println("Rserve connection: Exception occurred: "); 
      e.printStackTrace(); 
      System.exit(-1); 
     } 
     return true; 
    } 
} 

Und hier nennt, ist die Haupt-Java-Klasse, die die Anwendung startet und ruft die invoke() Methode:

public class Application { 
    /** 
    * Main method for the Swing application 
    * 
    * @param args 
    * @throws Exception 
    */ 
    public static void main(String[] args) throws Exception { 
      boolean value = InvokeRserve.invoke(); 
     RConnection check = new RConnection(); 
     if(check.isConnected()) 
     { 
      // Run the GUI construction in the Event-Dispatching thread for thread-safety 
      SwingUtilities.invokeLater(new Runnable() { 

       /** 
       * run method which create a new GUIMain object 
       */ 
       @Override 
       public void run() {new GUIMain("Java Application"); // Let the constructor do the job 
       } 
      }); 
     } 
     else 
     System.out.println("There was no R connection found."); 
    } 
} 

Auch ist es eine Möglichkeit, um eine bestehende Rserve() Verbindung zu stoppen (ich lese verschiedene Antworten, die vorschlagen, shutdown() zu verwenden, aber es funktioniert nicht für mich)? Jedes Mal muss ich meinen Computer neu starten, um eine bestehende Verbindung zu beenden und eine neue Verbindung zu starten, um den obigen Code zu testen.

Ich schaute auch in die StartRserve.java Beispieldatei unter http://www.rforge.net/DATRAS/files/org/rosuda/Mondrian/StartRserve.java. Aber wenn ich die Methode StartRserve.checkLocalRserve() in der Hauptklasse meiner Anwendung verwende, bekomme ich den gleichen Rserve() Fehler wie oben gezeigt.

Antwort

2

Ihre invoke()-Methode wird zurückgegeben, bevor Rserve tatsächlich gestartet wird. Daher versuchen Sie offenbar, sich zu früh zu verbinden. Möglicherweise möchten Sie p.waitFor(); hinzufügen. Siehe auch die StartRserve Klasse, die beim Starten von Rserve von Java viel robuster ist.

PS: Ich empfehle die Verwendung der stats-rosuda-devel mailing list für Rserve Fragen, die Ihnen viel schnellere Antworten gibt.

0

Ich habe eine Lösung zum Schließen der Rserve-Verbindung, ohne den Computer herunterzufahren. Versuchen Sie dies, während eine Rconnection Eröffnung:

RConnection rconn=null; 
    try{ 
     rconn=new RConnection(); 
     //Your personal code here 

    } catch(Exception exc){ 
     exc.printStackTrace(out); 
    } finally{ 
     if (rconn!=null){ 
      rconn.close(); 
     } 
    } 

Auf diese Weise, wenn die Anwendung auf halbem Wege mit einer Ausnahme beendet, es läuft immer noch die schließlich Teil und schließt die Verbindung. Hoffe das hilft in der Zeit.

Wie bei den Ausnahmedetails ist es möglich zu beantworten, ob Sie die Zeilennummern neben dem Code anzeigen können, da sich das Ausnahmeprotokoll auf den Code nach Zeilennummern bezieht.