after spy on thread object, thread.start(), thread.join() don't work。 - mockito

I can't find any documentation specifically mentions spy on thread object using mockito. But I tested using the following code (with mockito 1.8.5):
#Test
public void testThread() throws InterruptedException
{
Thread threada = spy( new Thread( new Runnable()
{
#Override
public void run()
{
System.out.println( "on thread" );
}
} ) );
threada.start();
//threada.join();
System.out.println( "finished test" );
}
The "on thread" is not print out, if I put threada.join() in, I got exception:
Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "Thread-1"
finished test
If I remove "spy()", I got both prints ("no thread" and "finished test"), and there is no exception. Why can't I spy on Thread object?

Please use current version of Mockito (2.X instead of 1.8.5)
I checked your code and the problem reproduces on 1.8.5, and is gone on 2.X
2.X introduced a significant change - it changed the mock maker engine from CGLIB to ByteBuddy.

Related

join() waiting forever when exception occurs, jvm shutdown hook not working

I am trying to shutdown the application, whenever any Fatal
Error/Exception comes but before shut down the application my current
thread/task should complete, so I have written mainThread.join()
inside run(), its working fine when there is no exception. But whenever my
doTask() throwing exception that time join() waiting forever.
public class POC
{
public void doTask() throws Exception
{
throw new Exception("Fatal Error");
//throw new Exception("Fatal Error"); By commenting working fine.
}
public static void main(String[] args)
{
POC ob = new POC();
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
try
{
System.out.println("Join() Start");
mainThread.join();
System.out.println("Join() End"); //Why this is not printing?
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
try
{
System.out.println("Before doTask()");
ob.doTask(); //User Defined Run()
System.out.println("After doTask()");
}
catch (Exception ex) // FATAL
{
System.err.println("Exception : " + ex.getLocalizedMessage());
System.exit(-1);
}
}
}
OutPut : 0
Before Run()
Exception : Fatal Error
Join() Start
Why System.out.println("Join() End"); is not printing?
You have a simple deadlock.
When you throw an exception, exception handler call System.exit(-1), which is blocking, see javadoc:
Terminates the currently running Java virtual machine by initiating its shutdown sequence
...
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered #addShutdownHook shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish.
So main thread is waiting in System#exit call until all shutdown hook will be finished and your only shutdown hook blocks and waits until main thread will finish (which is waiting in System#exit ... GOTO 1).

Understanding simple ProgressDialogue , how can another thread update UI?

This example is copied from a book on Android. As you can see from my question, I am new to Android and trying to understand. This application should crash but it does not (I am updating UI from another thread. Which is not allowed.It should cause a crash. It does not. Why?). My code is:
final ProgressDialog dialogue = ProgressDialog.show(this, "title", "message");
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(7000);
dialogue.dismiss();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
This is done in OnCreate function. I am confused with line - dialogue.dismiss(); Isn't that updating UI (dismissing dialogue) from another thread? Why does this app not cause segmentation fault?
Thanks.
You cant dismiss() it in run method because it is non UI thread.and if you want to dismiss then use Handler.And its better to use AsyncTask
The Code is correct only man.You are starting a thread using the .start function and after that the run function called and then after 7 seconds the the dialogue will dismiss.The dialogue.dismiss() is used to dismiss the dialogue.If you will not call dismiss(),the progress bar never dismissed.You can check by commenting the line Thread.sleep(7000).

Why does this NOT cause crash? I am updating UI from other thread

This example is copied from a book on Android. As you can see from my question, I am new to Android and trying to understand. This application should crash but it does not (I am updating UI from another thread. Which is not allowed.It should cause a crash. It does not. Why?). My code is:
final ProgressDialog dialogue = ProgressDialog.show(this, "title", "message");
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(7000);
dialogue.dismiss();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
This is done in OnCreate function. I am confused with line - dialogue.dismiss(); Isn't that updating UI (dismissing dialogue) from another thread? Why does this app not cause segmentation fault?
Thanks.
the dismiss() method can be run safetly on any thread as described in the Android documentation.
public void dismiss ()
Since: API Level 1 Dismiss this dialog, removing it from the screen.
This method can be invoked safely from any thread. Note that you
should not override this method to do cleanup when the dialog is
dismissed, instead implement that in onStop().

Problem in calling thread inside Eclipse view run method, after using asyncExec. Invalid Thread Exception

I am having an eclipse View. Inside the view I added a Table. Now I am calling a thread from run method of the view using asyncExec.
My View class is like -
public class SampleViewAction implements IWorkbenchWindowActionDelegate{
Thread t;
int Count;
#Override
public void run(IAction arg0) {
}
}
Now I added a thread like this -
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
new UDPReadThread();
}
});
Where UDPReadThread is a class extends a thread where in UDPReadThread 's constructor I started the thread.
But I am getting invalid Thread exception.
How to resolve the issue.
Similar to AWT and the EventDispatchThread, SWT must process everything in the UI thread.
Your SampleViewAction is run on the UI thread already, in response to a menu or tool item selection.
It looks like your problem comes from then using an asyncExec(*) which will post the runnable to be run on the UI thread (which delays it), and starting a new thread from that asyncExec Runnable. You may as well simply start your thread, and get rid of that asyncExec.
Your UDPReadThread is not the UI thread. If you need to update UI widgets from UDPReadThread, that's the code that needs the asyncExec:
display.asyncExec(
new Runnable() {
public void run(){
label.setText(text);
}
});
Just as an aside, you should not subclass Thread unless you really are extending threads capabilities. The normal pattern when you just want to start another thread:
UDPReadRunnable udpRunnable = ....;
Thread thread = new Thread(udpRunnable);
thread.start();
You can get more information on the display thread from http://www.eclipse.org/swt/faq.php#uithread

Thread Invalid Access Error in SWT

Could you let me know the reason for this error in SWT
"org.eclipse.swt.SWTException" Invalid Thread access ?
And How to fix such errors.
It happens when you try to act upon an interface item from a thread that's not the UI thread.
To run a code on the UI thread you have to use a Runnable and ask the display thread to run it. This way:
Display.getDefault().syncExec( new Runnable() {
#Override
public void run() {
// Do your job here
}
} );
As stated by the syncExec method javadoc,
the thread which calls this method is suspended until the runnable completes.
Also, you might check the asyncExec method.
In SWT you can access GUI resources only from the display thread. For example when setting the text in a org.eclipse.swt.widgets.Text control you must already be in the display thread or call
final Text text = ...;
Display.getCurrent().syncExec(new Runnable() {
#Override
public void run() {
text.setText("test");
}
});

Resources