Java: try-catch error, must be caught to be thrown - java

I have tried to create a method to load files but it is not working the way it should. Why do I get this error? Is there a problem with my try-catch block?
NamnMetod.java:157: error: unreported exception InterruptedException; must be caught or declared to be thrown
EventQueue.invokeAndWait(new Runnable() {
This is my code:
public static void hämtaFrånText() {
EventQueue.invokeAndWait(new Runnable() {
#Override
public void run() {
try {
String aktuellMapp = System.getProperty("user.dir");
JFileChooser fc = new JFileChooser(aktuellMapp);
int resultat = fc.showOpenDialog(null);
if (resultat != JFileChooser.APPROVE_OPTION) {
JOptionPane.showMessageDialog(null, "Ingen fil valdes!");
System.exit(0);
}
String fil = fc.getSelectedFile().getAbsolutePath();
String[] namn = new String[3];
String output ="";
BufferedReader inFil = new BufferedReader(new FileReader(fil));
String rad = inFil.readLine();
int antal = 0;
while(rad != null) {
namn[antal] = rad;
rad = inFil.readLine();
antal++;
}
inFil.close();
}catch(FileNotFoundException e1) {
JOptionPane.showMessageDialog(null,"Filen hittades inte!");
}
catch(IOException e2) {
JOptionPane.showMessageDialog(null,"Det misslyckades");
}
}
});
}

It's got nothing to do with the try/catch block in the run() method. The problem is with the method that calls invokeAndWait... EventQueue.invokeAndWait() is declared to throw InterruptedException, which is a checked exception... so either you need another try/catch block (around the call) or your hämtaFrånText method should declare that it can throw InterruptedException too.

As per the JavaDoc (emphasis my own):
public static void invokeAndWait(Runnable runnable)
throws InterruptedException,
InvocationTargetException
The invokeAndWait can throw two types of exception. In your method, you do not have a try-catch segment to cater with these errors, thus your method must specify that it can potentially throw these exceptions itself because they are not handled internally.
You would need to either:
Add throws InterruptedException to your method signature OR
Have a try-catch block which envelopes EventQueue.invokeAndWait(new Runnable() {... so that any exceptions can be dealt with.

Defining an anonymous class:
new Runnable() {
#Override public void run() { ... }
};
is basically a shorthand for defining a local class:
class MyAnonymousRunnable implements Runnable {
#Override public void run() { ... }
}
and then creating an instance of that class:
new MyAnonymousRunnable();
As such, your code could be written as:
EventQueue.invokeAndWait(new MyAnonymousRunnable());
provided you have a suitable definition of MyAnonymousRunnable.
If you did this, you'd get exactly the same compilation error on that line. However, you know how to catch an exception in code without an anonymous class:
try {
EventQueue.invokeAndWait(new MyAnonymousRunnable());
} catch (InterruptedException e) {
Thread.currentThread().interrrupt();
// Do whatever to handle the exception.
}
So there is no real difference if you define the class anonymously:
try {
EventQueue.invokeAndWait(new Runnable() {
#Override public void run() { ... }
});
} catch (InterruptedException e) {
Thread.currentThread().interrrupt();
// Do whatever to handle the exception.
}

You could envelope your entire EventQueue.invokeAndWait(new Runnable(){...}); code inside another try-catch block like so:
public static void hämtaFrånText() {
try {
EventQueue.invokeAndWait(new Runnable() {
#Override
public void run() {
try {
String aktuellMapp = System.getProperty("user.dir");
JFileChooser fc = new JFileChooser(aktuellMapp);
int resultat = fc.showOpenDialog(null);
if (resultat != JFileChooser.APPROVE_OPTION) {
JOptionPane.showMessageDialog(null, "Ingen fil valdes!");
System.exit(0);
}
String fil = fc.getSelectedFile().getAbsolutePath();
String[] namn = new String[3];
String output = "";
BufferedReader inFil = new BufferedReader(new FileReader(fil));
String rad = inFil.readLine();
int antal = 0;
while(rad != null) {
namn[antal] = rad;
rad = inFil.readLine();
antal++;
}
inFil.close();
} catch(FileNotFoundException e1) {
JOptionPane.showMessageDialog(null, "Filen hittades inte!");
} catch(IOException e2) {
JOptionPane.showMessageDialog(null, "Det misslyckades");
}
}
});
} catch(InterruptedException e3) {
// your catch code here
}
}

Related

How to execute all lines in try block before it moves to catch?

I have to read a file in try block and later print it out. While the print method is working, the program is not running the method. How do I solve this? I can't keep it in the while loop.
Lexer.java
private boolean atEOF = false;
private SourceReader source;
public static void main(String args[]) {
Token token;
try {
Lexer lex = new Lexer(args[0]);
while(!(lex.atEOF)) {
token = lex.nextToken();
}
lex.source.printVec(); // WANT TO EXECUTE THIS METHOD
} catch (Exception e) {
System.out.println("usage: java lexer.Lexer filename.x");
System.exit(-1);
}
}
SourceReader.java
public void printVec() {
System.out.println("in the program");
for (String l : progVec) {
System.out.println(l);
}
}
How do I run printVec() after the while loop in Lexer.java?
I would simply declare the Lexer outside of the try-catch block then put the required Function at the first line of the catch part too.
Lexer lex;
try {
lex = new Lexer(args[0]);
while(!(lex.atEOF)) {
token = lex.nextToken();
}
lex.source.printVec();
} catch (Exception e) {
lex.source.printVec();
//... rest of code
}

Strange thread behavior

I'm trying to do this: The question is displayed in the console. If during some time the user does not write the answer, then the next question is asked. If the user enters an answer, the next question is asked immediately. My code:
public class Test {
private boolean stopQuestion;
Thread scannerThread = new Thread();
public static void main(final String[] args) {
final Test test = new Test();
test.scannerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
String string;
do {
string = test.requestInput(new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (final InterruptedException e) {
}
test.scannerThread.interrupt();
}
}));
} while (!test.stopQuestion);
System.out.println("Input: " + string);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
});
test.scannerThread.start();
}
public String requestInput(final Thread timer) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
timer.start();
System.out.println("Any question");
System.out.println("Please type your answer: ");
try {
while (!br.ready()) {
Thread.sleep(100);
}
} catch (final InterruptedException e) {
System.out.println("Time is over. Next question: ");
return null;
}
System.out.println("Thank You for providing input!");
return br.readLine();
}
}
If you do not write anything to the console, everything seems to work as expected. Time ends and the next question is asked. But if something is written to the console, the timer starts to malfunction and the next question does not wait for the specified amount of time, sometimes it does not wait at all. I do not understand what's the matter.
I created instance of thread outside the method and pass instance to the method as reference but then throws IllegalThreadStateException.
I see two major problems with your code:
You are continously creating threads that are supposed to read input:
do {
string = test.requestInput(new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (final InterruptedException e) {
e.printStackTrace();
}
test.scannerThread.interrupt();
}
}));
} while (!test.stopQuestion); // <-- this is always true
You are opening as many BufferedReaders on System.in as many timer threads you are launching:
final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Also, you are not closing any of these BufferedReader instances.

How to implement runnable with java

I am trying to create a program that will carry on running automatically without me having to do anything. I am a bit confused on how to implement runnable in java so I can create a thread that will go to sleep for a certain period of time and then run the re-run the program after the sleep period is over.
public class work {
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.information();
}
private ConfigurationBuilder OAuthBuilder() {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setOAuthConsumerKey("dy1Vcv3iGYTqFif6m4oYpGBhq");
cb.setOAuthConsumerSecret("wKKJ1XOPZbxX0hywDycDcZf40qxfHvkDXYdINWYXGUH04qU0ha");
cb.setOAuthAccessToken("4850486261-49Eqv5mogjooJr8lm86hB20QRUpxeHq5iIzBLks");
cb.setOAuthAccessTokenSecret("QLeIKTTxJOwpSX4zEasREtGcXcqr0mY8wk5hRZKYrH5pd");
return cb;
}
public void information() throws IOException, InterruptedException {
ConfigurationBuilder cb = OAuthBuilder();
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
User user = twitter.showUser("ec12327");
Query query = new Query("gym fanatic");
query.setCount(100);
query.lang("en");
String rawJSON =null ;
String statusfile = null;
int i=0;
try {
QueryResult result = twitter.search(query);
for(int z = 0;z<5;z++){
for( Status status : result.getTweets()){
System.out.println("#" + status.getUser().getScreenName() + ":" + status.getText());
rawJSON = TwitterObjectFactory.getRawJSON(status);
statusfile = "results" + z +".txt";
storeJSON(rawJSON, statusfile);
i++;
}
}
System.out.println(i);
}
catch(TwitterException e) {
System.out.println("Get timeline: " + e + " Status code: " + e.getStatusCode());
if(e.getErrorCode() == 88){
Thread.sleep(900);
information();
}
}
} catch (TwitterException e) {
if (e.getErrorCode() == 88) {
System.err.println("Rate Limit exceeded!!!!!!");
Thread.sleep(90);
information();
try {
long time = e.getRateLimitStatus().getSecondsUntilReset();
if (time > 0)
Thread.sleep(900000);
information();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
private static void storeJSON(String rawJSON, String fileName) throws IOException {
FileWriter fileWriter = null;
try
{
fileWriter = new FileWriter(fileName, true);
fileWriter.write(rawJSON);
fileWriter.write("\n");
}
catch(IOException ioe)
{
System.err.println("IOException: " + ioe.getMessage());
} finally {
if(fileWriter!=null) {
fileWriter.close();
}
}
}
}
You have severable options to implement a thread in Java.
Implementing Runnable
When a class implements the Runnable interface, he has to override the run() method. This runnable can be passed to the constructor of a Thread. This thread can then be executed using the start() method. If you'd like to have this thread run forever and sleep, you could do something like the following:
public class HelloRunnable implements Runnable {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
Extending Thread
Thread itself also has a run() method. When extending thread, you can override the Thread's run() method and provide your own implementation. Then you'd have to instantiate your own custom thread, and start it in the same way. Again, like the previous you could do this:
public class HelloThread extends Thread {
public void run() {
while(true){
Thread.sleep(1000);
System.out.println("Hello from a thread!");
}
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Source: Oracle documentation
Building on the previous answer, you need to either extend Thread or implement Runnable on your Work class. Extending Thread is probably easier.
public class work extends Thread {
public void run() {
// your app will run forever, consider a break mechanism
while(true) {
// sleep for a while, otherwise you'll max your CPU
Thread.sleep( 1000 );
this.information();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
work test = new work();
test.start();
}
// ... rest of your class
}
public static void main(String[] args){
Thread thread = new Thread(runnable); // create new thread instance
thread.start(); // start thread
}
public static Runnable runnable = new Runnable(){
#Override
public void run(){
final int DELAY = 500;
while(true){
try{
// Code goes here;
Thread.sleep(DELAY)
} catch(Exception e){
e.printStackTrace();
}
}
}
}

What is the best way to write to a file in a parallel thread in Java?

I have a program that performs lots of calculations and reports them to a file frequently. I know that frequent write operations can slow a program down a lot, so to avoid it I'd like to have a second thread dedicated to the writing operations.
Right now I'm doing it with this class I wrote (the impatient can skip to the end of the question):
public class ParallelWriter implements Runnable {
private File file;
private BlockingQueue<Item> q;
private int indentation;
public ParallelWriter( File f ){
file = f;
q = new LinkedBlockingQueue<Item>();
indentation = 0;
}
public ParallelWriter append( CharSequence str ){
try {
CharSeqItem item = new CharSeqItem();
item.content = str;
item.type = ItemType.CHARSEQ;
q.put(item);
return this;
} catch (InterruptedException ex) {
throw new RuntimeException( ex );
}
}
public ParallelWriter newLine(){
try {
Item item = new Item();
item.type = ItemType.NEWLINE;
q.put(item);
return this;
} catch (InterruptedException ex) {
throw new RuntimeException( ex );
}
}
public void setIndent(int indentation) {
try{
IndentCommand item = new IndentCommand();
item.type = ItemType.INDENT;
item.indent = indentation;
q.put(item);
} catch (InterruptedException ex) {
throw new RuntimeException( ex );
}
}
public void end(){
try {
Item item = new Item();
item.type = ItemType.POISON;
q.put(item);
} catch (InterruptedException ex) {
throw new RuntimeException( ex );
}
}
public void run() {
BufferedWriter out = null;
Item item = null;
try{
out = new BufferedWriter( new FileWriter( file ) );
while( (item = q.take()).type != ItemType.POISON ){
switch( item.type ){
case NEWLINE:
out.newLine();
for( int i = 0; i < indentation; i++ )
out.append(" ");
break;
case INDENT:
indentation = ((IndentCommand)item).indent;
break;
case CHARSEQ:
out.append( ((CharSeqItem)item).content );
}
}
} catch (InterruptedException ex){
throw new RuntimeException( ex );
} catch (IOException ex) {
throw new RuntimeException( ex );
} finally {
if( out != null ) try {
out.close();
} catch (IOException ex) {
throw new RuntimeException( ex );
}
}
}
private enum ItemType {
CHARSEQ, NEWLINE, INDENT, POISON;
}
private static class Item {
ItemType type;
}
private static class CharSeqItem extends Item {
CharSequence content;
}
private static class IndentCommand extends Item {
int indent;
}
}
And then I use it by doing:
ParallelWriter w = new ParallelWriter( myFile );
new Thread(w).start();
/// Lots of
w.append(" things ").newLine();
w.setIndent(2);
w.newLine().append(" more things ");
/// and finally
w.end();
While this works perfectly well, I'm wondering:
Is there a better way to accomplish this?
Your basic approach looks fine. I would structure the code as follows:
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public interface FileWriter {
FileWriter append(CharSequence seq);
FileWriter indent(int indent);
void close();
}
class AsyncFileWriter implements FileWriter, Runnable {
private final File file;
private final Writer out;
private final BlockingQueue<Item> queue = new LinkedBlockingQueue<Item>();
private volatile boolean started = false;
private volatile boolean stopped = false;
public AsyncFileWriter(File file) throws IOException {
this.file = file;
this.out = new BufferedWriter(new java.io.FileWriter(file));
}
public FileWriter append(CharSequence seq) {
if (!started) {
throw new IllegalStateException("open() call expected before append()");
}
try {
queue.put(new CharSeqItem(seq));
} catch (InterruptedException ignored) {
}
return this;
}
public FileWriter indent(int indent) {
if (!started) {
throw new IllegalStateException("open() call expected before append()");
}
try {
queue.put(new IndentItem(indent));
} catch (InterruptedException ignored) {
}
return this;
}
public void open() {
this.started = true;
new Thread(this).start();
}
public void run() {
while (!stopped) {
try {
Item item = queue.poll(100, TimeUnit.MICROSECONDS);
if (item != null) {
try {
item.write(out);
} catch (IOException logme) {
}
}
} catch (InterruptedException e) {
}
}
try {
out.close();
} catch (IOException ignore) {
}
}
public void close() {
this.stopped = true;
}
private static interface Item {
void write(Writer out) throws IOException;
}
private static class CharSeqItem implements Item {
private final CharSequence sequence;
public CharSeqItem(CharSequence sequence) {
this.sequence = sequence;
}
public void write(Writer out) throws IOException {
out.append(sequence);
}
}
private static class IndentItem implements Item {
private final int indent;
public IndentItem(int indent) {
this.indent = indent;
}
public void write(Writer out) throws IOException {
for (int i = 0; i < indent; i++) {
out.append(" ");
}
}
}
}
If you do not want to write in a separate thread (maybe in a test?), you can have an implementation of FileWriter which calls append on the Writer in the caller thread.
One good way to exchange data with a single consumer thread is to use an Exchanger.
You could use a StringBuilder or ByteBuffer as the buffer to exchange with the background thread. The latency incurred can be around 1 micro-second, doesn't involve creating any objects and which is lower using a BlockingQueue.
From the example which I think is worth repeating here.
class FillAndEmpty {
Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
DataBuffer initialEmptyBuffer = ... a made-up type
DataBuffer initialFullBuffer = ...
class FillingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialEmptyBuffer;
try {
while (currentBuffer != null) {
addToBuffer(currentBuffer);
if (currentBuffer.isFull())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ... }
}
}
class EmptyingLoop implements Runnable {
public void run() {
DataBuffer currentBuffer = initialFullBuffer;
try {
while (currentBuffer != null) {
takeFromBuffer(currentBuffer);
if (currentBuffer.isEmpty())
currentBuffer = exchanger.exchange(currentBuffer);
}
} catch (InterruptedException ex) { ... handle ...}
}
}
void start() {
new Thread(new FillingLoop()).start();
new Thread(new EmptyingLoop()).start();
}
}
Using a LinkedBlockingQueue is a pretty good idea. Not sure I like some of the style of the code... but the principle seems sound.
I would maybe add a capacity to the LinkedBlockingQueue equal to a certain % of your total memory.. say 10,000 items.. this way if your writing is going too slow, your worker threads won't keep adding more work until the heap is blown.
I know that frequent write operations
can slow a program down a lot
Probably not as much as you think, provided you use buffering.

How to reschedule a task using a ScheduledExecutorService?

I saw this in the java docs: ScheduledAtFixedRate, it says
If any execution of the task
encounters an exception, subsequent
executions are suppressed
I don't want this to happen in my application. Even if I see an exception I would always want the subsequent executions to occur and continue. How can I get this behavior from ScheduledExecutorService.
Surround the Callable.call method or the Runnable.run method with a try/catch...
eg:
public void run()
{
try
{
// ... code
}
catch(final IOException ex)
{
// handle it
}
catch(final RuntimeException ex)
{
// handle it
}
catch(final Exception ex)
{
// handle it
}
catch(final Error ex)
{
// handle it
}
catch(final Throwable ex)
{
// handle it
}
}
Note that catching anything other than what the compiler tells you too (the IOException in my sample) isn't a good idea, but there are some times, and this sounds like one of them, that it can work out if you handle it properly.
Remember that things like Error are very bad - the VM ran out of memory etc... so be careful how you handle them (which is why I separated them out into their own handlers rather than just doing catch(final Throwable ex) and nothing else).
Try VerboseRunnable class from jcabi-log, which does the wrapping suggested by TofuBeer:
import com.jcabi.log.VerboseRunnable;
Runnable runnable = new VerboseRunnable(
Runnable() {
public void run() {
// do business logic, may Exception occurs
}
},
true // it means that all exceptions will be swallowed and logged
);
Now, when anybody calls runnable.run() no exceptions are thrown. Instead, they are swallowed and logged (to SLF4J).
I had the same problem. I also tried that try block within run() method but it doesn't work.
So I did something is working so far:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
public class Test2 {
static final ExecutorService pool = Executors.newFixedThreadPool(3);
static final R1 r1 = new R1();
static final R2 r2 = new R2();
static final BlockingQueue deadRunnablesQueue = new LinkedBlockingQueue<IdentifiableRunnable>();
static final Runnable supervisor = new Supervisor(pool, deadRunnablesQueue);
public static void main(String[] args) {
pool.submit(r1);
pool.submit(r2);
new Thread(supervisor).start();
}
static void reSubmit(IdentifiableRunnable r) {
System.out.println("given to an error, runnable [" + r.getId()
+ "] will be resubmited");
deadRunnablesQueue.add(r);
}
static interface IdentifiableRunnable extends Runnable {
String getId();
}
static class Supervisor implements Runnable {
private final ExecutorService pool;
private final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue;
Supervisor(final ExecutorService pool,
final BlockingQueue<IdentifiableRunnable> deadRunnablesQueue) {
this.pool = pool;
this.deadRunnablesQueue = deadRunnablesQueue;
}
#Override
public void run() {
while (true) {
IdentifiableRunnable r = null;
System.out.println("");
System.out
.println("Supervisor will wait for a new runnable in order to resubmit it...");
try {
System.out.println();
r = deadRunnablesQueue.take();
} catch (InterruptedException e) {
}
if (r != null) {
System.out.println("Supervisor got runnable [" + r.getId()
+ "] to resubmit ");
pool.submit(r);
}
}
}
}
static class R1 implements IdentifiableRunnable {
private final String id = "R1";
private long l;
#Override
public void run() {
while (true) {
System.out.println("R1 " + (l++));
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
System.err.println("R1 InterruptedException:");
}
}
}
public String getId() {
return id;
}
}
static class R2 implements IdentifiableRunnable {
private final String id = "R2";
private long l;
#Override
public void run() {
try {
while (true) {
System.out.println("R2 " + (l++));
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
System.err.println("R2 InterruptedException:");
}
if (l == 3) {
throw new RuntimeException(
"R2 error.. Should I continue to process ? ");
}
}
} catch (final Throwable t) {
t.printStackTrace();
Test2.reSubmit(this);
}
}
public String getId() {
return id;
}
}
}
You can try to comment out Test2.reSubmit(this) to see that without it, R2 will stop working.
If all you want is subsequent executions to occur and continue even after exceptions, this code should work.
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
#Override
public void run() {
try{
System.out.println(new Date() + " printing");
if(true)
throw new RuntimeException();
} catch (Exception exc) {
System.out.println(" WARN...task will continiue"+
"running even after an Exception has araised");
}
}
};
executor.scheduleAtFixedRate(task, 0, 3, TimeUnit.SECONDS);
If a Throwable other than Exception has occurred you might not want subsequent executions get executed.
Here is the output
Fri Nov 23 12:09:38 JST 2012 printing _WARN...task will
continiuerunning even after an Exception has raisedFri Nov 23
12:09:41 JST 2012 printing _WARN...task will continiuerunning
even after an Exception has raisedFri Nov 23 12:09:44 JST 2012
printing _WARN...task will continiuerunning even after an
Exception has raisedFri Nov 23 12:09:47 JST 2012 printing
_WARN...task will continiuerunning even after an Exception has raised

Categories