Skip to content

Commit b10e954

Browse files
authored
Merge pull request #20 from subes/master
Support for adding writers to capture matlab process output for debugging purposes
2 parents 66ae5ea + 3954d65 commit b10e954

2 files changed

Lines changed: 63 additions & 8 deletions

File tree

src/matlabcontrol/MatlabProxyFactoryOptions.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package matlabcontrol;
77

88
import java.io.File;
9+
import java.io.Writer;
910
import java.util.concurrent.atomic.AtomicLong;
1011

1112
import matlabcontrol.MatlabProxyFactory.CopyPasteCallback;
@@ -32,6 +33,8 @@ public class MatlabProxyFactoryOptions {
3233
private final String _licenseFile;
3334
private final boolean _useSingleCompThread;
3435
private final int _port;
36+
private final Writer _outputWriter;
37+
private final Writer _errorWriter;
3538

3639
private MatlabProxyFactoryOptions(Builder options) {
3740
_matlabLocation = options._matlabLocation;
@@ -46,6 +49,8 @@ private MatlabProxyFactoryOptions(Builder options) {
4649
_licenseFile = options._licenseFile;
4750
_useSingleCompThread = options._useSingleCompThread;
4851
_port = options._port;
52+
_outputWriter = options._outputWriter;
53+
_errorWriter = options._errorWriter;
4954
}
5055

5156
String getMatlabLocation() {
@@ -96,6 +101,14 @@ int getPort() {
96101
return _port;
97102
}
98103

104+
Writer getOutputWriter() {
105+
return _outputWriter;
106+
}
107+
108+
Writer getErrorWriter() {
109+
return _errorWriter;
110+
}
111+
99112
/**
100113
* Creates instances of {@link MatlabProxyFactoryOptions}. Any and all of these properties may be left unset, if so
101114
* then a default will be used. Depending on how the factory operates, not all properties may be used. Currently all
@@ -127,6 +140,8 @@ public static class Builder {
127140
private volatile String _licenseFile = null;
128141
private volatile boolean _useSingleCompThread = false;
129142
private volatile int _port = 2100;
143+
private volatile Writer _outputWriter = null;
144+
private volatile Writer _errorWriter = null;
130145

131146
//Assigning to a long is not atomic, so use an AtomicLong so that a thread always sees an intended value
132147
private final AtomicLong _proxyTimeout = new AtomicLong(180000L);
@@ -387,6 +402,30 @@ public final Builder setPort(int port) {
387402
return this;
388403
}
389404

405+
/**
406+
* Sets the output writer where the standard output of the created matlab process is written to.
407+
* This is only used when an actual process is spawned for the matlab proxy instance.
408+
*
409+
* @param outputWriter
410+
*/
411+
public final Builder setOutputWriter(Writer outputWriter) {
412+
_outputWriter = outputWriter;
413+
414+
return this;
415+
}
416+
417+
/**
418+
* Sets the error writer where the error output of the created matlab process is written to.
419+
* This is only used when an actual process is spawned for the matlab proxy instance.
420+
*
421+
* @param errorWriter
422+
*/
423+
public final Builder setErrorWriter(Writer errorWriter) {
424+
_errorWriter = errorWriter;
425+
426+
return this;
427+
}
428+
390429
/**
391430
* Builds a {@code MatlabProxyFactoryOptions} instance.
392431
*
@@ -396,4 +435,5 @@ public final MatlabProxyFactoryOptions build() {
396435
return new MatlabProxyFactoryOptions(this);
397436
}
398437
}
438+
399439
}

src/matlabcontrol/RemoteMatlabProxyFactory.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
import java.io.IOException;
99
import java.io.InputStream;
10+
import java.io.InputStreamReader;
11+
import java.io.Reader;
12+
import java.io.Writer;
13+
import java.nio.charset.Charset;
1014
import java.rmi.AlreadyBoundException;
1115
import java.rmi.NoSuchObjectException;
1216
import java.rmi.NotBoundException;
@@ -270,8 +274,8 @@ private Process createProcess(RemoteRequestReceiver receiver) throws MatlabConne
270274

271275
//If running under UNIX and MATLAB is hidden these streams need to be read so that MATLAB does not block
272276
if (_options.getHidden() && !Configuration.isWindows()) {
273-
new ProcessStreamDrainer(process.getInputStream(), "Input").start();
274-
new ProcessStreamDrainer(process.getErrorStream(), "Error").start();
277+
new ProcessStreamDrainer(process.getInputStream(), "Output", _options.getOutputWriter()).start();
278+
new ProcessStreamDrainer(process.getErrorStream(), "Error", _options.getErrorWriter()).start();
275279
}
276280

277281
return process;
@@ -309,10 +313,12 @@ private String getRunArg(RemoteRequestReceiver receiver) throws MatlabConnection
309313
* blocking.
310314
*/
311315
private static class ProcessStreamDrainer extends Thread {
312-
private final InputStream _stream;
316+
private final Reader _reader;
317+
private final Writer _writer;
313318

314-
private ProcessStreamDrainer(InputStream stream, String type) {
315-
_stream = stream;
319+
private ProcessStreamDrainer(InputStream stream, String type, Writer writer) {
320+
_reader = new InputStreamReader(stream, Charset.defaultCharset());
321+
_writer = writer;
316322

317323
this.setDaemon(true);
318324
this.setName("ProcessStreamDrainer - " + type);
@@ -321,14 +327,23 @@ private ProcessStreamDrainer(InputStream stream, String type) {
321327
@Override
322328
public void run() {
323329
try {
324-
byte[] buffer = new byte[1024];
325-
while (_stream.read(buffer) != -1)
326-
;
330+
char[] buffer = new char[1024];
331+
if (_writer != null) {
332+
int len = 0;
333+
while ((len = _reader.read(buffer)) != -1) {
334+
_writer.write(buffer, 0, len);
335+
_writer.flush();
336+
}
337+
} else {
338+
while (_reader.read(buffer) != -1)
339+
;
340+
}
327341
} catch (IOException e) {
328342
e.printStackTrace();
329343
throw new RuntimeException(e);
330344
}
331345
}
346+
332347
}
333348

334349
/**

0 commit comments

Comments
 (0)