Java claims to not send to console when called from runnable

In my program, I made a statement - which evaluates to false - from runnable, but will never see any console issues about the statement. I want to know if my statements are false, but does runnable seem to catch all the thrown statements?

Below is the simplest example program that I could write for a demonstration. (Statements are allowed. The program will behave differently if they were not, and print both lines, not just one). The output file of the program.

About False

What is it. After this, the statement claims to be thrown and will catch something, and I never know about it. I want to know about this, what am I doing wrong?

import java.nio.ByteBuffer; import java.util.concurrent.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.FlowLayout; import javax.swing.*; class App { private static final ScheduledExecutorService sExecutor = Executors.newSingleThreadScheduledExecutor(); // Main public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } // Swing GUI private static void createAndShowGUI() { // Just create a swing thing. Boring JFrame frame = new JFrame("Title String"); JLabel label = new JLabel("Hello World"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(label); frame.getContentPane().setLayout(new FlowLayout()); frame.pack(); frame.setVisible(true); // ******************************************** // INTERESTING CODE HERE. We schedule a runnable which assert false // but we never see a console assert error! // ******************************************** sExecutor.schedule(new Runnable() { @Override public void run() { doAssertFalse(); }}, 0, TimeUnit.SECONDS); } public static void doAssertFalse() { System.out.println("About to assert False"); assert false; System.out.println("Done asserting False"); } } 
+6
source share
2 answers

This will be done:

 private static final ScheduledExecutorService sExecutor = Executors.newSingleThreadScheduledExecutor(); // Main public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { try { createAndShowGUI(); } catch (ExecutionException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); } // Swing GUI private static void createAndShowGUI() throws ExecutionException, InterruptedException { // Just create a swing thing. Boring JFrame frame = new JFrame("Title String"); JLabel label = new JLabel("Hello World"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(label); frame.getContentPane().setLayout(new FlowLayout()); frame.pack(); frame.setVisible(true); // ******************************************** // INTERESTING CODE HERE. We schedule a runnable which assert false // but we never see a console assert error! // ******************************************** ScheduledFuture<?> future = sExecutor.schedule(new Runnable() { @Override public void run() { doAssertFalse(); } }, 0, TimeUnit.SECONDS); future.get(); } public static void doAssertFalse() { System.out.println("About to assert False"); assert false; System.out.println("Done asserting False"); } 

Note. I save the result of schedule in the variable ScheduledFuture . The exception is not returned until you call the get() method in the future. All exceptions are thrown in an ExecutionException .

Unfortunately, this blocks, so another way to get an exception is as follows:

 // Swing GUI private static void createAndShowGUI() { // Just create a swing thing. Boring JFrame frame = new JFrame("Title String"); JLabel label = new JLabel("Hello World"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(label); frame.getContentPane().setLayout(new FlowLayout()); frame.pack(); frame.setVisible(true); // ******************************************** // INTERESTING CODE HERE. We schedule a runnable which assert false // but we never see a console assert error! // ******************************************** sExecutor.schedule(new Runnable() { @Override public void run() { try { doAssertFalse(); } catch (Error e) { e.printStackTrace(); } } }, 0, TimeUnit.SECONDS); } public static void doAssertFalse() { System.out.println("About to assert False"); assert false; System.out.println("Done asserting False"); } 

Please note that I am breaking an error, not an exception. I do this because Assertions throws java.lang.AssertionError, and not an * Exception.

I'm having trouble finding any kind of documentation in Javadoc saying that the ScheduledExecutorService swallows exceptions if you don't do this, but through my tests, which seem to be taking place.

+3
source

Threads do nothing with exceptions (how could they? What if you do not use STDERR or STDOUT, but register in the database, how Thread.run () knows where to register the exception, or who reconstructs it to?)

There is a Thread.UncaughtExceptionHandler that you can use, and when you do this, your checks should work with that.

I believe the problem is that the Assert mechanism uses exceptions and therefore must follow the predefined rules for exceptions. Personally, I would not mind if Assert just printed a stack dump and made exit (0), because you should never catch this exception anyway - but that's what it is.

Please note that you can also use Thread.setDefaultUncaughtExceptionHandler only once for all threads in your application (note "DEFAULT") ... this should be a pretty good general solution.

  import java.lang. *;

 public class ThreadDemo {

    public static void main (String [] args) {

      Thread t = new Thread (new adminThread ());

      t.setUncaughtExceptionHandler (new Thread.
      UncaughtExceptionHandler () {
         public void uncaughtException (Thread t2, Throwable e) {
            System.out.println (t2 + "throws exception:" + e);
         }
      });
      // this will call run () function
      t.start ();

    }
 }

 class adminThread implements Runnable {

    public void run () {
       assert (false);
       throw new RuntimeException ();
    }
 } 

When I run this "Normal", it shows that a RuntimeException has been thrown. When I run the -ea option, it shows an AssertException. Give it a try.

0
source

All Articles