1. added J2sePlatform for StandardLuaJVM to use J2SE DebugNetSupportImpl
This commit is contained in:
@@ -91,10 +91,10 @@ public class DebugLuaState extends LuaState implements DebugRequestListener {
|
|||||||
if (debugSupport != null)
|
if (debugSupport != null)
|
||||||
setDebugSupport(debugSupport);
|
setDebugSupport(debugSupport);
|
||||||
else
|
else
|
||||||
System.out.println("Warning: DebugNetSupportBase is not implemented.");
|
System.out.println("Warning: DebugNetSupport is missing. Cannot communicate with a debugging client.");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// no debug client can talk to VM, but VM can continue functioning
|
// no debug client can talk to VM, but VM can continue functioning
|
||||||
System.out.println("Warning: no debug client support due to error: " + e.getMessage());
|
System.out.println("Warning: cannot communicate with a debugging client due to error: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ public class DebugMessageType extends EnumType {
|
|||||||
public static final DebugMessageType disconnected = new DebugMessageType("disconnected", 34);
|
public static final DebugMessageType disconnected = new DebugMessageType("disconnected", 34);
|
||||||
public static final DebugMessageType sessionId = new DebugMessageType("sessionId", 35);
|
public static final DebugMessageType sessionId = new DebugMessageType("sessionId", 35);
|
||||||
public static final DebugMessageType debugServiceDown = new DebugMessageType("debugServiceDown", 36);
|
public static final DebugMessageType debugServiceDown = new DebugMessageType("debugServiceDown", 36);
|
||||||
|
public static final DebugMessageType outputRedirect = new DebugMessageType("outputRedirect", 37);
|
||||||
|
|
||||||
protected static DebugMessageType[] ENUMS = new DebugMessageType[] {
|
protected static DebugMessageType[] ENUMS = new DebugMessageType[] {
|
||||||
start,
|
start,
|
||||||
@@ -104,7 +105,8 @@ public class DebugMessageType extends EnumType {
|
|||||||
clientRequestGlobalReply,
|
clientRequestGlobalReply,
|
||||||
disconnected,
|
disconnected,
|
||||||
sessionId,
|
sessionId,
|
||||||
debugServiceDown
|
debugServiceDown,
|
||||||
|
outputRedirect
|
||||||
};
|
};
|
||||||
|
|
||||||
protected DebugMessageType(String name, int ordinal) {
|
protected DebugMessageType(String name, int ordinal) {
|
||||||
|
|||||||
57
src/debug/org/luaj/debug/RedirectOutputStream.java
Normal file
57
src/debug/org/luaj/debug/RedirectOutputStream.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package org.luaj.debug;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.luaj.debug.event.DebugEventListener;
|
||||||
|
import org.luaj.debug.event.DebugEventOutputRedirect;
|
||||||
|
|
||||||
|
public class RedirectOutputStream extends OutputStream {
|
||||||
|
|
||||||
|
protected DebugEventListener listener;
|
||||||
|
protected int count;
|
||||||
|
protected byte[] buffer;
|
||||||
|
|
||||||
|
public RedirectOutputStream(DebugEventListener listener) {
|
||||||
|
this(listener, 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RedirectOutputStream(DebugEventListener listener, int count) {
|
||||||
|
this.listener = listener;
|
||||||
|
this.count = 0;
|
||||||
|
this.buffer = new byte[count];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void flush() throws IOException {
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
super.write(b, off, len);
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] b) throws IOException {
|
||||||
|
super.write(b);
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void write(int b) throws IOException {
|
||||||
|
if (count >= buffer.length) {
|
||||||
|
flushBuffer();
|
||||||
|
}
|
||||||
|
buffer[count++] = (byte)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized void flushBuffer(){
|
||||||
|
if (count > 0) {
|
||||||
|
String msg = new String(buffer, 0, this.count);
|
||||||
|
listener.notifyDebugEvent(new DebugEventOutputRedirect(msg));
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
import org.luaj.debug.event.DebugEventBreakpoint;
|
||||||
import org.luaj.debug.event.DebugEventError;
|
import org.luaj.debug.event.DebugEventError;
|
||||||
|
import org.luaj.debug.event.DebugEventOutputRedirect;
|
||||||
import org.luaj.debug.request.DebugRequestDisconnect;
|
import org.luaj.debug.request.DebugRequestDisconnect;
|
||||||
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
import org.luaj.debug.request.DebugRequestLineBreakpointToggle;
|
||||||
import org.luaj.debug.request.DebugRequestStack;
|
import org.luaj.debug.request.DebugRequestStack;
|
||||||
@@ -59,6 +60,7 @@ public class SerializationHelper {
|
|||||||
static final int SERIAL_TYPE_DebugResponseVariables = 12;
|
static final int SERIAL_TYPE_DebugResponseVariables = 12;
|
||||||
static final int SERIAL_TYPE_DebugResponseStack = 13;
|
static final int SERIAL_TYPE_DebugResponseStack = 13;
|
||||||
static final int SERIAL_TYPE_DebugResponseSession = 14;
|
static final int SERIAL_TYPE_DebugResponseSession = 14;
|
||||||
|
static final int SERIAL_TYPE_DebugEventOutputRedirect = 15;
|
||||||
|
|
||||||
public static void serialize(Serializable object, DataOutputStream dout)
|
public static void serialize(Serializable object, DataOutputStream dout)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@@ -93,6 +95,9 @@ public class SerializationHelper {
|
|||||||
} else if (object instanceof DebugEventError) {
|
} else if (object instanceof DebugEventError) {
|
||||||
dout.writeInt(SERIAL_TYPE_DebugEventError);
|
dout.writeInt(SERIAL_TYPE_DebugEventError);
|
||||||
DebugEventError.serialize(dout, (DebugEventError) object);
|
DebugEventError.serialize(dout, (DebugEventError) object);
|
||||||
|
} else if (object instanceof DebugEventOutputRedirect) {
|
||||||
|
dout.writeInt(SERIAL_TYPE_DebugEventOutputRedirect);
|
||||||
|
DebugEventOutputRedirect.serialize(dout, (DebugEventOutputRedirect) object);
|
||||||
} else if (object instanceof DebugResponseStack) {
|
} else if (object instanceof DebugResponseStack) {
|
||||||
dout.writeInt(SERIAL_TYPE_DebugResponseStack);
|
dout.writeInt(SERIAL_TYPE_DebugResponseStack);
|
||||||
DebugResponseStack.serialize(dout, (DebugResponseStack) object);
|
DebugResponseStack.serialize(dout, (DebugResponseStack) object);
|
||||||
@@ -152,6 +157,9 @@ public class SerializationHelper {
|
|||||||
case SERIAL_TYPE_DebugEventError:
|
case SERIAL_TYPE_DebugEventError:
|
||||||
object = DebugEventError.deserialize(din);
|
object = DebugEventError.deserialize(din);
|
||||||
break;
|
break;
|
||||||
|
case SERIAL_TYPE_DebugEventOutputRedirect:
|
||||||
|
object = DebugEventOutputRedirect.deserialize(din);
|
||||||
|
break;
|
||||||
case SERIAL_TYPE_DebugResponseCallgraph:
|
case SERIAL_TYPE_DebugResponseCallgraph:
|
||||||
object = DebugResponseCallgraph.deserialize(din);
|
object = DebugResponseCallgraph.deserialize(din);
|
||||||
break;
|
break;
|
||||||
|
|||||||
40
src/debug/org/luaj/debug/event/DebugEventOutputRedirect.java
Normal file
40
src/debug/org/luaj/debug/event/DebugEventOutputRedirect.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package org.luaj.debug.event;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.luaj.debug.DebugMessage;
|
||||||
|
import org.luaj.debug.DebugMessageType;
|
||||||
|
|
||||||
|
public class DebugEventOutputRedirect extends DebugMessage {
|
||||||
|
protected String data;
|
||||||
|
|
||||||
|
public DebugEventOutputRedirect(String data) {
|
||||||
|
super(DebugMessageType.outputRedirect);
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOutput() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return type.toString() + ": " + this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void serialize(DataOutputStream out, DebugEventOutputRedirect event)
|
||||||
|
throws IOException {
|
||||||
|
out.writeUTF(event.getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DebugMessage deserialize(DataInputStream in) throws IOException {
|
||||||
|
String data = in.readUTF();
|
||||||
|
return new DebugEventOutputRedirect(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/debug/org/luaj/debug/j2se/J2sePlatform.java
Normal file
37
src/debug/org/luaj/debug/j2se/J2sePlatform.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package org.luaj.debug.j2se;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
import org.luaj.debug.net.j2se.DebugSupportImpl;
|
||||||
|
import org.luaj.vm.DebugNetSupport;
|
||||||
|
import org.luaj.vm.Platform;
|
||||||
|
|
||||||
|
public class J2sePlatform extends Platform {
|
||||||
|
public Reader createReader(InputStream inputStream) {
|
||||||
|
return new InputStreamReader(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream openFile(String fileName) {
|
||||||
|
return getClass().getResourceAsStream("/" + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assumes J2SE platform, return the corresponding system
|
||||||
|
* property
|
||||||
|
*/
|
||||||
|
public String getProperty(String propertyName) {
|
||||||
|
return System.getProperty(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a J2SE DebugSupport instance.
|
||||||
|
*/
|
||||||
|
public DebugNetSupport getDebugSupport() throws IOException {
|
||||||
|
int port = getDebugPort();
|
||||||
|
DebugSupportImpl debugSupport = new DebugSupportImpl(port);
|
||||||
|
return debugSupport;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ import org.luaj.vm.LValue;
|
|||||||
import org.luaj.vm.LoadState;
|
import org.luaj.vm.LoadState;
|
||||||
import org.luaj.vm.LuaErrorException;
|
import org.luaj.vm.LuaErrorException;
|
||||||
import org.luaj.vm.LuaState;
|
import org.luaj.vm.LuaState;
|
||||||
|
import org.luaj.vm.Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StandardLuaJVM executes a lua program in normal run mode or debug mode.
|
* StandardLuaJVM executes a lua program in normal run mode or debug mode.
|
||||||
@@ -171,6 +172,8 @@ public class StandardLuaJVM {
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
// new lua debug state
|
// new lua debug state
|
||||||
|
Platform.setInstance(new J2sePlatform());
|
||||||
|
|
||||||
state = LuaState.newState();
|
state = LuaState.newState();
|
||||||
init(state);
|
init(state);
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ import javax.microedition.io.SocketConnection;
|
|||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
import org.luaj.debug.DebugMessage;
|
||||||
import org.luaj.debug.DebugMessageType;
|
import org.luaj.debug.DebugMessageType;
|
||||||
|
import org.luaj.debug.RedirectOutputStream;
|
||||||
import org.luaj.debug.SerializationHelper;
|
import org.luaj.debug.SerializationHelper;
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
import org.luaj.debug.event.DebugEventListener;
|
||||||
import org.luaj.debug.response.DebugResponseSession;
|
import org.luaj.debug.response.DebugResponseSession;
|
||||||
|
import org.luaj.lib.BaseLib;
|
||||||
|
|
||||||
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
||||||
private static final boolean TRACE = true; //(null != System.getProperty("TRACE"));
|
private static final boolean TRACE = true; //(null != System.getProperty("TRACE"));
|
||||||
@@ -26,6 +28,8 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
protected DataInputStream inStream;
|
protected DataInputStream inStream;
|
||||||
protected DataOutputStream outStream;
|
protected DataOutputStream outStream;
|
||||||
|
|
||||||
|
protected RedirectOutputStream redirectOutputStream;
|
||||||
|
|
||||||
public ClientConnectionTask(String host, int port, DebugSupportImpl debugSupport) {
|
public ClientConnectionTask(String host, int port, DebugSupportImpl debugSupport) {
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
@@ -59,6 +63,10 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
if ( TRACE )
|
if ( TRACE )
|
||||||
System.out.println("LuaJ debug server connected to " + host + ":" + port);
|
System.out.println("LuaJ debug server connected to " + host + ":" + port);
|
||||||
|
|
||||||
|
// to redirect the print to the debug client console
|
||||||
|
this.redirectOutputStream = new RedirectOutputStream(this);
|
||||||
|
BaseLib.redirectOutput( redirectOutputStream );
|
||||||
|
|
||||||
// loop for incoming requests
|
// loop for incoming requests
|
||||||
while ( !isDisconnected() ) {
|
while ( !isDisconnected() ) {
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
@@ -85,6 +93,13 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
|
|
||||||
debugSupport.disconnect(1);
|
debugSupport.disconnect(1);
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
redirectOutputStream.close();
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
|
||||||
|
// restore the print output
|
||||||
|
BaseLib.restoreStandardOutput();
|
||||||
|
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,11 @@ import java.net.Socket;
|
|||||||
|
|
||||||
import org.luaj.debug.DebugMessage;
|
import org.luaj.debug.DebugMessage;
|
||||||
import org.luaj.debug.DebugMessageType;
|
import org.luaj.debug.DebugMessageType;
|
||||||
|
import org.luaj.debug.RedirectOutputStream;
|
||||||
import org.luaj.debug.SerializationHelper;
|
import org.luaj.debug.SerializationHelper;
|
||||||
import org.luaj.debug.event.DebugEventListener;
|
import org.luaj.debug.event.DebugEventListener;
|
||||||
import org.luaj.debug.response.DebugResponseSession;
|
import org.luaj.debug.response.DebugResponseSession;
|
||||||
|
import org.luaj.lib.BaseLib;
|
||||||
|
|
||||||
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
public class ClientConnectionTask implements Runnable, DebugEventListener {
|
||||||
private static final boolean TRACE = (null != System.getProperty("TRACE"));
|
private static final boolean TRACE = (null != System.getProperty("TRACE"));
|
||||||
@@ -23,6 +25,7 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
protected DataOutputStream eventWriter;
|
protected DataOutputStream eventWriter;
|
||||||
protected DebugSupportImpl debugSupport;
|
protected DebugSupportImpl debugSupport;
|
||||||
protected boolean isDisposed = false;
|
protected boolean isDisposed = false;
|
||||||
|
protected RedirectOutputStream redirectOutputStream;
|
||||||
|
|
||||||
public ClientConnectionTask(DebugSupportImpl debugSupport, Socket socket)
|
public ClientConnectionTask(DebugSupportImpl debugSupport, Socket socket)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
@@ -60,6 +63,10 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
// to redirect the print to the debug client console
|
||||||
|
this.redirectOutputStream = new RedirectOutputStream(this);
|
||||||
|
BaseLib.redirectOutput( redirectOutputStream );
|
||||||
|
|
||||||
// loop for incoming requests
|
// loop for incoming requests
|
||||||
while (!isDisconnected()) {
|
while (!isDisconnected()) {
|
||||||
byte[] data = null;
|
byte[] data = null;
|
||||||
@@ -87,6 +94,13 @@ public class ClientConnectionTask implements Runnable, DebugEventListener {
|
|||||||
|
|
||||||
debugSupport.disconnect(getSessionId());
|
debugSupport.disconnect(getSessionId());
|
||||||
} finally {
|
} finally {
|
||||||
|
try {
|
||||||
|
redirectOutputStream.close();
|
||||||
|
} catch (IOException ignore) {}
|
||||||
|
|
||||||
|
// restore the print output
|
||||||
|
BaseLib.restoreStandardOutput();
|
||||||
|
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.io.IOException;
|
|||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.luaj.debug.event.DebugEventBreakpoint;
|
import org.luaj.debug.event.DebugEventBreakpoint;
|
||||||
|
import org.luaj.debug.event.DebugEventOutputRedirect;
|
||||||
|
|
||||||
public class DebugEventTest extends TestCase {
|
public class DebugEventTest extends TestCase {
|
||||||
public void testDebugEventSerialization() {
|
public void testDebugEventSerialization() {
|
||||||
@@ -34,4 +35,17 @@ public class DebugEventTest extends TestCase {
|
|||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDebugEventOutputRedirectSerialization() {
|
||||||
|
try {
|
||||||
|
String msg = "This is a testing message";
|
||||||
|
DebugEventOutputRedirect redirectEvent = new DebugEventOutputRedirect(msg);
|
||||||
|
byte[] data = SerializationHelper.serialize(redirectEvent);
|
||||||
|
DebugEventOutputRedirect redirectEventOut = (DebugEventOutputRedirect)
|
||||||
|
SerializationHelper.deserialize(data);
|
||||||
|
assertEquals(msg, redirectEventOut.getOutput());
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/test/java/org/luaj/debug/RedirectOutputStreamTest.java
Normal file
24
src/test/java/org/luaj/debug/RedirectOutputStreamTest.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package org.luaj.debug;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.luaj.debug.event.DebugEventListener;
|
||||||
|
|
||||||
|
public class RedirectOutputStreamTest extends TestCase {
|
||||||
|
public void testRedirectOutputStream() {
|
||||||
|
RedirectOutputStream redirectOut = new RedirectOutputStream(
|
||||||
|
new DebugEventListener(){
|
||||||
|
public void notifyDebugEvent(DebugMessage event) {
|
||||||
|
assertEquals(event.toString(), "outputRedirect: true\r\na");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
PrintWriter writer = new PrintWriter(redirectOut);
|
||||||
|
writer.print(true);
|
||||||
|
writer.println();
|
||||||
|
writer.print('a');
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user