what does this runtime-error mean?
I already googled it, some say, it belongs to timers, other say its a socket error and more say, it belongs to pictures. I have sockets and timers (lot of timers) and i have no idea, which of these causes it. SOmetimes it works for over an hour, and other times just for 5 minutes. Any Ideas?
A basic impression of what this error is about is enough. If i would post all the code, where it could happen, this page would be multiple kilometres long ( a little extreme of course, but it is lot of code.)
Found right now, it could belong to too many open files but im not using any extern files in my app.
Seems to be a memory leak, belonging to this part:
public static Runnable connection() throws IOException {
Log.e("Communication", "connection");
new Thread(new Runnable() {
public void run() {
Looper.prepare();
try {
serv = new ServerSocket(port); sock = serv.accept();
reader(); } catch (IOException e) {
e.printStackTrace();
}
}
}).start();
return null;
After deleting a part of the code above everything works fine again. Deleted the looper.prepare() and my app does not die anymore.
public static void sendJsonList(final List<String> jsonStrlist,
final String resturl) {
Thread t = new Thread() {
public void run() {
Looper.prepare();
/* Your HTTP clients code */
try {
for (String jsonStr : jsonStrlist) {
/* Loop logic */
response = client.execute(post);
if (response != null) {
/*reponse handler logic */
}
}
} catch (Exception e) {
e.printStackTrace();
}
Looper.loop();
}
};
t.start();
}
Related
I have a simple http server implemented with thread pool. I want to shut down the server gracefully. I referred the post Best Way to Gracefully Shutdown a Java Command Line Program
Here is the basic code:
public static void main(String[] args) {
ThreadPoolServer threadserver = new ThreadPoolServer(9000);
new Thread(threadserver).start();
threadserver.attachShutDownHook();
while (true) {
try {
Thread.sleep(20 * 10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void stopthread(){
this.shutdown = true;
try {
this.serverSocket.close();
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
public synchronized void attachShutDownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
stopthread();
}
});
}
But it seems it does not stop the right way, any ideas? Thx.
This is too small piece of code.
But at the first sight I don't see any check for shutdown value in the main while loop. Secondly the variable should be set after and probably join on the listening thread would be worthy. In the run method I assume you properly handle the exception raised by asynchronous close.
I have a piece of Java program that essentially does the following:
public static void main(String[] args)
{
while(true)
{
// does stuff ...
}
}
The infinite loop is there by design - when left alone the program will loop infinitely. For the most part it works fine. However, sometimes I want to take the program down for maintenance, and when I take it down I want to make sure that it runs through all the code in the loop to the end then exit.
I am wondering what is the best solution for this. One idea I have in mind is to do something like this:
public static void main(String[] args)
{
File f = new File("C:\exit.txt");
while(!f.exists())
{
// does stuff ...
}
}
which basically allows me to gracefully get out of the loop by creating a file called "exit.txt". This is probably OK for my purposes, but I would like to know if there are better, alternative methods.
I think that the WatchService that was introduced in Java 7 may be of use here (if you prefer a file based approach that is). From the JavaDocs:
A watch service that watches registered objects for changes and events. For example a file manager may use a watch service to monitor a directory for changes so that it can update its display of the list of files when files are created or deleted.
Basically what this means is that you can set up a WatchService that can watch a folder for changes. When a change occurs you can choose what actions to take.
The following code uses the WatchService to monitor a specified folder for changes. When a change has happened it executes a Runnable that the caller has provided (the method runWhenItIsTimeToExit).
public class ExitChecker {
private final Path dir;
private final Executor executor;
private final WatchService watcher;
// Create the checker using the provided path but with some defaults for
// executor and watch service
public ExitChecker(final Path dir) throws IOException {
this(dir, FileSystems.getDefault().newWatchService(), Executors.newFixedThreadPool(1));
}
// Create the checker using the provided path, watcher and executor
public ExitChecker(final Path dir, final WatchService watcher, final Executor executor) {
this.dir = dir;
this.watcher = watcher;
this.executor = executor;
}
// Wait for the folder to be modified, then invoke the provided runnable
public void runWhenItIsTimeToExit(final Runnable action) throws IOException {
// Listen on events in the provided folder
dir.register(watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY);
// Run it async, otherwise the caller thread will be blocked
CompletableFuture.runAsync(() -> {
try {
watcher.take();
} catch (InterruptedException e) {
// Ok, we got interrupted
}
}, executor).thenRunAsync(action);
}
}
So, how do we use the checker then? Well, the following code illustrates this:
public static void main(String... args) throws IOException, InterruptedException {
// Setup dirs in the home folder
final Path directory = Files.createDirectories(
new File(System.getProperty("user.home") + "/.exittst").toPath());
// In this case we use an AtomicBoolean to hold the "exit-status"
AtomicBoolean shouldExit = new AtomicBoolean(false);
// Start the exit checker, provide a Runnable that will be executed
// when it is time to exit the program
new ExitChecker(directory).runWhenItIsTimeToExit(() -> {
// This is where your exit code will end up. In this case we
// simply change the value of the AtomicBoolean
shouldExit.set(true);
});
// Start processing
while (!shouldExit.get()) {
System.out.println("Do something in loop");
Thread.sleep(1000);
}
System.out.println("Exiting");
}
Finally, how do you exit the program then? Well simply touch a file in the specified folder. Example:
cd ~/.exittst
touch exit-now.please
Resources:
A good tutorial on how to use the WatchService
WatchService JavaDocs
A good article about CompletableFuture
More stuff about CompletableFuture
Why the WatchService is slow on Mac OS X
One could employ some sophisticated techniques here. The file watchdog is one option. RMI could be another. But in fact, the mechanisms that are required here are quite simple, so I'd like to propose another (very simple) solution.
Note: This solution is just one option, showing that it is possible to do it that way. It is not a general recommendation, and whether it is "good" or not depends on the application case.
The solution is simply based on Sockets. The ServerSocket#accept method already encapsulates the functionality that you want:
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
Based on this, it is trivial to create such a "remote control": The server just waits for a connection, and sets a flag when the connection is opened:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.atomic.AtomicBoolean;
class RemoteExitServer
{
private final AtomicBoolean flag = new AtomicBoolean();
RemoteExitServer()
{
Thread t = new Thread(new Runnable()
{
#Override
public void run()
{
waitForConnection();
}
});
t.setDaemon(true);
t.start();
}
private void waitForConnection()
{
ServerSocket server = null;
Socket socket = null;
try
{
server = new ServerSocket(1234);
socket = server.accept();
flag.set(true);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (server != null)
{
try
{
server.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
boolean shouldExit()
{
return flag.get();
}
}
The client does exactly that: It opens a connection, and nothing else
import java.io.IOException;
import java.net.Socket;
public class RemoteExitClient
{
public static void main(String[] args)
{
Socket socket = null;
try
{
socket = new Socket("localhost", 1234);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (socket != null)
{
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
}
The application is then also very simple:
public class RemoteExitTest
{
public static void main(String[] args)
{
RemoteExitServer e = new RemoteExitServer();
while (!e.shouldExit())
{
System.out.println("Working...");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
}
System.out.println("done");
}
}
(The code could be made even more concise with try-with-resources, but this should not matter here)
You could make use of runtime shutdown hook. That way you won't need to use console input in order to stop the loop. If JVM is being closed normally then shutdown hook thread will run. This thread will wait for the end of current loop iteration. Keep in mind that there are some limitations when using hooks though: https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-
import java.util.concurrent.CountDownLatch;
public class Test {
private volatile static CountDownLatch lastIterationLatch = null;
private static boolean stop = false;
public static void main(String [] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
lastIterationLatch = new CountDownLatch(1);
try {
lastIterationLatch.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
while(!stop) {
System.out.println("iteration start");
Thread.sleep(200);
System.out.println("processing...");
Thread.sleep(200);
System.out.println("processing...");
Thread.sleep(200);
System.out.println("processing...");
Thread.sleep(200);
System.out.println("iteration end");
if(lastIterationLatch != null) {
stop = true;
lastIterationLatch.countDown();
}
}
}
}
For something quick/dirty, use Signals:
boolean done = false;
// ...
Signal.handle(new Signal("USR1"), new SignalHandler() {
#Override
public void handle(Signal signal) {
// signal triggered ...
done = true;
}
});
// ...
while(!done) { ... }
Then, use kill -USR1 _pid_ to trigger the signal.
You could use a AtomicBoolean as in the test program below.
To suspend just type true into the console to resume type false. The program will never exit.
public class Test2 {
public static void main(String[] args) {
final AtomicBoolean suspended = new AtomicBoolean(false);
new Thread() {
public void run() {
while (true)
{
Scanner sc = new Scanner(System.in);
boolean b = sc.nextBoolean();
suspended.set(b);
}
}
}.start();
while(true){
if(!suspended.get()){
System.out.println("working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
//System.exit(0) //if you want to exit rather than suspend uncomment.
}
}
}
}
I'm trying to do something potentially stupid, but I reckon it's a good idea, so bear with me. I tried to implement it, but I hit an awkward issue with sockets closing between threads - so I want some fresh eyes on the case.
Scenario
I want to write an object from a Client to a Server via sockets. There may be more than one Client communicating with the Server concurrently.
The object, a Message, is handled by the Server through its handling mechanisms. It is proposed that instead of the Server's main thread looking out for new incoming connections, a Listener thread is set up. Once it spots an incoming connection, it alerts the Server, storing the socket in a queue without receiving the data, so it can go back to listening quickly.
In its own time, the Server picks up the waiting socket, spawns a new thread, reads the Message, and closes the socket.
The code
Here's my first thoughts on how this should be implemented. There is a fundamental flaw in it which I will explain below.
Ignore the use of public fields - I'm just trying to make the code short for you guys
public class Server {
public boolean messageWaiting = false;
public static void main(String[] args) {
new Server().run();
}
public void run() {
Listener l = new Listener();
l.listen(this);
try {
while (true) {
System.out.println("I'm happily doing my business!");
Thread.sleep(1000);
if (messageWaiting) {
acceptMessages(l);
}
}
} catch (InterruptedException die) {}
}
private void acceptMessages(Listener l) {
while (!l.waiting.isEmpty()) {
try (
Socket client = l.waiting.poll();
ObjectInputStream ois = new ObjectInputStream(client.getInputStream())
) {
// Handle messages in new threads! (or a thread pool)
new Thread() {
public void run() {
try {
System.out.println(ois.readObject());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}.start();
} catch (Exception ex) {
// Oh no! The socket has already been closed!
ex.printStackTrace();
}
}
}
}
public class Listener {
public ConcurrentLinkedQueue<Socket> waiting = new ConcurrentLinkedQueue<>();
public void listen(final Server callback) {
new Thread() {
public void run() {
try (ServerSocket rxSock = new ServerSocket(7500)) {
while (!isInterrupted()) {
try (Socket client = rxSock.accept()) {
// Once a new socket arrives, add it to the waiting queue
waiting.add(client);
// Alert the server
callback.messageWaiting = true;
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}.start();
}
}
public class Client {
public static void main(String[] args) {
try (
Socket txSock = new Socket(InetAddress.getLoopbackAddress(), 7500);
ObjectOutputStream oos = new ObjectOutputStream(txSock.getOutputStream())
) {
oos.writeObject("This is a Message, trust me.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
What's wrong with this?
This:
I'm happily doing my business!
I'm happily doing my business!
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
at Server.acceptMessages(Server.java:30)
at Server.run(Server.java:20)
at Server.main(Server.java:9)
This is because the Java 7 try blocks I'm using close the sockets once they're finished. So why don't I do this manually? Try yourself - you end up with a warning saying you're only ever going to call close() on a null object!
So, how do I avoid the whole issue of my incoming socket being closed before the Server thread picks up on it? Or is this a bad idea anyway and I should do something else?
Your statement in Listener
try (Socket client = rxSock.accept()) { ...
Is a try-with-resources for the client socket. As soon as you add it to the queue and exit the try block, the socket gets auto-closed.
I have a question relating to the timer function. I have managed to find the cause of my problem, but I'm not sure on how to address it. I will give you an overview of my function. It will first execute the cost() function, with a background thread working. However, what I realize was that my cost() function failed to load right at the beginning. Secondly, it's program to run every 60 secs which it failed as well. I check my code for my cost() function and it works fine if I call it down without the timer function. Could it be my Opencsv() function? The question is it due to constraint of the timer function or is there ways to address this issue?
public static void main(String[] args) {
launch(EVschedulerApp.class, args);
Timer timer = new Timer();
// timer.scheduleAtFixedRate(new Cost(), 10*1000, 10*1000);
timer.scheduleAtFixedRate(new Cost() {
#Override
public void run() {
new Thread(new Runnable() {
public void run() {
File file = new File("D:/test.csv");
if(file != null){
try {
Opencsv csv = new Opencsv();
csv.Csvreader();
} catch (IOException ex) {
Logger.getLogger(EVschedulerApp.class.getName()).log(Level.SEVERE, null, ex);
}
}
else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}
}).start();
}
Opencsv class file:
public class Opencsv {
public void Csvreader() throws IOException {
try {
// TODO code application logic here
CSVReader reader = new CSVReader(new FileReader("D:/Test.csv"));
String [] nextLine;
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
System.out.println(nextLine[0] + " " + nextLine[1]+ " " + nextLine[2]+ " " + nextLine[3]);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Opencsv.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Cost Class:
public class Cost extends TimerTask{
public void run() {
Calendar rightNow = Calendar.getInstance();
Integer hour = rightNow.get(Calendar.HOUR_OF_DAY);
if (hour==23 ) {
try {
URL tariff = new URL("http://www.******.downloadRealtime=true");
ReadableByteChannel tar = Channels.newChannel(Test.openStream());
FileOutputStream fos = new FileOutputStream("Test.csv");
fos.getChannel().transferFrom(tar, 0, 1<<24);
} catch (IOException ex) {
Logger.getLogger(Cost.class.getName()).log(Level.SEVERE, null, ex);
}
}
else {
}
}
I really think that your "bug" is not here, but somewhere else. Also you should be really looking at
ScheduledThreadPoolExecutor
instead of the Timer, it would be something like this :
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//Do your stuff in here
}
}), 60, TimeUnit.SECONDS );
Also may I recommend not to swallow the InterruptedExceptions - there are a lot of posts here on SO on this subject.
Cheers,
Eugene.
I think your bug is that you never call Cost's run() method, you are not just overriding it, you are hiding it. Try something like this:
timer.scheduleAtFixedRate(new Cost() {
#Override
public void run() {
super.run(); //Added this call to Cost's original method.
new Thread(new Runnable() {
public void run() {
//your code still here
}
}).start();
}
Although, as others point out, you should look into the Executor Service.
It seems that your bug is in class Cost that you have not posted here.
But anyway you have yet another problem here. Why do you create yet another thread inside run() of timer task. It may have sense only if your business logic takes significant time. In your case if your csv file is very large.
Start from simple implementation. Create task that synchronously pareses CSV. Schedule it and see how is it working. If and only if you see that task takes a lot of time thing about using yet another thread. In this case take a look on Executors.
here's a little code I wrote. This next class waits for a connection and creates a new thread upon receiving one:
ServerSocket serverSocket = null;
ExecutorService serv = Executors.newCachedThreadPool();
serv.execute(new UserThread());
try {
serverSocket = new ServerSocket(FMDataManager.getPort());
serverSocket.setSoTimeout(0);
while (_listening){
System.out.println("Listening on port "+FMDataManager.getPort());
System.out.println("Waiting for connections.");
serv.execute(new UploadThread(serverSocket.accept()));
}
} catch (IOException e) {
System.err.println("Could not listen on port: "+FMDataManager.getPort()+".");
System.exit(-1);
}
as you can see i am using ServerSocket.accept() method to wait for a connection.
The thread is indeed created, but it won't run. I put a little "thread created" in its constructor and another message "starting thread" in run(), but I only got the first message. After that it didn't do anything, I didn't even get "thread created".
Any ideas please?
I've add the implementation of the UploadThread I am trying to start, maybe It'll help
public class UploadThread extends Thread{
Socket _socket;
public UploadThread(Socket socket) {
super("UserThread");
_socket = socket;
}
public void run(Socket socket) {
System.out.println("entred upload thread");
DataOutputStream out = null;
DataInputStream in = null;
try {
out = new DataOutputStream(_socket.getOutputStream());
in = new DataInputStream(_socket.getInputStream());
FileMessage inputMessage;
SendFile outputMessage;
inputMessage = (FileMessage) CommandEnum.readMessage(in);
System.out.println("F: "+inputMessage.getCaption());
File file = null;
Iterator<File> itr = FMDataManager.getFiles().iterator();
while (itr.hasNext()){
File temp = itr.next();
if (temp.getName().equals(inputMessage.getFile()))
file = temp;
}
outputMessage = new SendFile(file);
outputMessage.send(out);
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
_socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Try serv.submit instead of serv.execute.
EDIT
Looks like UploadThread isn't overriding run() correctly. That being said, your run method declaration should look like this:
#Override
public void run(){
//do stuff
}
There's no need to pass socket as an argument.
As indicated by sthupahsmaht's comment your UploadThread implementation is wrong. The signature for the run() method is public void run(). Currently you are creating a new method with the signature public void run(Socket). As run() doesn't take any arguments you have to pass all parameters via the constructor or setters.
There are two best practices that can help you avoid such mistakes in the future:
Whenever you implement or override a method, annotate it with #Override. If you create a new method with #Override, the compiler signals an error.
Don't extend Thread but implement Runnable. Thread has a default implementation for run() which does nothing. This is what happens with your code currently.
Without seeing the part of the code that actually constructs the thread, I'll guess you're NOT calling the 'start()' method on the thread object.
Needs to be something like this:
Thread thr = new Thread(new Runnable() { void run() { /* do stuff */ }) ;
thr.start() // GO!