I am willing to add a button in my application which on-click will restart the app. I searched Google but found nothing helpful except this one. But the procedure follows here is violating the WORA concept of Java.
Is there any other Java centric way to achieve this feature? Is it possible to just fork another copy and then exit?
Thanks in advance. I appreciate your help.
#deporter I have tried your solution but it is not working :(
#mKorbel I wrote the following code by taking concept you had shown in so
JMenuItem jMenuItem = new JMenuItem("JYM");
jMenuItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(true);
ScheduledFuture<?> future = executor.schedule(new Runnable() {
#Override
public void run() {
try {
Process p = Runtime.getRuntime().exec("cmd /c start java -jar D:\\MovieLibrary.jar");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}, 2, TimeUnit.SECONDS);
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.exit(0);
}
});
And also:
ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(2);
Callable<Process> callable = new Callable<Process>() {
#Override
public Process call() throws Exception {
Process p = Runtime.getRuntime().exec("cmd /c start java -jar D:\\MovieLibrary.jar");
return p;
}
};
FutureTask<Process> futureTask = new FutureTask<Process>(callable);
schedulerExecutor.submit(futureTask);
schedulerExecutor.shutdown();
try {
schedulerExecutor.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.exit(0);
its working but only once. If I launch the application for first time and press JYM menuitem then it shutdowns and after few second it opens a new ui with cmd, but if I press that JYM menuitem the application terminate completely, i.e., it is not again launches anymore.
I really appreciate your help.
It is solved.
The solution:
Call the following code from the ActionListener.
ScheduledExecutorService schedulerExecutor = Executors.newScheduledThreadPool(2);
Callable<Process> callable = new Callable<Process>() {
#Override
public Process call() throws Exception {
Process p = Runtime.getRuntime().exec("cmd /c start /b java -jar D:\\MovieLibrary.jar");
return p;
}
};
FutureTask<Process> futureTask = new FutureTask<Process>(callable);
schedulerExecutor.submit(futureTask);
System.exit(0);
Thanks.
The link that u provided in your answer is the best way to restart your swing app. Let me ask you, is not having it done through " WORA" a bad thing? Most applications come with a platform centric launcher. It makes your app look and feel like a native application. Are u planning on deploying your entire app as a double clickable jar file ? Double clicking a jar file is not very intuitive. Sometimes if the local computer installs winip or winrar for example if you double click a jar file it doesn't launch your app by default.
To solve such issues it's best having a native launcher. Take a look at db visualizer it has native launchers for it's java swing program
Related
I wrote a program in which a pdf file should be opened on an Action Event (you can have a look at my code below).
menuElementHilfe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
File hilfe = new File ("src\\resources\\Hilfe.pdf");
try {
java.awt.Desktop.getDesktop().open(hilfe);
} catch (IOException e) {
e.printStackTrace();
}
}
});
If I execute the program via Eclipse everything works, but after exporting as a runnable jar I get following Exception:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: The file: src\resources\Hilfe.pdf doesn't exist.
Any Feedback is appreciated
The way you're retrieving resources may be the problem. try this :
menuElementHilfe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
File hilfe = new File(getClass().getResource("/resources/Hilfe.pdf").getFile());
try {
java.awt.Desktop.getDesktop().open(hilfe);
} catch (IOException e) {
e.printStackTrace();
}
}
});
When running in Eclipse, you are targeting a file in your build path.
When running from JAR/WAR, the URL is different and look like "jar:file:/your-path/your-jar.jar!/Hilfe.pdf" which is not what you set when calling new File(...) So to get the right URL for internal resources, you have to use methods like getResource or getResourceAsStream depending on your needs.
Check out following explanations for more information :)
https://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html
[EDIT]
I assume you're working on some Swing app, but I dont know if you're aware that doing some task like that in your AWT-EventQueue thread will freeze your UI.
To prevent that you have to run UI-unrelated stuff in another thread.
This is made using SwingUtilities.invokeLater (Java 5 and prior) method and/or the SwingWorker class (since Java 6).
as mentionned in this answer
You should put the previous solution in something like that :
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Your UI unrelated code here
}
});
The resource can be packed in the application jar, hence File (physical disk file)
is not possible. Copy it to a temporary file, so that the desktop can open it.
menuElementHilfe.addActionListener(evt -> {
Path tmp = Files.createTempFile("hilfe-", ".pdf");
Files.copy(getClass().getResourceAsStream("/Hilfe.pdf"), tmp);
try {
Desktop.getDesktop().open(tmp.toFile());
tmp.toFile().deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
});
An other difference is the forward slash, and that the path is case-sensitive, opposed to Windows File.
After problems
menuElementHilfe.addActionListener(evt ->
SwingUtilities.invokeLater(() -> {
Path tmp = Files.createTempFile("hilfe-", ".pdf");
Logger.getLogger(getClass().getName()).log(Level.INFO, "actionPerformed "
+ tmp + "; event: " + evt);
Files.copy(getClass().getResourceAsStream("/resources/Hilfe.pdf"), tmp);
try {
Desktop.getDesktop().open(tmp.toFile());
//tmp.toFile().deleteOnExit();
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.WARN, "Error with " + tmp,
e);
}
}));
I did not delete, so the Desktop access can live longer than the java app.
I did an invokeLater in order to have no frozen GUI on the actionPerformed.
I added logging to see every call to actionPerformed
I made spark+hadoop yarn enviroment and spark-submit command works well. So I made SparkLauncher java code to do this in my application jar, BUT somehow it doesn't work (actually computer fan is spinning at first but not as long as i did with spark-submit.)
It seems not work well (no application log in hadoop web ui, unlike spark-submit). I cannot see any error log when I do with 'SparkLauncher'. without log message, I can do nothing with it.
Here is how I made it so far.
public class Main {
public static void main(String[] args) {
Process spark = null;
try
{
spark = new SparkLauncher()
.setAppResource("/usr/local/spark/examples/jars/spark-examples*.jar")
.setMainClass("org.apache.spark.examples.SparkPi")
.setMaster("yarn")
.setDeployMode( "cluster")
.launch();
}
catch( IOException e)
{
e.printStackTrace();
}
}
}
executed it with ( java -jar example.jar)
I had the same problem at first. I think the main issue is that you forgot about the waitFor().
Also, it's really helpfull to extract your errorMessage and deal with it (e.g. log it or checking it while debuging ) within your java code. To allow this, you should create a streamReader thread as follows:
InputStreamReaderRunnable errorStreamReaderRunnable = new InputStreamReaderRunnable(spark.getErrorStream(), "error");
Thread errorThread = new Thread(errorStreamReaderRunnable, "LogStreamReader error");
errorThread.start();
int result= spark.waitFor();
if(result!=0) {
String errorMessage = extractExceptionMessage(errorStreamReaderRunnable.getMessage());
LOGGER.error(errorMessage);
}
This should be after your launch() command and inside your try block. Hope it helps
So my problem here is that I'm not too sure how to print a set of commands to cmd. I have a batch file that runs a Minecraft server, and I need to be able to run commands through the command prompt that shows up when I run the batch file, which will in turn perform commands to the server.
Here is my code so far:
package com.Kaelinator;
import java.io.IOException;
public class ServerManager {
public static void main(String[] args){
try {
System.out.println("Opening");
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("cmd /C start /min " + "C:/Users/Owner/Desktop/rekt/Run.bat");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//System.out.println("Closing");
//process.destroy();
} catch (IOException e){
e.printStackTrace();
}
}
}
Yes, I understand that all this does so far is open the batch file. :P I am expecting something like this that I need to add to my code:
process.InputStream(command1);
But I am certain that there is more to it, something along the lines of bufferedWriters or something like that...
Whenever I try to get answers from Google, the answers always have a whole load of extra code, or have something completely different about them.
Thanks!
I am writing an application that displays webcam connected to my computer.
I will just write code here since the code is very simple.
public static void main(String[] args) {
JFrameImageDisplayer _window = new JFrameImageDisplayer();
//webcamGrabber _wg = new webcamGrabber();
//commented out because I am having trouble with this class.
}
JFrameImageDisplayer opens a frame, pretty much that's all it does.
When I run this code, I open a simple application with a JLabel in the frame. If I close the application, then the whole process terminates( and the process at the Windows Task Manager Process tab processes as well).
However once I create _wg, the process at the Task Manager does not terminate even after I close the application ending up just burning processing power until I manually go to process bar to end it.
Below is the construction code for the webcamGrabber.
{
OpenCVFrameGrabber _grab = new OpenCVFrameGrabber(0);
try{
_grab.start();
} catch (Exception e){
e.printStackTrace();
}
}
Well I was not so sure what do. So I manually released the resources.
protected void processWindowEvent(WindowEvent e){
if(e.getID() == WindowEvent.WINDOW_CLOSING) {
try{_wg._grab.release();}
catch(Exception ee){}
}
super.processWindowEvent(e);
}
Not the prettiest way to do it, but it works.
I run JADE embedded in a Java program, i.e. not with java jade.Boot ....
Now I wanted to stop the JADE system, but I have found no nice way to do that.
I can exit the whole program using System.exit(), but that's not what I want to do.
I tried several different things, and I succeeded stopping my agent behaviours,
but a couple of Threads continue running: the AMS, the DF, a web server, the JADE Timer dispatcher, several Deliverer threads, etc.
This is how my current shutdown method looks like:
#Override
public void shutdown() {
// TODO This does not work yet..
try {
for (WeakReference<AgentController> acr : agents) {
AgentController ac = acr.get(); // jade.wrapper.AgentController
if ( ac != null ) ac.kill();
}
container.kill(); // jade.wrapper.AgentContainer
Runtime.instance().shutDown(); // jade.core.Runtime
} catch ( StaleProxyException e ) {
e.printStackTrace();
}
}
The reason I want to do that is that I have some JUnit tests for my
agent system.
Any ideas how to accomplish that?
You can request AMS to stop the platform in such way:
Codec codec = new SLCodec();
Ontology jmo = JADEManagementOntology.getInstance();
getContentManager().registerLanguage(codec);
getContentManager().registerOntology(jmo);
ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
msg.addReceiver(getAMS());
msg.setLanguage(codec.getName());
msg.setOntology(jmo.getName());
try {
getContentManager().fillContent(msg, new Action(getAID(), new ShutdownPlatform()));
send(msg);
}
catch (Exception e) {}
You can shutdown the whole JADE platform with:
try {
this.getContainerController().getPlatformController().kill();
}
catch (final ControllerException e) {
System.out.println("Failed to end simulation.");
}
"this" refers to an Agent class object.