I have defined this kind of Android Java class, where native function baresipStart() never terminates:
package com.tutpro.baresip;
public class BaresipThread extends Thread {
public void start() {
baresipStart();
}
public void kill() {
baresipStop();
}
public native void baresipStart();
public native void baresipStop();
}
I then call its start() function from another Java class:
BaresipThread thread;
thread = new BaresipThread();
thread.start();
The result is that baresipStart() function starts to run fine, but rest of the application becomes completely unresponsive.
Why is that and how to fix the code so that baresipStart() function runs in the background without stopping all other activity?
Thread.start() is responsible for actually creating the new thread of execution and setting it running. By overriding it as you did, you cause it to instead run baresipStart(), in the thread that invokes start().
Instead of overriding start(), you should override run(). This method is what defines the work to be performed in the new thread of execution.
Furthermore, if native method baresipStart() indeed never returns then you have a problem. Your application cannot terminate while it has any active threads. Supposing that you intend for baresipStop() to cause the thread to finish, you should arrange for baresipStart() to return (or to throw an unchecked exception) when execution is terminated by an invocation of baresipStop(). Do be aware, however, that those native methods need to be thread-safe, because they will, perforce, be invoked by different Java threads.
Thanks for your explanation. I got the new baresip thread started by removing BaresipThread object altogether and replacing the three lines above with this:
new Thread(new Runnable() {
public void run() {
baresipStart();
}
}).start();
User can stop the resulting process via its user interface after which the application is terminated.
Related
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).
I have an OSGI bundle of a following structure:
//...
public ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
//...
#Activate
public void activate() {
executor.submit(new Runnable() {
#Override
public void run() {
//call 3 functions and log the data
}
}
}
#Deactivate
public void deactivate(){
//call 2 other functions
}
The executor in the activate method makes sure that 3 functions are called in a separate from all other bundles thread, because those functions actually implement some sophisticated Windows-message-loop, i.e. a while true loop, that's why, in order not to block other bundles, it is activated in a separate thread. Now what I've sadly noticed, that in order to run 2 functions in deactivate method I need to run them in the same thread, in which 3 functions in activate method were run. Simply speaking, I need to be sure, that activate and deactivate methods of my bundle run in the one same thread, but still to keep this bundle activation separated (in an own thread) from the other bundles.
My question is: how to implement this?
I am not a guru in concurrency in Java, I've tried simply to call this executor in the deactivate method too but I don't know how to do it with one Runnable task, since in deactivate I have only to call 2 functions and in activate only 3 functions and no other calls should be made.
UPD: sorry, I forgot to mention, that there is a routine in another bundle, which calls in certain situations context.getBundle(0).stop() in order to call a deactivation for all bundles. If I want just to add the same submit routine in the deactivate method as is in activate, then in such situation I could clearly see, that those 2 functions from deactivate method of my bundle in the submit's body were not called.
Simply do another executor.submit in deactivate. As it is a single threaded executor it will make sure only one thread processes both.
The only question is how to shut down the executor reliably. Normally after deactivate a component should have closed all its resources.
This sounds like a very common problem. I would just make it explicit you're using a thread and use the methods in Thread that were designed for this. At activate you start the thread, at deactivate you interrupt it. Your main loop watches the interrupt status and executes your deactivate functions after it is interrupted. After interrupt, it is best to join the thread to ensure your activate() method does not return before the background thread has finished running your deactivate functions.
Since exiting the framework (stopping bundle 0) must stop all bundles, and a stopped bundle will deactivate its components, this should all work.
public class Foo extends Thread {
#Activate void activate() { start(); }
#Deactivate void deactivate() throws Exception { interrupt(); join(); }
public void run() {
while(!isInterrupted()) try {
... your 3 function loop
} catch( InterruptedException e) {
break;
}
... 2 deactivate functions
}
}
I suddenly got a weird problem in my application, but I am not sure if I can isolate the issue. I couldn't reproduce the bug in a SCCEE, but maybe someone could help me understand what happens by answering the 2 questions below.
The Context:
I have, basically this:
...
Some treatment
->call to json-io to parse a Json String to Java Objects. see below
...
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
myUI.start();//starts my user interface
}
});
Usually, everything goes fine. But I added to the treatments a call to Json IO (a library that parses Json to Java and that I generally use without any trouble).
Now, one of my other library is yelling:
Caused by: java.lang.NullPointerException
at net.sourceforge.jeuclid.elements.support.ClassLoaderSupport.loadClass(ClassLoaderSupport.java:65)
After some researches, I discovered that it is because Thread.currentThread().getContextClassLoader() returns null.
I went to the run() above and discovered that the only difference between the 2 executions is that the Event Dispatched Thread that used to belong to the group main now belongs to system:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
System.out.println(Thread.currentThread());
//returns Thread[AWT-EventQueue-0,6,system] instead of Thread[AWT-EventQueue-0,6,main]
myUI.start();//starts my user interface
}
});
In the end, I could solve the problem with
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader());
myUI.start();//starts my user interface
}
}
});
The Questions:
1) What kind of things can make the EDT change group ?
2) What are the consequences of writing Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); ? Is it a good or a bad idea ?
If your invocation of SwingUtilities.invokeLater is the first action that relies on the presence of the EDT, that thread will be created as a byproduct. So the created thread inherits the thread group of the thread which created it, e.g.
ThreadGroup tg=new ThreadGroup("foo");
new Thread(tg, ()->
SwingUtilities.invokeLater(() -> System.out.println(Thread.currentThread()))
).start();
when performed as first action of an application, will print
Thread[AWT-EventQueue-0,6,foo]
as you can verify on Ideone.
But note that the thread group has no impact on the context class loader, it’s rather a symptom of the same cause. The context class loader is just inherited exactly like the thread group when the thread is created, e.g.
ClassLoader dummyLoader=new URLClassLoader(new URL[0]);
Thread.currentThread().setContextClassLoader(dummyLoader);
SwingUtilities.invokeLater(() ->
System.out.println(Thread.currentThread().getContextClassLoader()==dummyLoader));
will print true; (verify on Ideone).
So apparently, the context loader of the thread which invokes SwingUtilities.invokeLater, initiating the EDT creation, is already null (and that thread is in the system group). Setting the context loader to ClassLoader.getSystemClassLoader() means setting it to its default, so it has no negative impact unless you encounter an environment where the context loader is intentionally set to a non-default loader, though null can not be considered to be such a case. In other words, identifying the place, where it is set to null and fixing that, is the better choice.
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.