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.
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.
I am writing a Java application in IntelliJ IDE. The application uses Rserve() to connect to R and access scripts. I have a java script which sends a command to the shell to start Rserve(). The problem I am facing now is the first time when I run the application, I get the following error:
Exception in thread "main" java.lang.NoSuchMethodError: org.rosuda.REngine.REngineException.<init>(Lorg/rosuda/REngine/REngine;Ljava/lang/String;Ljava/lang/Throwable;)V
at org.rosuda.REngine.Rserve.RserveException.<init>(RserveException.java:59)
at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:90)
at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:60)
at org.rosuda.REngine.Rserve.RConnection.<init>(RConnection.java:44)
at de.uni_jena.bioinformatik.RecalibrationGUI.Application.main(Application.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
And, when the next time I run the application, it works perfectly. From what I can understand, in the first run, it just established the Rserve() connection and then in the second run it works. Can someone help me fix this, so that the application connects to Rserve() in the first instance and also runs perfectly?
Here is the java class which calls Rserve()
public class InvokeRserve {
public static boolean invoke() {
try {
Process p = Runtime.getRuntime().exec("R CMD Rserve --vanilla");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
}
catch (IOException e) {
System.out.println("Rserve connection: Exception occurred: ");
e.printStackTrace();
System.exit(-1);
}
return true;
}
}
And, here is the main java class which starts the application and calls the invoke() method:
public class Application {
/**
* Main method for the Swing application
*
* #param args
* #throws Exception
*/
public static void main(String[] args) throws Exception {
boolean value = InvokeRserve.invoke();
RConnection check = new RConnection();
if(check.isConnected())
{
// Run the GUI construction in the Event-Dispatching thread for thread-safety
SwingUtilities.invokeLater(new Runnable() {
/**
* run method which create a new GUIMain object
*/
#Override
public void run() {new GUIMain("Java Application"); // Let the constructor do the job
}
});
}
else
System.out.println("There was no R connection found.");
}
}
Also, is there a way to stop an existing Rserve() connection (I read different answers which suggest using shutdown(), but it is not working for me)? Every time, I have to restart my computer to shutdown an existing connection and start a new connection to test the above code.
I also looked into the StartRserve.java example file at http://www.rforge.net/DATRAS/files/org/rosuda/Mondrian/StartRserve.java. But when I use the method StartRserve.checkLocalRserve() in the main class of my application, I get the same Rserve() error as shown above.
Your invoke() method returns before Rserve is actually started, so you're apparently trying to connect too early. You may want to add p.waitFor();. See also the StartRserve class which is far more robust in starting Rserve from Java.
PS: I'd recommend using the stats-rosuda-devel mailing list for Rserve questions which gives you much faster responses.
I have a solution for shutting Rserve connection withoutt shutting down the computer. Try this while opening an Rconnection:
RConnection rconn=null;
try{
rconn=new RConnection();
//Your personal code here
} catch(Exception exc){
exc.printStackTrace(out);
} finally{
if (rconn!=null){
rconn.close();
}
}
This way when the app stops halfway with an exception, it still runs the finally part and closes the connection.
Hope this helps in time.
As for the exception-part details, it would be possible to answer if you could display the line numbers beside the code, as the exception log refers to the code by line numbers.
I am working on a project that has to process external signals passed as an input to Java program. The signals can be corrupted (i.e. we don't have much control of the input) which may lead to processing errors (such as DivisionByZeroException).
What my team wants is that each time uncaught exception is thrown, which causes the Java program to terminate, SOME CODE should just restart the Java program from scratch.
Therefore, my main question is: Any danger of writing SOME CODE in the following way?
MY SOLUTION (SOME CODE will be another Java class):
Suppose our Java program is implemented as a method M of class C that gets called once and ideally should run forever.
I firstly make class C implement Runnable interface.
I then override run method as:
class C implements Runnable {
#Override
public void run() {
this.M();
}
public void M() {
// Code for main method to be called ONCE and ideally run FOREVER
....
}
}
Finally, I create a wrapper (called Recovery class) around class C to restart C.M() each time an exception is thrown:
class Recovery {
final Object lock = new Object();
void runAndRecover(final Runnable runnable) { // Will pass an instance of C
while (true) {
// Synchronising to make sure that only one instance
// of runnable input is running at the time.
synchronized(lock) {
try {
runnable.run();
// Ideally the process should run forever
// (no termination),
// and the code of THIS FILE will be blocked HERE
// with the runnable RUNNING (which is what we want).
} catch (Exception exception) {
// If the process was interrupted
// by uncaught exception,
// we will restart it.
lock.notifyAll();
}
}
}
}
}
What I hope is that we could run the system as follows:
public static void main(final String[] args) {
C c = new C();
Recovery recovery = new Recovery();
recovery.runAndRecover(c);
// My hope is that code gets blocked HERE and runs REGARDLESS
// of anything happening inside c. Can I make such assumption?
}
A side question: if this approach is not safe, I could then write a shell script to restart the Java program each time exception is thrown. What would be a simple shell loop to repeatedly execute command sudo java /path/to/Program? Is writing a shell script safer?
I have such code in my application which I want to run in background:
import java.awt.*;
import java.awt.datatransfer.*;
class Main extends Thread implements ClipboardOwner {
private Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
public void run() {
Transferable trans = sysClip.getContents(this);
regainOwnership(trans);
System.out.println("Listening to board...");
while (true) { }
}
public static void main(String[] args) {
Main b = new Main();
b.start();
}
//............
It listens for Ctrl+C and prints the content of clipboard once this key combination is pressed. However, it makes CPU run 99% all the time. If I remove while (true) { } then the application will just stop in a second.
I tried to launch it as java -jar myapp.jar & but the result was the same. And it would be the same on Windows I guess, although I care about Linux for now.
What do I do about that?
You have a thread running an infinite loop. That's exactly the sort of thing that will use 100% of your CPU for nothing. If nothing else, putting a couple second Thread.sleep() in the loop will bring the CPU usage down.
You should avoid using eternal loops to check if a variable has changed, but rather use a listener. To be more precise, a FlavorListener will allow you to execute code when the clipboard has changed.
It would be something like this:
Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(
new FlavorListener() {
#Override
public void flavorsChanged(FlavorEvent e) {
System.out.println("Clipboard contents: " + e.toString());
}
});