Can I write to the Beanshell console from Java? - 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)

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:
class ClientList {
Integer clients = 0;
public String debugClientList() {
return clients.toString();
}
and then calling it from beanshell
print(clients.debugCientList());
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
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);
}
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:
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); }
}
}

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 and System.err are not redirected.
But that exactly is what has to be done in your case: redirect System.out and System.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 like mybsh.util.DebuggerSessiond, apply the redirection code to the run method of the inner class SessiondConnection and modify bsh/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

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!)

Related

Java shutdown hook is ignored (?) when using HCL Domino NotesThread

I'm currently developing a Vaadin-based program in Java which extracts documents from Domino databases and writes them to a MongoDB collection. The program works perfectly but has one small flaw:
Currently i've found no way to stop the program other then send "KILL" to the process. My shutdown hook/signal handler is totally ignored. I've narrowed down the problem to a single line of code:
NotesThread.sinitThread();
When i remove this line, the hook works perfectly and my program is shutdown properly. When the line is inserted, then the hook is never called.
Here is some example code:
private boolean running = true;
...
#Override
public void run() {
try {
NotesGC.runWithAutoGC(() -> {
NotesThread.sinitThread() // --> "Kills" all signal handling
Session session = NotesFactory.createSession();
while (running) {
Thread.sleep(1000);
System.out.println("Running ...");
}
session.recycle();
return null;
});
} catch (Exception e) {
} finally {
NotesThread.stermThread();
}
}
public void kill() {
System.out.println("Killed!");
this.running = false;
}
...
Signal.handle(new Signal("TERM"), sig -> runner.kill()); // Signal handler from main-method
I've asks friends and colleagues and nobody ever had the same problem.
NotesGC.runWithAutoGC
As I see you are using Domino JNA, a side project.
It use the domino CAPI.
It's open source: https://github.com/klehmann/domino-jna
You can create issue ticket or ask question.
BTW, func "runWithAutoGC" call initThread() in his body.
This link for source code: https://github.com/klehmann/domino-jna/blob/master/domino-jna/src/main/java/com/mindoo/domino/jna/gc/NotesGC.java

ArrayList empty when accessed from separate thread although it is populated.

I have a simple Client/Server Application. I try to access the arraylist from UI but get an empty arraylist in return. I have tried every possible solution on internet but none has worked in my case.
Server.java
import java.net.*;
import java.util.ArrayList;
import java.io.*;
public class Server {
public static ArrayList<MyThread> clients = new ArrayList<MyThread>();
public static void main(String args[]) throws IOException {
ServerSocket s = new ServerSocket(7777);
try {
while (true) {
Socket s1 = s.accept();
MyThread t = new MyThread(s1);
clients.add(t); // adds threads to an ArrayList
System.out.println(clients); // prints the ArrayList(It works and print all threads)
t.start(); //start the thread
}
} catch (SocketException e) {
System.out.println("Error: " + e);
}
}
}
This is a MouseClickeed method in my UI class where I want to access the ArrayList in Server Class
public void mouseClicked(MouseEvent arg0) {
try {
String s = textField.getText();
Client.ClientName = s; \\ gets the string entered and set it as Client Name
System.out.println(Server.clients); \\It's supposed to print Client ArrayList but instead it prints an empty List ([])
}
catch (NullPointerException e1) {
System.out.println("Error: " + e1);
}
}
});
It's look like you try to use objects from Server application in client application with UI.
Server and client app are two different processes.
Server.clients is initialized with values in your server app, and isn't initialized in your client app.
You're not just working with separate threads, you're working with different processes.
The Server process has it's own Server.class instance. The Client is launched in a different java process, it could use the same classes, but they will be different instances, even the static fields will be different in different processes.
If you need data from the Server in the Client, you need some sort of communication. You already have tcp/ip socket, so you could send the list via the socket.
Or you could use some distributed cache library if you want to use this pattern in a large application. E.g. hazelcast or Terracotta DSO

How do I design a program that does completely different tasks concurrently?

I've just got my feet wet with multi-threading and its really awesome. I find myself trying to figure out new ways I can use it make things better and I think I found one but I'm unsure how to design the program for this.
Here's the situation. I have a queue server that multiple clients consume and produce data to but to kick start the process I run a java program on to put some initial data for them to start. then my program is done and I have excess capacity on the queue server but nothing is really running on it. So I want to try to do some maintenance tasks, run a service, and do low priority stuff.I'm not sure how do that though. How do I design a program that does completely different tasks concurrently?
Typically I just wrap my programs in a while (true) loop and it does a single task and I realize I cannot do two while loops at the same time in the same process(maybe nested?). To show a simplified example, I put a bunch of code that runs a runnable(maybe it'll process a low priority queue) and a service that monitors a socket and replies back(I might want to add more depending on cpu usage). How do I get them all to work together? Is there a better way to design it(I know long term its probably better to run multiple java processes but right now I am just trying to manage a single file and I suspect there's a way to give the socket service a higher priority than processing the queue within the file but if they are both running in different files I don't know how to lower one over the other instead of them fighting for resources)?
Thanks and I'll edit this question if it turns out I'm explaining this totally wrong. But in a nutshell, I want it to provide a service to other systems(server socket, in the example) and when its idle I want it to do a few other tasks.
Example(if you understand what I'm asking this code may not be necessary to read):
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class multipleThreads {
private ServerSocket server;
private int port = 7777;
public void ServerSocketExample() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("starting");
ServerSocketExample example = new ServerSocketExample();
example.handleConnection();
while (true) {
//monitor low low priority queue
}
}
public void handleConnection() {
System.out.println("Waiting for client message...");
//
// The server do a loop here to accept all connection initiated by the
// client application.
//
while (true) {
try {
Socket socket = server.accept();
new ConnectionHandler(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable {
private Socket socket;
public ConnectionHandler(Socket socket) {
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run() {
try
{
//
// Read a message sent by client application
//
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message Received: " + message);
//
// Send a response information to the client application
//
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi...");
ois.close();
oos.close();
socket.close();
System.out.println("Waiting for client message...");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class MonitorQueue implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
//do work when stuff comes in the queue
}
}
I strongly recommend you take a look at this project: Java Concurrent Animated. I found this probably the best way to get my head around concurrency concepts in Java: it's animated, interactive, and you can just take one concept at a time and get a good understanding.
http://sourceforge.net/projects/javaconcurrenta/
Take a look at the java.util.concurrent package. It's full off goodies for doing exactly the kinds of things you describe.
In particular, check out the Executors factory class which lets you build Thread Pools that allow multiple tasks to be scheduled and run concurrently on any number of Threads you specify.
Oracle has some great tutorials on using Executors:
http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html
Concurrency is hard, you can read Java Concurrency in Practice, but even the experts have difficulties.
Look for a training course in your area.
I would like to recommend Concurrency Specialist Courses which is based on Java Concurrency in Practice and endorsed by the author, Brian Goetz

What is the best way to manage text-based client-server connections?

I'm looking to write a small client-server-based text game that handles multiple client connections and persistently affects a game state. I'm wondering what the best way would be to handle multiple connects such that commands are processed in the order they arrive at the server.
Ideally I'm not looking to take advantage of multi-threading, at least on the command processing level. I would be okay with each client having a separate thread (in order to have blocking IO on each thread), as long as I could unify the processing in a single thread thereafter.
Since the only communication between the client and server will be text, I'm not sure how best to go about setting up the communication. If I chose blocking IO, how would I get queue the processing to occur in a single thread?
Alternatively, if I choose non-blocking IO and use a selector to query for when clients have written to the server, how can I get read a String of unknown/unlimited length without using a set-size ByteBuffer? Non-blocking also favours keeping the processing in a single thread as it can just read from the client connections as and when they send new data. However, when I tried to implement it with read/writeUTF I came up against the IllegalBlockingModeException heh.
Any answers to the questions or suggestions on how to do this in a way I haven't mentioned would be sincerely appreciated! I'm fairly new to clients and servers so I don't know whether java.io or java.nio would be most appropriate.
Sorry for the convoluted question. I think I ran away with myself.
Opinions differ, but I'd definitely go with a single thread per client. The communication to the single processing thread could then go via a LinkedBlockingQueue, or just a synchronized LinkedList.
Something like this on the per-client thread:
public class Client implements Runnable, ResponseOutput {
private final BufferedReader br;
private final PrintWriter pw;
public Client(Socket s) {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream());
}
// defined by the ResponseOutput interface
public void sendReply(String reply) {
pw.println(reply);
}
public void run() {
try {
while (true) {
String s = br.readLine();
if (s==null)
break;
Processor.queue(new Processor.InputItem(this, s));
}
} catch (IOException ioe) {
... error handling ...
}
}
}
Then this for the processing:
public class Processor implements Runnable {
static public class InputItem {
final ResponseOutput client;
final String command;
public InputItem(ResponseOutput client, String command) {
this.client = client;
this.command = command;
}
}
static private Processor instance;
static public void queue(InputItem item) {
instance.commandQueue.add(item);
}
private BlockingQueue<InputItem> commandQueue;
public void run() {
try {
while (true) {
InputItem item = commandQueue.take();
String reply = doStuff(item.command);
item.client.sendReply(reply);
}
} catch (InterruptedException ie) {
... error handling ....
}
}
}
Within the InputItem class, you can also include a reference to any game state that needs updating. Since there's only the processing thread changing it, you get to do that without any synchronization.
i'm no expert in sever client systems but I'll share a couple of tips
Depending on your need you could simply set up a Tomcat server and do http request, its fairly straight forwards and of course all in Java.
the downside is that the request might be a bit slow.
The Second option you can check out is RMI.
The concept is simple you connect to another computer and when that is done you call methods on the other computer from a local object in you code.
http://java.sun.com/developer/onlineTraining/rmi/RMI.html
it might look a bit complicated (and sometimes debbuging a stack through multiple computer is a bit tricky) but I recommend because it keeps your code clear.
Finally you can try sockets but there your on your own :P

Testing Java Sockets

I'm developing a network application and I want to get unit testing right. THIS time we'll do it, you know? :)
I'm have trouble testing network connections, though.
In my application I use plain java.net.Sockets.
For example:
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Message {
byte[] payload;
public Message(byte[] payload) {
this.payload = payload;
}
public boolean sendTo(String hostname, int port) {
boolean sent = false;
try {
Socket socket = new Socket(hostname, port);
OutputStream out = socket.getOutputStream();
out.write(payload);
socket.close();
sent = true;
} catch (UnknownHostException e) {
} catch (IOException e) {
}
return sent;
}
}
I read about mocking but am not sure how to apply it.
If I was to test the code, I'd do the following.
Firstly, refactor the code so that the Socket isn't directly instantiated in the method you want to test. The example below shows the smallest change I can think of to make that happen. Future changes might factor out the Socket creation to a completely separate class, but I like small steps and I don't like making big changes on untested code.
public boolean sendTo(String hostname, int port) {
boolean sent = false;
try {
Socket socket = createSocket();
OutputStream out = socket.getOutputStream();
out.write(payload);
socket.close();
sent = true;
} catch (UnknownHostException e) {
// TODO
} catch (IOException e) {
// TODO
}
return sent;
}
protected Socket createSocket() {
return new Socket();
}
Now that the socket creation logic is outside of the method you are trying to test, you can start to mock things up and hook into the creation the socket.
public class MessageTest {
#Test
public void testSimplePayload() () {
byte[] emptyPayload = new byte[1001];
// Using Mockito
final Socket socket = mock(Socket.class);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
when(socket.getOutputStream()).thenReturn(byteArrayOutputStream);
Message text = new Message(emptyPayload) {
#Override
protected Socket createSocket() {
return socket;
}
};
Assert.assertTrue("Message sent successfully", text.sendTo("localhost", "1234"));
Assert.assertEquals("whatever you wanted to send".getBytes(), byteArrayOutputStream.toByteArray());
}
}
Overriding individual methods on units you want to test is really useful for testing, especially in ugly code with horrible dependencies. Obviously the best solution is sorting out dependencies (in this case I would think that a Message not depend on a Socket, maybe there is a Messager interface as glowcoder suggests), but it's nice to move towards the solution in the smallest possible steps.
I'm going to answer your question as asked instead of redesigning your class (others have that covered, but the basic question on the class as written is stil valid).
Unit testing never tests anything outside the class being tested. This hurt my brain for a while--it means unit test does not in any way prove that your code works! What it does is prove that your code works the same way it did when you wrote the test.
So that said you want a unit test for this class but you also want a functional test.
For the unit test you have to be able to "Mock out" the communications. To do this instead of creating your own socket, fetch one from a "Socket factory", then make yourself a socket factory. The factory should be passed in to the constructor of this class you are testing. This is actually not a bad design strategy--you can set the hostname and port in the factory so you don't have to know about them in your communication class--more abstract.
Now in testing you just pass in a mock factory that creates mock sockets and everything is roses.
Don't forget the functional test though! Set up a "test server" that you can connect to, send some messages to the server and test the responses you get back.
For that matter, you probably want to do even deeper functional tests where you write a client that sends the REAL server some scripted commands and tests the results. You probably even want to create a "Reset state" command just for functional testing. Functional tests actually ensure that entire "Functional units" work together as you expect--something that many unit testing advocates forget.
I'm not going to say this is a bad idea.
I am going to say it can be improved upon.
If you're sending across a raw byte[] over your socket, the other side can do whatever it wants with it. Now, if you're not connecting to a Java server, then you might NEED to do that. If you're willing to say "I'm always working with a Java server" then you can use serialization to your advantage.
When you do this, you can mock it by just creating your own Sendable objects as if they came across the wire.
Create one socket, not one for every message.
interface Sendable {
void callback(Engine engine);
}
So how does this work in practice?
Messenger class:
/**
* Class is not thread-safe. Synchronization left as exercise to the reader
*/
class Messenger { // on the client side
Socket socket;
ObjectOutputStream out;
Messenger(String host, String port) {
socket = new Socket(host,port);
out = new ObjectOutputStream(socket.getOutputStream());
}
void sendMessage(Sendable message) {
out.writeObject(message);
}
}
Receiver class:
class Receiver extends Thread { // on the server side
Socket socket;
ObjectInputStream in;
Engine engine; // whatever does your logical data
Receiver(Socket socket, Engine engine) { // presumable from new Receiver(serverSocket.accept());
this.socket = socket;
this.in = new ObjectInputStream(socket.getInputStream());
}
#Override
public void run() {
while(true) {
// we know only Sendables ever come across the wire
Sendable message = in.readObject();
message.callback(engine); // message class has behavior for the engine
}
}
}
It's difficult testing connection and server interactions.
Tipically, I isolate business logic from communication logic.
I create scenarios for unit tests on business logic, these tests are automatic (use JUni,t and Maven) and i create other scenarios to test real connections, I don't use framework like JUnit for these tests.
In last year I've used Spring Mocks to test logic with HttpResponse HttpRequest, but I think this is not useful.
I follow this question.
Bye

Categories