2009-11-19 110 views
3

我在我的應用程序中使用Beanshell作爲嵌入式調試工具。這意味着我可以遠程登錄到我的應用程序,並在內部運行的同時運行它(我通常用rlwrap包裝telnet會話)。我可以從Java寫入Beanshell控制檯嗎?

的問題是,我發現打印到控制檯的BeanShell,而不是應用本身的標準輸出的唯一辦法,就是內的BeanShell的print()方法。

但我想用Java編寫代碼,我可以從Beanshell調用,它將輸出到Beanshell控制檯 - 即。它會顯示在我的telnet會話中,不會發送到應用程序的stdout,就像您嘗試使用System.out或System.err一樣。

這可能嗎?


編輯:爲了進一步澄清,我正在建立一個BeanShell的服務器如下:

public static void setUpBeanshell() { 
    try { 
     i.setShowResults(true); 
     i.eval(new InputStreamReader(Bsh.class.getResourceAsStream("init.bsh"))); 
     i.eval("server(" + Main.globalConfig.beanShellPort + ");"); 
    } catch (final EvalError e) { 
     Main.log.error("Error generated while starting BeanShell server", e); 
    } 
} 

我將如何修改這個,這樣我可以寫輸出到telnet會話的Java函數(而不是我的應用程序的System.out)

+0

是否可以從有問題的類繼承,添加你想要的功能,並實例者的一個實例上課呢? – 2009-11-25 02:42:18

+0

如何在需要在標準輸出上打印並調用 print(object.dumpInfo())的對象上使用String dumpInfo()方法?或者你想讓它更像一個記錄器? – 2009-11-25 13:53:04

+0

如果您需要更多記錄器,您需要在單獨構建的特定控制檯類上實例化解釋器,然後對象可以使用console.print()寫入該控制檯 - http://www.beanshell.org/ javadoc/bsh/ConsoleInterface.html#print(java.lang.String) – 2009-11-25 13:57:10

回答

2

,因爲它似乎是註釋忽略這幾天我在那裏複製它。

,您可以: ,而不是具有打印調試信息到調試信息的標準輸出回報的方法:

class ClientList { 
Integer clients = 0; 
public String debugClientList() { 
    return clients.toString(); 
} 

,然後從BeanShell的

print(clients.debugCientList()); 

會給你叫它輸出在您的telnet上

或者如果您需要更多記錄器,您需要直接與Interpreter對象進行交互

InterpreterSingleton { 
    public static final void Console console = new Interpreter(); 
} 
.... 

class ClientList { 
Integer clients = 0; 
public void addClient(Client c) { 
    .... 
    InterpreterSingleton.console.print("Client added, clients now are " + clients); 
} 

我在那裏回覆評論,因爲它需要更多的編碼; telnet實現爲每個連接使用不同的解釋器,因此您必須將該解釋器公開給要打印到telnet客戶端的對象。最快的方法是在默認的telnet服務器上改變一些位置,並使用修改的啓動服務器,而不是使用server()腳本命令(它是在lgpl或sun許可證條款下)

請注意,爲每個連接啓動一個解釋器;容易和快速修復是維護所有正在運行的口譯員名單,並打印到每一個調試信息,所以:

class InterpreterSingletonList { 
    public static final void Set<Interpreter> is = new HashSet(); 
    void printToAll(String s) { 
     for (Interpreter i: is) { 
      i.print(s); 
     } 
    } 
} 



package bsh.util; 

import java.io.*; 

import java.net.Socket; 
import java.net.ServerSocket; 
import bsh.*; 

/** 
    BeanShell remote session server. 
    Starts instances of bsh for client connections. 
    Note: the sessiond effectively maps all connections to the same interpreter 
    (shared namespace). 
*/ 
public class Sessiond extends Thread 
{ 
    private ServerSocket ss; 
    NameSpace globalNameSpace; 

    public Sessiond(NameSpace globalNameSpace, int port) throws IOException 
    { 
     ss = new ServerSocket(port); 
     this.globalNameSpace = globalNameSpace; 
    } 

    public void run() 
    { 
     try 
     { 
      while(true) 
       new SessiondConnection(globalNameSpace, ss.accept()).start(); 
     } 
     catch(IOException e) { System.out.println(e); } 
    } 
} 

class SessiondConnection extends Thread 
{ 
    NameSpace globalNameSpace; 
    Socket client; 

    SessiondConnection(NameSpace globalNameSpace, Socket client) 
    { 
     this.client = client; 
     this.globalNameSpace = globalNameSpace; 
    } 

    public void run() 
    { 
     try 
     { 
      InputStream in = client.getInputStream(); 
      PrintStream out = new PrintStream(client.getOutputStream()); 
      /* this is the one you're looking for */ 
         Interpreter i = new Interpreter( 
       new InputStreamReader(in), out, out, true, globalNameSpace); 
      i.setExitOnEOF(false); // don't exit interp 
        /*store the interpreter on the list*/ 
        InterpreterSingletonList.is.add(i); 
      i.run(); 
        /*remove it (i.run() blocks)*/ 
        InterpreterSingletonList.is.remove(i); 
     } 
     catch(IOException e) { System.out.println(e); } 
    } 
} 
+0

我根據你的建議嘗試了console.print(),但是這似乎將輸出發送到我的應用程序的System.out,而不是控制檯: -/ – sanity 2009-11-26 16:26:40

+0

你將需要使用您在telnet上公開的控制檯,解釋器初始化是默認的非交互式控制檯 – 2009-11-26 16:51:17

+0

如何獲取我在telnet上公開的控制檯,給定我添加到我的問題中的代碼? – sanity 2009-11-27 01:46:54

-1

如果所有應用程序的輸出都是使用某種日誌記錄框架編寫的,那麼可以編寫一個自定義的附加程序/處理程序,它除了記錄日誌以外,還會寫入到beanshell控制檯加成?執行一些beanshell命令後可能啓用和禁用控制檯日誌記錄。

(我不知道的BeanShell之前,但它似乎有用!)

0

我認爲這是不可能的了劈......,對不起,適應遠程登錄服務器實現BSH。

我們正在查看的課程是bsh.util.Sessiond。一旦啓動,它將打開並維護一個telnet服務器。當它接收到一個命令時,它會創建一個新的工作線程,這將創建一個新的帶有正確的輸入和輸出流(從套接字派生)的bsh.Interpreter並運行解釋器。

所以它是有道理的,只有解釋命令的輸出發送到telnet客戶端,因爲System.outSystem.err沒有重定向。

但是,您的情況正是如此:在解釋器運行命令之前將System.outSystem.err重定向到套接字輸出流,並在完成後重置流。

我建議,你bsh.util.Sessiond類複製到類似mybsh.util.DebuggerSessiond,應用重定向代碼內部類SessiondConnection的run方法和修改bsh/commands/server.bsh開始,除了這個「新」 Telnet服務器(或代替原來的一個)。 (我想,這個腳本啓動服務器...)

的源代碼可以在這裏找到:beanshell repository

相關問題