Eclipse plugin: about the function --println(String) in org.eclipse.ui.console.MessageConsoleStream - eclipse-plugin

Recently I am doing a eclipse plugin project with eclipse_RCP. But I encountered some issues with eclipse UI when I wanted to print a large number of messages in the console of plugin.
The messages are from a complex process which could be considered as a factory producing messages all the time and never stop (until the client stop the process of course).
When I printed the message before (the message is short), I just needed to call the function -org.eclipse.ui.console.MessageConsoleStream.println().
BUT this time ,when I tried like before at first , the runtime-EclipseApplication (launch the debug mode) stopped responding and then tell me out of memory.
It seems like that the eclipse will read all the messages in the memory and THEN print them to the console one time .So when the number of message is large ,it will out of memory.
My issue is what can I do if I want to print the message line by line in the console ?
My description may be not accurate. Below is the java code:
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
try {
while ((line = in.readLine()) != null) {
//it is correct when print in the main console
System.out.println(line);
//when print in plugin console .it is out of memory
//this is the function
//org.eclipse.ui.console.MessageConsoleStream.println()
println(line);
}
in.close();
this.flush();
this.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then I try to write to a file at first and let the MessageConsoleStream read from the file every 1000 messages,but it looks like the same .
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
char []tem = new char[1024];
int i = 0 ;
try {
File temp = File.createTempFile("temp", ".tep",new File("E:/"));
FileWriter out = new FileWriter(temp);
MessageConsoleStream mcs = null;
while((line = in.readLine())!=null){
if(i<=1000){
System.out.println(line);
out.write(line+"\n", 0, line.length()+1);
i++;
}
else{
i=0 ;
out.flush();
out.close();
FileReader fr=new FileReader(temp);
mcs = CConsole.getMessageStream("consoleName", "file name");
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
fr.close();
out = new FileWriter(temp,false);
}
}
if(i!= 0){
mcs = CConsole.getMessageStream("consoleName", "file name");
out.flush();
out.close();
FileReader fr=new FileReader(temp);
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
}
in.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
All the ways above will make the eclipse out of memory when the number of messages more than 600,000 (then I stop the process ,otherwise it will out of memory).
It looks like the ecplipse wants to print all of them one time but not line by line.So it reads and reads again until out of memory.
BTW,I find a note in the org.eclipse.ui.console.MessageConsoleMessage.java——
Clients should avoid writing large amounts of output to this stream
in the UI thread. The console needs to process the output in the UI
thread and if the client hogs the UI thread writing output to the
console, the console will not be able to process the output.
That is not the real reason ,isn't it ?
I also notice that both the cdt and jdt are ok when printing a large number of message .How did they do ?
THANKS!

You have to use the flush() method every so often to write the MessageConsoleStream out to the console.
The flush() method is part of the IOConsoleOutputStream class, in the org.eclipse.ui.console package. The flush() method is not well documented, so I can see how you might have missed it.

Related

Convert writes to OutputStream into a Flux<DataBuffer> usable by ServerResponse

I have a legacy library that I have to use to retrieve a file. This legacy library doesn't return in InputStream, as you usually expect for reading stuff, but it expects that it is passed an open OutputStream, that it can write to.
I have to write a Webflux REST service, that writes this OutputStream to the org.springframework.web.reactive.function.server.ServerResponse body.
legacyLib.BlobRead(outputStream); // writes the stream to an outputstream, that has to be provided by me, and somehow has to end up in the ServerResponse
Since I want to pass along the Stream directly to the ServerResponse, I probably have to do something like this, right?
ServerResponse.ok().body(magicOutpuStreamToFluxConverter(), DataBuffer.class);
Here is the part of the RequestHandler that's important. I left out some errorhandling/catching of exceptions, that might generally not be needed. Note that I publishedOn a different Scheduler for the read (or at least, that's what I wanted to do), so that this blocking read doesn't interfere with my main event thread:
private Mono<ServerResponse> writeToServerResponse(#NotNull FPTag tag) {
final long blobSize = tag.getBlobSize();
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(Flux.<DataBuffer>create((FluxSink<DataBuffer> emitter) -> {
// for a really big blob I want to read it in chunks, so that my server doesn't use too much memory
for(int i = 0; i < blobSize; i+= tagChunkSize) {
// new DataBuffer that is written to, then emitted later
DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().allocateBuffer();
try (OutputStream outputStream = dataBuffer.asOutputStream()) {
// write to the outputstream of DataBuffer
tag.BlobReadPartial(outputStream, i, tagChunkSize, FPLibraryConstants.FP_OPTION_DEFAULT_OPTIONS);
// don't know if flushing is strictly neccessary
outputStream.flush();
} catch (IOException | FPLibraryException e) {
log.error("Error reading + writing from tag to http outputstream", e);
emitter.error(e);
}
emitter.next(dataBuffer);
}
// if blob is finished, send "complete" to my flux of DataBuffers
emitter.complete();
}, FluxSink.OverflowStrategy.BUFFER).publishOn(Schedulers.newElastic("centera")).doOnComplete(() -> closeQuietly(tag)), DataBuffer.class);
}

Why am I getting a Java IO Exception in this very simple code?

The following is some sample code I created to get myself more familiar with Groovy. I have a good understanding of Java and I am trying to now learn this new language.
class Activity {
static void reverseString() {
def text
System.in.withReader{
println "Enter a string to be reversed:"
text = it.readLine()
}
print "\n";
for (int i = text.length() - 1; i >= 0; i--){
print text[i];
}
}
static void main(String[] args) {
def selection
System.in.withReader{
println "Select a project:"
println "1 - Reverse String"
selection = it.readLine()
}
switch (selection) {
case "1":
reverseString()
break
}
}
}
I am able to compile and run this code. I am able to enter '1' and press enter, and then the prompt from my method shows up. At this point I am supposed to enter a string to reverse, but before I can enter I get the IO Exception:
Exception in thread "main" java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:127)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:112)
at java.io.InputStreamReader.read(InputStreamReader.java:168)
at Activity$_reverseString_closure1.doCall(main.groovy:10)
at Activity.reverseString(main.groovy:7)
at Activity.main(main.groovy:39)
What am I missing here?
The purpose of withReader() is to ensure the stream is closed. So after the project selection is input in the main() method, the stream is closed. When reverseString() is executed, it's too late; the stream is closed.
Don't close System.in (directly, or through withReader) . Only close streams that your code creates, not streams that your application receives from a caller, or global instances in the runtime.

C# Audio File is played in a loop although it is stopped

I have an older implementation using NAudio 1.6 to play a ring tone signalling an incoming call in an application. As soon as the user acceptes the call, I stop the playback.
Basically the follwing is done:
1. As soon as the I get an event that a call must be signalled, a timer is started
2. Inside this timer Play() on the player
3. When the timer starts again, a check is performed if the file is played by checking the CurrentTime property against the TotalTime propery of the WaveStream
4. When the user accepts the call, Stop() is called on the player and also stop the timer
The point is, that we run sometimes in cases where the playback is still repeated although the timer is stopped and the Stop() was called on the player.
In the following link I read that the classes BufferedWaveProvider and WaveChannel32 which are used in the code are always padding the buffer with zero.
http://mark-dot-net.blogspot.com/2011/05/naudio-and-playbackstopped-problem.html
Is it possible that the non-stopping playback is due to usage of the classes BufferedWaveProvider and WaveChannel32?
In NAudio 1.7 the AudioFileReader class is there. Is this class also padding with zeros? I did not find a property like PadWithZeroes in this class. Does it make to use AudioFileReader in this case of looped playback?
Below the code of the current implementation of the TimerElapsed
void TimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
WaveStream stream = _audioStream as WaveStream;
if (stream != null && stream.CurrentTime >= stream.TotalTime )
{
StartPlayback();
}
}
catch (Exception ex)
{
//do some actions here
}
}
The following code creates the input stream:
private WaveStream CreateWavInputStream(string path)
{
WaveStream readerStream = new WaveFileReader(path);
if (readerStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
{
readerStream = WaveFormatConversionStream.CreatePcmStream(readerStream);
readerStream = new BlockAlignReductionStream(readerStream);
}
if (readerStream.WaveFormat.BitsPerSample != 16)
{
var format = new WaveFormat(readerStream.WaveFormat.SampleRate, 16, readerStream.WaveFormat.Channels);
readerStream = new WaveFormatConversionStream(format, readerStream);
}
WaveChannel32 inputStream = new WaveChannel32(readerStream);
return inputStream;
}

usbManager openDevice call fails after several hundred successful attempts

I'm using usbmanager class to manage USB host on my android 4.1.1 machine.
all seems to work quite well for a few hundreds of transactions until (after ~ 900 transactions) opening the device fails, returning null without exception.
Using a profiler it doesn't seem to be a matter of memory leakage.
this is how I initialize the communication from my main activity (doing this once):
public class MainTestActivity extends Activity {
private BroadcastReceiver m_UsbReceiver = null;
private PendingIntent mPermissionIntent = null;
UsbManager m_manager=null;
DeviceFactory m_factory = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
m_UsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// call your method that cleans up and closes communication with the device
Log.v("BroadcastReceiver", "Device Detached");
}
}
}
};
registerReceiver(m_UsbReceiver, filter);
m_manager = (UsbManager) getSystemService(Context.USB_SERVICE);
m_factory = new DeviceFactory(this,mPermissionIntent);
}
and this is the code of my test:
ArrayList<DeviceInterface> devList = m_factory.getDevicesList();
if ( devList.size() > 0){
DeviceInterface devIf = devList.get(0);
UsbDeviceConnection connection;
try
{
connection = m_manager.openDevice(m_device);
}
catch (Exception e)
{
return null;
}
The test will work OK for 900 to 1000 calls and after this the following call will return null (without exception):
UsbDeviceConnection connection;
try
{
connection = m_manager.openDevice(m_device);
}
You might just run out of file handles, a typical limit would be 1024 open files per process.
Try calling close() on the UsbDeviceConnection, see doc.
The UsbDeviceConnection object has allocated system ressources - e.g. a file descriptor - which will be released only on garbage collection in your code. But in this case you run out of ressources before you run out of memory - which means the garbage collector is not invoked yet.
I had opendevice fail on repeated runs on android 4.0 even though I open only once in my code. I had some exit paths that did not close the resources and I had assumed the OS would free it on process termination.
However there seems to be some issue with release of resources on process termination -I used to have issues even when I terminated and launched a fresh process.
I finally ensured release of resources on exit and made the problem go away.

Application crashes when lots of images are displayed

In my WP7 application I have downloaded 200 images from Web and saved in isolated storage .When debug all the images are loaded in panorama view by queue method and I can view when it is connected to pc. after disconnect it from pc when i open the application and navigate the images it shows some images and terminated.
if (i < 150)
{
WebClient m_webClient = new WebClient();
Uri m_uri = new Uri("http://d1mu9ule1cy7bp.cloudfront.net/2012//pages/p_" + i + "/mobile_high.jpg");
m_webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
m_webClient.OpenReadAsync(m_uri);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
int count;
try
{
Stream stream = e.Result;
byte[] buffer = new byte[1024];
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
//isf.Remove();
using (System.IO.IsolatedStorage.IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("IMAGES" + loop2(k) + ".jpg", FileMode.Create, isf))
{
count = 0;
while (0 < (count = stream.Read(buffer, 0, buffer.Length)))
{
isfs.Write(buffer, 0, count);
}
stream.Close();
isfs.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I think that your problem is that if you load too many images at once in a loop the moment you go out of the loop and give focus back to the UI thread all the Garbage Collection on the bitmap images is done.
This article explains it a bit better and provides with a solution.
I also had this problem and came up with my own solution. I had a dictonairy with image url that needed to be loaded, but you can easily alter this for your scenario.
This SO question is also about this problem (loading multiple images and crash (Exception)). It also has Microsofts response to it, I based my solution on their response.
In my solution I use the dispatcher to return to the UI thread and thus making sure the garbage of the image and bitmaps used was cleaned.
private void LoadImages(List<string> sources)
{
List<string>.Enumerator iterator = sources.GetEnumerator();
this.Dispatcher.BeginInvoke(() => { LoadImage(iterator); });
}
private void LoadImage(List<string>.Enumerator iterator)
{
if (iterator.MoveNext())
{
//TODO: Load the image from iterator.Current
//Now load the next image
this.Dispatcher.BeginInvoke(() => { LoadImage(iterator); });
}
else
{
//Done loading images
}
}
After talking on Skype I reviewed his code and found out his problem was with his Isolated Storage Explorer. It couldnt connect to his pc so it gave an error. Had nothing to do with the image loading.
I'd be very wary of the memory implications of loading 200 images at once. Have you been profiling the memory usage? Using too much memory could cause your application to be terminated.