java - 我可以从 Java 写入 Beanshell 控制台吗?

标签 java beanshell

我在我的应用程序中使用 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/

相关文章:

java - 如何将 currentTimeMillis 转换为可读的日期格式?

java - 无法从 web.xml 读取上下文参数

java - Jmeter 中的 Bean shell 实用程序

java - 在beanshell脚本中提取json值

java - 编译器说有一个无法访问的语句,我做错了什么?

java - 如何使用 Firebird 的 jaybird JDBC 驱动程序将绑定(bind)值设置为 NULL?

java - 带扩展的通配符

java - 从数组中获取随机列表?

jenkins - JMeter:来自 Jenkins 的九个以上参数

jmeter - 如何在JMeter中使用beanshell生成哈希(SHA1)?