我在我的应用程序中使用 Beanshell 作为嵌入式调试工具。这意味着我可以 telnet 到我的应用程序并在它运行时查看它的内部结构(我通常使用 rlwrap 包装 telnet session )。
问题是我发现打印到 Beanshell 控制台的唯一方法,而不是应用程序本身的标准输出,是 Beanshell 中的 print() 方法。
但我想用 Java 编写可以从 Beanshell 调用的代码,它将输出到 Beanshell 控制台 - 即。它将显示在我的 telnet session 中,而不是发送到应用程序的标准输出,就像您尝试使用 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);
}
}
我将如何修改它以便我可以编写一个 Java 函数输出到 telnet session (而不是我的应用程序的 System.out)
最佳答案
我会把它复制到那里,因为这些天似乎忽略了评论。
您可以: 而不是使用将调试信息打印到标准输出的方法返回该调试信息:
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); }
}
}
关于java - 我可以从 Java 写入 Beanshell 控制台吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1760917/