Eclipse MessageConsole seems blocked - need Asynchronous output - java

I want write the output of a program to the console, but in someway the Console seems blocked/the Console doesn't even show before the function has finished.
Here is some sample code, which shows the exact same behaviour:
public void startConsole() throws IOException {
long start = System.currentTimeMillis();
MessageConsole console = new MessageConsole("TestConsole", null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] {console});
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(console);
MessageConsoleStream stream = console.newMessageStream();
stream.setActivateOnWrite(true);
stream.println("Start: " + (System.currentTimeMillis()-start));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stream.println("End: " + (System.currentTimeMillis()-start));
}
What I get: The function runs for about a second and I see the output ("Start: 0\nEnd:1000")
What I want: I launch the function, and see the first output ("Start: 0"), one second later, I want "End: 1000" to be added to the Console.
How do I achieve this?

You will need to run the method in a new thread.
Define a new class that implements java.lang.Runnable with
its run() method does the things that have been shown above.
Then, create an instance of java.lang.Thread with the Runnable
object that you defined. Kick off the job by invoking the
thread by calling start() method on the thread instance.

Related

Future.get(5,TimeUnit.SECONDS) doesnt timeout after 5 seconds if native methods are used in Java

I am using Executor framework in my java code. I am facing an issue and i need clarification regarding the same.
Below is my java code,
ExecutorService executorObj = Executors.newFixedThreadPool(10);
String name = "default";
Future<String> futRes = executorObj.submit(new Callable<String>() {
#Override
public String call() {
computePropertyPage("");
return "Hello";
}
});
try {
System.out.println("waiting for name for 5 seconds maximum...");
return futRes.get(5,TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("Exception occurred : " + e);
return name;
}
In the above code, computePropertyPage() is a native method. Its properly linked with the java code. But the call to the function is not getting completed. Its stuck indefinitely. If the call is stuck for more than 5 seconds, i am expecting TimeOutException after 5 seconds. But i am not recieving it.
Instead of native method call, if i just add a sleep of 10 seconds as below,
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I get TimeOutException.
I just want to know if its the limitation from the java side that it dont have control on the native methods and thats the reason its not able to throw TimeOutException for futRes.get(5,TimeUnit.SECONDS);
Your method computePropertyPage completes in less than 5 seconds and return response. Since you aren't calling shutdown on ExecutorService it isn't terminating. Try calling executorObj.shutdown();

How to use console view in Eclipse RCP Application

I just started using RCP to write Java-based applications. I am trying to add a console view in my app, and output info of log4j to the console. Now it works. But there is a problem, it cannot perform as eclipse witch output once per line, but output all info after the method finish.
Object[] elements = tableViewer.getCheckedElements();
if(elements.length > 0){
for(Object ele : elements){
File file = (File) ele;
logger.info("log4j处理目录" + file.getAbsolutePath());
MessageConsoleStream stream = ConsoleFactory.getConsole().newMessageStream();
stream.println("println处理目录" + file.getAbsolutePath());
try {
stream.flush();
stream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I tried use stream.println() stream.flush(), but it does not work.
It is my first time questing on stackoverflow. Sorry for my english.
Calling Thread.sleep(1000) in the User Interface Thread will block the entire UI and nothing will happen. Never do this.
If you want to do something once a second use the timerExec method of Display to run code.
Something like:
Display.getDefault().timerExec(1000, new Runnable() {
#Override
public void run()
{
// TODO output one item to the log
// TODO if need to run again call
Display.getDefault().timerExec(1000, this);
}
});
The JavaDoc for MessageConsoleStream says:
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.
So you must not loop constantly outputting to the stream without letting other code in the UI thread run.

Print Message after successfully compilation

I have a simple JAVA code it will just print hello after compile and Run the Program. But I want to print one message after successful completion. Is this possible? If yes than how?
Although, the following code snippet is way too overkill for your task but, expanding on my comment - you may want to submit a custom task to a class
which implements Callable.
public class Main {
public static void main(String[] args) {
final ExecutorService executorService;
final Future<Integer> future;
final int statusCode;
executorService = Executors.newFixedThreadPool(1);
future = executorService.submit(new TextMessagePrinter());
try {
statusCode = future.get();
if (statusCode == 10) { // Printed successfully
System.out.println("JOB DONE. EXITING...");
Runtime.getRuntime().exit(0); // A zero status code indicates normal termination.
} else {
System.out.println("ERR...SOMETHING WEIRD HAPPENED!");
Runtime.getRuntime().exit(statusCode); // A non-zero status code indicates abnormal termination.
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executorService.shutdownNow();
}
}
}
class TextMessagePrinter implements Callable<Integer> {
public Integer call() {
Integer STATUS_CODE;
try {
System.out.println("Printing hello..."); // Try printing something
System.out.println("Dividing 6 by 0 gives us: " + 6 / 0); // And then you try to do something knowing which will result in an exception
STATUS_CODE = 10; // Indicates success.
} catch (ArithmeticException e) {
STATUS_CODE = 20; // Indicates failure...setting status code to 20.
}
return STATUS_CODE;
}
}
Running the above code on my IDE gives me the following output:
When the exception happens
(Note the status code set in the catch block getting printed when the process finishes):
No exception happens, everything happens fine:
(Comment the following line)
System.out.println("Dividing 6 by 0 gives us: " + 6 / 0);
If you mean completion of the application's Runtime, I think you are looking for the answer in this StackOverflow question: Java Runtime Shutdown Hook.
Or if you want to do what is in the question title and do something after building, then you may consider a build automation tool, like Maven.

Why jTextArea.setText() method works after it should?

Sorry guys maybe it can be a silly question but really i couldn't find any similar situation like this.
Here is my code:
private void startHashingButtonActionPerformed(java.awt.event.ActionEvent evt) {
consoleArea.setText( myFile.getName() + " started to be hashing! It can take few minutes, please wait.."); //20:05
try {
BufferedReader reader = new BufferedReader(new FileReader(myFile));
myHash = new HashOA(300000);
try {
while(reader.readLine() != null){
myHash.hash(reader.readLine());
}
consoleArea.append("\n" + myFile.getName() + " is successfully hashed!!");
} catch (IOException ex) {
Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
I expect that in consoleArea(TextArea) there should be "file.txt started to be hashing! It can take few minutes, please wait.." written and after that the hashing process(that while(reader.readLine() != null) loop) should be started. But when i run the program and click on "startHashingButton" it first finishes hashing process and later it writes on console(jTextArea) --> "file.txt started to be hashing! It can take few minutes, please wait..", "file.txt is successfully hashed!!"
I'm working on a large text file and it takes a while to hash it. That's why i want to tell user he/she should wait a bit.
Why the working queue differs from my code order ?
Note: The only thing that came to my mind is to use thread, could it solve the problem?
Note: The only thing that came to my mind is to use thread, could it solve the problem?
Yes, that is correct. Code executed in an event listener is invoked on the Event Dispatch Thread. The GUI can't be repainted until all the code is finished executing. So a long running task prevents the GUI from repainting itself.
Read the section from the Swing tutorial on Concurrency in Swing for more information. Maybe a SwingWorker will be a better solution than creating your own Thread.
Use SwingWorker to implement a worker thread.
Do all the processing in doInBackground method, you can add your following code in doInBackground. Before that you can you will set the text in your console area. And once your file is hashed, you can implement done() method and set the appropriate message in your console area. To give you an idea, it will look something like this
#Override
protected Integer doInBackground() throws Exception {
try {
BufferedReader reader = new BufferedReader(new FileReader(myFile));
myHash = new HashOA(300000);
try {
while(reader.readLine() != null){
myHash.hash(reader.readLine());
}
return null;
} catch (IOException ex) {
Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(MainScreen.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
protected void done() {
consoleArea.append("\n" + myFile.getName() + " is successfully hashed!!");
}
Refer this for more clarity : How do I make my SwingWorker example work properly?

Program hanging after thread ending

Basically I have a ServerSocket listener , on new incoming connection the program executes a thread to serve it , after the thread finishes , the program doesn't continue
this is the listener
client = listenSocket.accept();
new HandleConnection(client);//HandleConnections extends thread and start
//method is called in the constructor
counter++;
System.out.println("Number of clients served : " + counter);
this is the thread
public HandleConnection(Socket client) {
this.client = client;
this.start();
}
public void run() {
try {
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
handler();
System.out.println("Ending Thread !");
} catch (IOException e) {
//System.out.println("socket closed");
e.printStackTrace();
}
}
the message "Ending Thread !" is executed normally , but the counter++ and the following println statement are never executed
the message "Ending Thread !" is executed normally , but the counter++ and the following println statement are never executed
So if new HandleConnection(client); actually starts a new thread (which you should not do in a constructor, see below), then the counter++ should immediately be executed and the "Number of clients... message printed. Any chance the message is appearing above the "Ending Thread!" message in your logs? Typically it takes some time to start the actual thread so the caller will continue to execute before the run() method is entered.
Other comments about your code:
As #MarkoTopolnik mentions, you need to close the input and output streams in your run() method. finally clauses are a required pattern there.
You should never call Thread.start() in an object constructor because of Thread race condition issues around object construction. See: Why not to start a thread in the constructor? How to terminate?
Instead of extending Thread you should consider implementing Runnable and doing something like:
new Thread(new HandleConnection(client)).start();
Event better than managing the threads yourself would be to use an ExecutorService thread-pool for your client handlers. See this tutorial.
The typical way to do this is to perform something like this:
ServerSocket listener = new ServerSocket(3030); //Create a new socket to listen on
try
{
//While we are running, if a client connects
//accept the connect and increment the client ID
while (true)
{
new udSocketServer(listener.accept()).start();
}
}
finally //Gracefully close
{
listener.close(); //Close socket object
}
You could then call the shared variable 'counter' in the thread constructor. If you need more than this, let me know and I will edit.
But in reality you need a little more code for us to answer.

Categories

Resources