I have a simple restarting Runnable:
static void launchThreads(){
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
try {
exec.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
try {
System.out.println("line"); <--breakpoint
}
catch (Exception e) {
e.printStackTrace(); <--breakpoint
}
}
}, 1, 1000, TimeUnit.MILLISECONDS);
}catch (Exception e) {
e.printStackTrace(); <--breakpoint
}
}
If I launch that method from the main() method of the class, it works as expected - writes a line that looks like "line", once a second, forever.
line
line
line
line
...
But if I launch that from a TestNG test method:
#Test
public class PostpackagesIntegratorTest {
#Test
public void testLaunchThreads10SmallestWithoutFees() {
PostpackagesIntegrator.launchThreads();
}
}
,it outputs only one "line" and the test is passed. "Successfully".
If I make a JUnit4 test to launch the same method,
public class PostpackagesIntegratorJUnit4Test {
#Test
public void launchThreadsTest() {
PostpackagesIntegrator.launchThreads();
}
}
, the test is also passed, again with only one "line" in output.
If I am not running, but debugging the tests, my IntelliJ stops at printing the "line", but does not notice any catch content.
I do not understand, what prevents the ScheduledExecutorService from repetitions. According to docs, such non-repeating should happen at an exception, but no exception happens.
Is it possible to make ScheduledExecutorService in TestNG tests or must I use other classes? Due to the whole project, I am limited by Java 6 version and TestNG.
Edit: #Eugene advised to declare exec as private static final ScheduledExecutorService exec, for blocking erroneous GC, but it did not help and even didn't change anything - the problem is elsewhere.
I would start by dumping a lot of thread details.
Thread.currentThread().dumpStack() (or just (new Throwable()).printStackTrace()) would show any peculiar classes frames above your runnable. These could be quite different if junit/ng are fiddling with thread factories or such.
Then you can also inspect the thread.currentThread() for isDaemon() and the threadgroup's isDeamon(). Your new executorsvc may be part (and making worker threads in) a threadgroup that is interrupted. You might be able to reveal that by writing your own thread factory and issuing threads whose interrupt() is proxied for the sake of trapping it (before forwarding it). A main() is normally a non-daemon thread, so it would spawn non daemon threads too for the execsvc. I wouldn't be surprised is junit/ng are wrapping the test in a pseudo thread sandbox to 'try' to detect and perhaps stop leaked/forgotten threads from a test.
If your are in a debugger, you should be able to browse the top frame local variables and the thread instance already without much code, to reveal all of the above (except the unanticipated interrupt call, if any).
Related
is it possible to have a method be called when the main thread or the entire program terminates? I'm aware of Thread's .join() method, but I do not think it will work on the main thread. For example, if I create a temporary directory, I would like to delete that temporary directory when the program terminates, but I would like for that to happen when the program terminates, not after something like the main method.
I do not want this:
public static void main() {
....Do something
....Delete temp directory
}
Simply add a shutdown hook..
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
System.out.println("ERMEHGERDDD");
}
});
From the Javadoc: A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently.
The shutdown hook will be called when all non-deamon threads finish or if System.exit() is called.
As user:Mad Programmer mentioned above, you could use ShutdownHook.
public static void main(String[] args)
{
ShutdownHookThread shutdownHook = new ShutdownHookThread();
Runtime.getRuntime().addShutdownHook(shutdownHook );
}
private static class JVMShutdownHook extends Thread
{
public void run()
{
// tempDirectory.delete();
}
}
I see four possible methods.
Use your own Thread subclass with an overridden run() method. Add a finally block for thread termination.
2.Use a Runnable with similar decoration, perhaps as a wrapper around the supplied Runnable. A variant of this is to subclass Thread in order to apply this wrapper at construction time.
3.Create a 2nd thread to join() on the real thread and thus detect its termination.
4.Use instrumentation to rewrite the Thread.run() method as above.
Can we execute a program without main method and how in java tell me any example. have you done that kind of example.
Yes, it's possible:
public class MyClass {
static {
Runnable r = new Runnable() {
public void run() {
// whatever you like
}
};
Thread t = new Thread(r)
t.start();
t.join();
}
}
Now you run java passing this class to the command. Java loads the class before attempting to run its main (which doesn't exist), but in loading the class, it fires the static block, which halts until the thread finishes.
If the thread finishes without exiting, java will complain there's no main method, but by that time the thread could have run anything for any duration.
You'll have to catch some exceptions in there, but it will work.
public class TestWithoutMain {
// static block executes first
static{
System.out.println("Program without main");
System.exit(0);
}
}
Note : This works well in JDK1.7 old versions(build 1.7.0-ea-b19)
from jdk 1.7(build1.7.0-ea-b85),It gives run time Exception
Yes, sequence is as follows:
jvm loads class
executes static blocks
looks for main method and invokes it
So, if there's code in a static block, it will be executed. But there's no point in doing that.
How to test that:
public final class Test {
static {
System.out.println("FOO");
}
}
Then if you try to run the class (either form command line with java Test or with an IDE), the result is:
Error will be this.
FOO
java.lang.NoSuchMethodError: main
and ans is that no you can not execute program without main method but the thing is that u can use it either way means partial.
and how ever you can achieve by using static block like this.
static{
System.out.println("Program without main executing into the environment.");
System.exit(0);
}
In Java 9 and beyond you can use JShell to execute Java code without requiring a main method. Not suitable for a stand alone application, but great for quickly testing your code and prototyping changes.
Unless its is web application, I don't think that is possible for any stand alone application which is being self executable, the Runtime should know the entry point, The runtime design such a way that main method is an entry point.
As in the title, I want to test a method like this:
public void startThread()
{
new Thread()
{
public void run()
{
myLongProcess();
}
}.start();
}
EDIT:
Judging by comments I guess it is not very common to test if a thread starts or not. So I've to adjust the question... if my requirement is 100% code coverage do I need to test if that thread starts or not? If so do I really need an external framework?
This can be done elegantly with Mockito. Assuming the class is named ThreadLauncher you can ensure the startThread() method resulted in a call of myLongProcess() with:
public void testStart() throws Exception {
// creates a decorator spying on the method calls of the real instance
ThreadLauncher launcher = Mockito.spy(new ThreadLauncher());
launcher.startThread();
Thread.sleep(500);
// verifies the myLongProcess() method was called
Mockito.verify(launcher).myLongProcess();
}
If you need 100% coverage, you will need to call startThread which will kick off a thread. I recommend doing some sort of verification that the thread was stared (by verifying that something in myLongProcess is happening, then clean up the thread. Then you would probably do the remainder of the testing for myLongProcess by invoking that method directly from your unit test.
I'm using play 1.2.4 and I'm trying to set up a unit test to test a job.
My job runs at every 2 second and changes the status of certain objects based on some conditions. This is what I use to do this.
#Every("2s")
public class GameScheduler extends Job {
public void doJob(){
//Fetch of object from db and status change based on conditions happens here
}
}
Now in my unit test, I setup those conditions but I want the test to wait say 3 seconds before fetching one of the setup objects and do an assert Equals on its status to see if the job... well did it's job.
If I use
pause(3000);
or something like
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
The test stops but the job also stops. It seems like the job and the test are on the same thread. Is there a way to pause the test without stopping the job? Something like the await() method in the controller
You don't need to test the scheduler because it is supposed to work (since the framework is handling it). What you need is just test if the doJob method is doing its work. So, just write a test like this:
GameScheduler job = new GameScheduler();
job.doJob();
// assert whatever you want here
Though simply testing the job (without waiting for the scheduler to run it for you) would do the trick in most (read this as: probably all) situations, there are some in which it might be interesting to not have to trigger it manually.
For instance, you have a cluster of play apps that share a common configuration set. Change one config in one slave, all the others take note and do the same. Let's say the configuration is kept in memcached. One useful unit test is to manually change some setting using Cache.set, wait for the amount of time it takes for the configurationObserver job to run, then check that the internal config has been updated. This would be even more helpful if there would be a series of jobs updating the configuration, etc.
To do that, you must remember that play in DEV mode uses one thread (this helps debugging a lot, btw). You can simply add this line to your application.conf: %test.application.mode=prod and you'll have multiple threads.
Later edit: It appears that setting the mode to prod doesn't really help in this case. What does help is this: use some "await" magic.
#Test
public void myTest() {
final Lock lock = new ReentrantLock();
final Condition goAhead = lock.newCondition();
/* Here goes everything you need to do before "pausing" */
lock.lock();
try {
/**
* Set whatever time limit you want/need
* You can also use notifiers like goAhead.signal(), from within another thread
*/
goAhead.await(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
assertTrue(whateverINeedToTest);
} finally {
lock.unlock();
}
}
I have a java code which works in one (main) thread. From the main thread, i spawn a new thread in which I make a server call. After the server call is done, I am doing some work in the new thread and after that the code joins the main thread.
I am using eclipse Jobs to do the server call.
I want to know, how do I write a JUnit test case for this.
You may need to restructure your code so that it can be easily tested.
I can see several distinct areas for testing:
Thread Management code: the code that launches the thread(s) and perhaps waits for results
The "worker" code run in the thread
The concurrency issues that may result when multiple threads are active
Structure your implementation so that Your Thread Management code is agnostic as to the details of the Worker. Then you can use Mock Workers to enable testing of Thread Management - for example a Mock Worker that fails in certain ways allows you to test certain paths in the management code.
Implement the Worker code so that it can be run in isolation. You can then unit test this independently, using mocks for the server.
For concurrency testing the links provided by Abhijeet Kashnia will help.
This is what I created ConcurrentUnit for. The general usage is:
Spawn some threads
Have the main thread wait or sleep
Perform assertions from within the worker threads (which via ConcurrentUnit, are reported back to the main thread)
Resume the main thread from one of the worker threads once all assertions are complete
See the ConcurrentUnit page for more info.
I'm guessing that you may have done your mocking code and may want a simple integration test to ensure that that your server call works.
One of the difficulties in testing threads comes from their very nature - they're concurrent. This means that you're force into writing JUnit test code that is forced to wait until your thread has finished its job before testing your code's results. This isn't a very good way of testing code, and can be unreliable, but usually means that you have some idea about whether you code is working.
As an example, your code may look something like:
#Test
public void myIntegrationTest() throws Exception {
// Setup your test
// call your threading code
Results result = myServerClient.doThreadedCode();
// Wait for your code to complete
sleep(5);
// Test the results
assertEquals("some value",result.getSomeValue());
}
private void sleep(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
I really don't like doing this and prefer mocks and agree with the other answers. But, if you need to test your threads, then this is one approach that I find works.
When your only problem is waiting for the result, use ExecutorService for spawning your threads. It can accept work jobs both as Runnable and Callable. When you use the latter, then you are given a Future object in return, that can be used to wait for the result. You should consider using ExecutorService anyway, as from what I understand, you create many threads, and this is a perfect use case for executor services.
class AnyClass {
private ExecutorService threadPool = Executors.newFixedThreadPool(5);
public List<Future<Integer>> anyMethod() {
List<Future> futures = new ArrayList<>();
futures.add(threadPool.submit(() -> {
// Do your job here
return anyStatusCode;
}));
futures.add(threadPool.submit(() -> {
// Do your other job here
return anyStatusCode;
}));
return futures;
}
}
And the test class:
class TestAnyClass {
#Test
public void testAnyMethod() {
AnyClass anyObject = new AnyClass();
List<Future<Integer>> futures = anyObject.anyMethod();
CompletableFuture[] completable = futures.toArray(new CompletableFuture[futures.size()]);
// Wait for all
CompletableFuture.allOf(completable).join();
}
}
I suggest you use a mocking framework, to confirm that the server call was indeed made. As for the thread unit testing: Unit testing multithreaded applications
The resources provided by Abhijeet Kashnia may help, but I am not sure what you are trying to achieve.
You can do unit testing with mocks to verify your code, that won't test concurrency but will provide coverage.
You can write an integration test to verify that the threads are being created and joined in the fashion you expect.However this will not guarantee against concurrency problems. Most concurrent problems are caused by timing bugs which are not predictable and thus can't be tested for accurately.
Here is my solution to test asynchrone method which used thread.start:
public class MyClass {
public void doSomthingAsynchrone() {
new Thread(() -> {
doSomthing();
}).start();
}
private void doSomthing() {
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class MyClassTest {
ArgumentCaptor<Runnable> runnables = ArgumentCaptor.forClass(Runnable.class);
#InjectMocks
private MyClass myClass;
#Test
public void shouldDoSomthingAsynchrone() throws Exception {
// create a mock for Thread.class
Thread mock = Mockito.mock(Thread.class);
// mock the 'new Thread', return the mock and capture the given runnable
whenNew(Thread.class).withParameterTypes(Runnable.class)
.withArguments(runnables.capture()).thenReturn(mock);
myClass.doSomthingAsynchrone();
runnables.getValue().run();
/**
* instead of 'runnables.getValue().run();' you can use a real thread.start
*
* MockRepository.remove(Thread.class);
* Thread thread = new Thread(runnables.getValue());
* thread.start();
* thread.join();
**/
verify(myClass, times(1)).doSomthing();
}
}