I have a Console Java Application in maven, infinite loop
I have handle exception in java
public class MyClassName {
public static void main(String[] args) {
while (true) {
start();
}
}
private static void start() {
try {
//this method check new files in S3 and copy to network location also it has throws Throwable
//i have not added code here because it is too long
doProcess()
} catch (Throwable t) {
t.printStackTrace();
}
}
}
doProcess() method check new files in S3 and copy to Network Machine
also it has throws Throwable
after creating jar, in windows command promp
java -jar -Xmx8192M jarname.jar
when it throws exception, pause completely until ctrl+C, but if I ctrl+C it will resume again,
what is wrong here?
is there any wrong on java code or is there any wrong on command?
Related
I am now executing java a java program like this:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
I want to execute the Test.execute() method in linux shell script, wait until the method return and get return code . but the return of main() method is void , so what Can I do the get a return code or return msg from it ?
Any suggestions?
I find a solution:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
System.out.println("sleeping");;
Thread.sleep(5000);
Runtime.getRuntime().exit(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
And then my shell:
#!/bin/bash
java -cp test.jar com.test.Test
echo "The return code of the java application is $?"
I can get the value n which is in Runtime.getRuntime().exit(n);
First change the signature of main method in your code example:
public static void main() to public static void main(String[] args)
Then instead of just calling the execute method from main, try to print the result using System.out.println :
System.out.println(execute());
and then in linux shell you can use following to get the return values:
> set out = `java com.test.Test`
> echo $out
The shell script would have to call java com.test.Test. And this will call the main method which inturn is currently calling execute.
From a shell script you would have to start a JVM and a JVM always starts with a Main method.
As for the return code, you can access it using the $? shell variable.
So basically your shell script would be something like this:
#!/bin/bash
java -cp . com.test.Test
echo "The return code of the java application is $?"
Also you need to specify the classpath where all you relevant classes reside. In the above example I am putting in the current dir as the classpath.
The JVM will terminate with a exit code of 0 on completion of all non-daemon threads. If you want to return a specific exit code in case of an error you can use System.exit(<codehere>). Please note that calling System.exit() will cause the JVM to shutdown even if there are other non-daemon threads that are running.
Edit:
Added "-cp ." to the command based on the comments.
Added some exit code details
I want to get latest/updated copy on environment variable using java.
Java is not returning latest copy if someone changed particular environment variable after running a programme.
please use below sample code to test the scenario.
import javax.swing.JOptionPane;
public class Test extends Thread {
public static void main(String[] args) {
Test test = new Test();
test.start();
}
#Override
public void run() {
super.run();
while (true) {
JOptionPane.showMessageDialog(null, System.getenv("A"));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Update:
Tried ProcessBuilder also
ProcessBuilder processBuilder = new ProcessBuilder("echo %A%");
System.out.println(processBuilder.environment().get("A"));
The environment variables are set when the JVM starts and will not change.
That is generally true for all Windows programs. E.g. start a Command Prompt, change an environment variable through the Windows Control Panel, and the Command Prompt will not see the changed value.
Only Command Prompts opened after the change will see the change.
How can I restart my Java Console Application.
I want to create a method that when it's being called it restart or relaunch the console application. Can you guys give me some ideas how can I do it?
Have you tried calling main(args) passing in String[] args
If you really want a restart() method you could do something like
private void restart(String[] strArr)
{
main(strArr);
}
Crude mini example
import java.io.*;
public class Test{
public static void main(String[] args)
{
try{
System.out.println("Type 'R' to restart");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
if(input.equals("R"))
restart(args);
else
System.out.println("You did not restart");
}
catch(Exception e)
{e.printStackTrace();}
}
private static void restart(String[] strArr)
{
System.out.println("You restarted");
main(strArr);
}
}
I can't think of a way to do it using just Java, you will need some help from scripting. You could restart by finishing the JVM execution with System.exit() and using a special value for the caller to know if it needs to be restarted rather than finished. So in your Java code you would have something like this:
public class Test {
public static final int RESTART_CODE = 100;
public static void main(String ... args) throws IOException {
// DO something...
restart();
}
static void restart() {
System.exit(RESTART_CODE);
}
}
And then a script invoking the JVM (in this case a Linux bash script, you could do something similar with a *.bat file if you're using Windows). Tee script:
#!/bin/bash
java Test "$#"
[ $? == 100 ] && ./test.sh "$#"
An then you can call your program with
java.sh _argument1_ _argument2_ ...
Theoretically, you should be able to called Runtime.exec() and pass in the command to run your Java Console App.
For precaution, prior to calling Runtime.exec(), you should save all the data or reach the state where your application is ready to exit.
As Runtime.exec() will execute another instance of console app, and the new instance could have loaded all the data.
After successfully called Runtime.exec(), the existing app can peacefully die off.
Let me know if this can be done, as my concern is whether the new instance will be killed off when the existing app exited.
I'm using commons VFS to monitor certain folder for changes (mainly inserting new file), the program should runs permanently, I use the following code
FileSystemManager fsManager = VFS.getManager();
FileObject listendir = fsManager.resolveFile(path);
DefaultFileMonitor fm = new DefaultFileMonitor(new VfsListener());
fm.setRecursive(true);
fm.addFile(listendir);
fm.start();
where path is the folder path, and VfsListener is a class that implements FileListener, when I run the program it runs and then closed immediately, when I added this after fm.start() :
Thread.sleep(100000)
the program run for a while and then closed after the time out is reached, and I don't want that, I want the program to rum permanently, if anyone know please reply
VFS starts the FileMonitor thread as a daemon thread in low priority. The definition of the method setDaemon(boolean) states that
Marks this thread as either a daemon thread or a user thread. The
Java Virtual Machine exits when the only threads running are all
daemon threads.
This method must be called before the thread is started.
This is the reason your program works as long as you 'sleep' in the main thread. However, this is only an issue if you're running this program as a standalone java program. If you run the same piece of code in a application server like Jboss, the code just works fine.
If you still want the standalone program to wait indefinitely, you can modify the program to use a ThreadPoolExecutor which will essentially wait for the new tasks to be available in the Task Queue.
public static void main(String[] args) throws FileSystemException {
Executor runner = Executors.newFixedThreadPool(1);
runner.execute(new Runnable() {
#Override
public void run() {
FileObject listendir = null;
try {
FileSystemManager fsManager = VFS.getManager();
listendir = fsManager.resolveFile(absolutePath);
} catch (FileSystemException e) {
e.printStackTrace();
}
DefaultFileMonitor fm = new DefaultFileMonitor(new FileListener() {
#Override
public void fileDeleted(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Deleted.");
}
#Override
public void fileCreated(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Created.");
}
#Override
public void fileChanged(FileChangeEvent event) throws Exception {
System.out.println(event.getFile().getName().getPath()+" Changed.");
}
});
fm.setRecursive(true);
fm.addFile(listendir);
fm.start();
}
});
}
Hope this helps.
This question already has answers here:
How to start/stop/restart a thread in Java?
(9 answers)
Closed 7 years ago.
I have created a program which searches for files in a source folder. If it finds any file, it processes that file and moves it to a destination folder, then looks for a new file in the source folder. It has to keep on checking the source folder for a file.
I have used a thread to look for files in the source folder. The problem I am facing is whenever any exception is thrown during file processing, the thread gets stopped. I want the thread to be running even if an exception is thrown. It has to move the file that caused the error to some other folder and look for a new file in the source folder. How can I make the thread keep on running?
Eg:
public void run() {
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){
...
}
Update :
I should be more clear in my question. Actually there are 4 source folders and 4 destination folders. I have to perform the same operation in each source & destination pair. So i have created 4 threads in one class and do the operation in separate class.
class MainClass
{
public static void main(String[] args){
for(int i=0;i<4;i++){
SearchClass search = new SearchClass();
Thread thread = new Thread(search);
thread.start();
}
}
}
class SearchClass
{
public void run() {
try {
searchfile();
} catch(Exception e) {
e.printStackTrace();
}
}
public void searchfile(){ ... } }
All the thread wont stop running eventhough it caught any exception in middle. How can i do that?
If a thread is dying due to an uncaught exception, the answer is simple: catch the exception at an appropriate place so that you can keep going. Either catch the exception within your searchfile method, or make the run method call searchfile in a loop.
If you want your thread to keep running use a loop.
public void run() {
while(!Thread.interrupted())
try {
searchfile();
}
catch(Exception e) {
e.printStackTrace();
}
}
Inside your catch, you can move the file to the error folder then create a new object of the same thread and start it again.
unless i got you wrong, your code is missing the "keep running" nature, i.e. you need to have a loop somewhere:
public static void main(String[] args){
ExecutorService service = Executors.newFixedThreadPool(4);
// for each of your 4 folders
while (true) {
Future<File> searchResult = service.submit(new SearchTask());
try {
File foundFile = searchResult.get();
// handle found file
} catch (Exception e) {
// handle exception
}
}
}
private static class SearchTask implements Callable<File> {
#Override
public File call() {
return searchFile();
}
public File searchFile() {
// search & return found file
}
}
note that this is just a very simple extension of your example. it is still missing the parametrization of the SearchTask to actually be specific for a folder, handling of files & exceptions, etc. as mentioned in previous answers, your SearchTask should implement Runnable (i prefer Callable...), and IMHO it's always better to use an ExecutorService than to spawn threads manually. hope this helps...
I'm not entirely sure if this will work, yet here's a try.
public void run() {
try {
searchFile();
} catch(Exeption e) {
e.printStackTrace();
if(!Thread.currentThread().isAlive())
Thread.currentThread().start();
}
}
you said that the exception may be thrown during file process , so i put the processFile() in a try-catch block. but if it may be thrown during search, you may put it in a try-catch too.
public void run() {
while(!terminated) {
findNextFile();
try {
processFile();
} catch {
// handle error
}
}
}
Here are my assumptions based on your question and your clarification:
Each thread, in the run() method, only calls searchfile() once and not in a loop
your searchfile() method has a loop in it and you want that loop to continue running even if an exception is thrown in it.
you have some way of initializing each thread that you aren't showing us (and that isn't terribly important for this specific quiestion)
searchfile() does not declare that it throws any Exception
You aren't using a logging framework, but are instead using System.out (although using a logging framework is a Really Good Idea
Java 5 is OK (otherwise you'll have to use a different for() loop below
With these assumptions, you don't want to plan to catch an Exception in your run() method except for the purpose of logging that something went very wrong:
public void run() {
try {
searchfile();
} catch (RuntimeException e) {
System.out.println("Something went very wrong! Unexpected RuntimeException");
e.printStackTrace();
}
}
Note that the code catches RuntimeException. Always catch the most specific Exception that will do what you need. Then what you need is something such as the following in your searchfile() method:
File[] files = directory.listFiles();
for (File file : files) {
try {
// Do your normal file/directory processing here
} catch (Exception e) {
System.out.println("Exception processing file " + file.getName() + " " + e);
// Move "file" to another area
}
}
Since you are trapping unexpected Exceptions in the main loop of your Thread, your thread will continue processing after handling the Exception.
You can easily go with a workaround. Just run the needed logic for some amount of times and finish the job based on some criteria.
public class ThreadRestartWorkaround extends Thread {
public static void main(String[] args) {
ThreadRestartWorkaround th = new ThreadRestartWorkaround(5);
th.start();
}
private int maxCycles;
private int currentCycle;
public ThreadRestartWorkaround(int maxCycles) {
this.maxCycles = maxCycles;
}
#Override
public void run() {
while(executeSomeLogicUntilReachingTheLimit());
System.out.println("Finished due to exceeding the maxCycles config");
}
private boolean executeSomeLogicUntilReachingTheLimit() {
currentCycle++;
System.out.println("Executing logic for " + currentCycle + " time");
return currentCycle < maxCycles;
}
}
And the output is
Executing logic for 1 time
Executing logic for 2 time
Executing logic for 3 time
Executing logic for 4 time
Executing logic for 5 time
Finished due to exceeding the maxCycles config