我可以从 Java 写入 Beanshell 控制台吗?
我在我的应用程序中使用 Beanshell 作为嵌入式调试工具。这意味着我可以 telnet 到我的应用程序并在其运行时查看其内部结构(我通常使用 rlwrap 包装 telnet 会话)。
问题是我发现打印到 Beanshell 控制台(而不是应用程序本身的标准输出)的唯一方法是 Beanshell 中的 print() 方法。
但我想用 Java 编写可以从 Beanshell 调用的代码,该代码将输出到 Beanshell 控制台 - 即。它将显示在我的 telnet 会话中,而不是发送到应用程序的标准输出,就像您尝试使用 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 会话(而不是我的应用程序的 System.out)的 Java 函数
I'm using Beanshell as an embedded debugging tool in my app. It means I can telnet to my app and poke around with its internals while it is running (I typically wrap the telnet session with rlwrap).
The problem is that the only way I've found to print to the Beanshell console, rather than stdout of the application itself, is the print() method within Beanshell.
But I'd like to write code in Java that I can call from Beanshell, which will output to the Beanshell console - ie. it will be shown in my telnet session, not sent to stdout of the application, as happens if you try to use System.out or System.err.
Is this possible?
edit: To further clarify, I'm setting up a Beanshell server as follows:
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);
}
}
How would I modify this such that I can write a Java function that outputs to the telnet session (rather than to System.out of my application)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会将其复制到那里,因为现在看来评论已被忽略。
你可以:
而不是使用将调试信息打印到标准输出的方法返回该调试信息:
然后从 beanshell 调用它将
为您提供 telnet 上的输出
,或者如果您需要更像记录器的输出,则需要直接与 Interpreter 对象交互
我正在回复评论,因为它需要更多编码; telnet 实现对每个连接使用不同的解释器,因此您必须将该解释器公开给对象以打印到 telnet 客户端。最快的方法是更改默认 telnet 服务器中的一些位并使用修改后的服务器来启动服务器,而不是使用 server() 脚本命令(它遵循 lgpl 或 sun 许可条款)
请注意,这种方式可以启动解释器每个连接;简单快速的解决方法是维护所有正在运行的解释器的列表并向每个解释器打印调试信息,因此:
I'll copy it there as it seems that comments are disregarded this days.
you can:
instead of having a method which print debug information to the standard output returns that debug information:
and then calling it from beanshell
will give you an output on your telnet
or if you need it more logger like, you need to interact with the Interpreter object directly
I'm replying there to the comment as it will need some more coding; the telnet implementation uses a different interpreter for each connection, so you have to expose that interpreter to the objects for printing to the telnet client. The quickest way is to change some bit in the default telnet server and use the modified one to start your server, instead of using the server() scripted command (it's under lgpl or sun license terms)
note that this way have an interpreter started for each connection; the easy and quick fix is to maintain a list of all the running interpreters and print to each one the debugging information, so:
我认为没有 hack 是不可能的...,抱歉,调整了 BSH 的 telnet 服务器实现。
我们正在查看的类是bsh.util.Sessiond。一旦启动,它就会打开并维护一个 telnet 服务器。当它收到命令时,它会创建一个新的工作线程,这会创建一个具有正确输入和输出流(从套接字派生)的新 bsh.Interpreter 并运行解释器。
因此,只有解释命令的输出才会发送到 telnet 客户端,因为
System.out
和System.err
不会被重定向。但这正是您的情况必须要做的:在解释器运行命令并重置流之前将
System.out
和System.err
重定向到套接字输出流完成后。我建议您将
bsh.util.Sessiond
类复制到mybsh.util.DebuggerSessiond
之类的内容,将重定向代码应用于内部类 SessiondConnection 的 run 方法并修改bsh/commands/server.bsh
以另外启动此“新”telnet 服务器(或代替原始服务器)。 (我猜,这个脚本启动服务器...)源代码可以在这里找到: beanshell 存储库
I think it's not possible with out hack..., sorry, adapting the telnet server implementation of BSH.
The class we're looking at is
bsh.util.Sessiond
. Once started, it opens and maintains a telnet server. When ever it receives a command, it creates a new worker thread, this on creates a new bsh.Interpreter with the correct input and output streams (derived from the socket) and runs the interpreter.So it makes sense, that only output of interpreted commands is send to the telnet client, because
System.out
andSystem.err
are not redirected.But that exactly is what has to be done in your case: redirect
System.out
andSystem.err
to the sockets output stream before the interpreter runs the command and reset the streams after completion.I'd suggest, you copy the
bsh.util.Sessiond
class to something likemybsh.util.DebuggerSessiond
, apply the redirection code to the run method of the inner class SessiondConnection and modifybsh/commands/server.bsh
to start this 'new' telnet server in addition (or instead of the original one). (I guess, this script starts the servers...)Source code can be found here: beanshell repository
如果您的应用程序的所有输出都是使用某些日志记录框架编写的,那么您可以编写一个自定义附加程序/处理程序,除了记录日志之外,还可以将文件写入 beanshell 控制台吗?执行某些 beanshell 命令后可能启用和禁用控制台日志记录。
(我以前不知道beanshell,但它似乎很有用!)
If all your application's output is written using some logging framework anyways, you could write a custom appender/handler which besides logging to say a file would write to the beanshell console in addition? Possibly enabling and disabling the console-logging after executing some beanshell command.
(I wasn't aware of beanshell before, but it seems useful!)