I created a console application using Java, then exported it as runnable JAR file. but when I run the JAR file the automation is finished but the "Java (TM) Platform SE binary" is still on background, I tried to put System.exit(0) and still not able to terminate the process.
I'm also trying to run this automatically in Task Scheduler in indefinitely repetition every 15 minutes, the problem is it will not run again after 15 minutes since the "Java (TM) Platform SE binary" is still in process and identified its status as running.
I'm pretty sure that all my automation task is all finished without error and not creating another threads.
Here is my code below:
public static void main(String[] args) {
String jarName = new File(Selenium.class.getProtectionDomain().getCodeSource().getLocation().getPath())
.getName();
System.out.println("Running " + jarName + " Automation");
if (args.length >= 1 && args[0].toLowerCase().equals("-run")) {
for (int i = 1; i < args.length; i++) {
String pram = args[i].replace(jarName + "_", "");
if (pram.toLowerCase().equals("all")) {
GFC.execute("Login");
GFC.execute("SwitchIntegration");
GFC.execute("BODActivate");
GFC.execute("Users");
GFC.execute("Settings");
GFC.execute("AccountingEntityRegistration");
GFC.execute("CustomizedData");
GFC.execute("BOD");
GFC.execute("BODAttributesMDM");
GFC.execute("BODAttributesTransactional");
GFC.execute("CMD");
GFC.execute("CMDAttributes");
GFC.execute("CMDDataEntry");
GFC.execute("CMDActivate");
GFC.execute("AccountingEntity");
GFC.execute("AccountingEntityMapping");
GFC.execute("JETemplates");
GFC.execute("Scenarios");
GFC.execute("Rules");
GFC.execute("RulesScript").quit();
} else {
if (!pram.equals("Login")) {
GFC.execute("Login");
}
GFC.execute(pram).quit();
}
}
if (Boolean.parseBoolean(infor.automation.utils.Properties.get("gfc.enableemailer"))) {
sendEmail();
}
}
}
Update: 3/14/2018
Worrying might my automation is creating another threads, so I decide
to create a new project and just a main class and export it as a
runnable Jar file, and it's still the same.
My JDK version is 1.8
I make a workaround or maybe a solution. I found out that the System.exit(0) on main will only close the console application, but the "Java (TM) Platform SE binary" will remain. To terminate this I extended to JFrame class to be able to override the ExitApp(). Inside the ExitApp() I add window listener and in windowClosing() I called the disposed() and System.exit(0) once more. I don't have any idea how this even works. If someone know how this works feel free to update this answer.
public class TestClass extends JFrame {
public void ExitApp() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// Dispose Java (TM) Platform SE binary.
dispose();
// Close the Java.exe I'm not sure.
System.exit(0);
}
});
}
public static void main(String[] args) {
// Close Your Application Trigger ExitApp();
System.exit(0);
}
}
Related
I want to profile my test application started by IntelliJ. For profiling I useVisualVm.
I started the java tool with the parameter -J-Dorg.netbeans.profiler.separateConsole=true.
I started the application with the VM parameter -Xverify:none, otherwise VisualVM throws an error if I start profiling (Redefinition failed with error 62)
I want to profile my application before any important code has beed executed, so I tried to set a break point and start profiling in VisualVM. The problem is that VisualVm doesn't respond to any interaction while I'm waiting at my break point. Do I miss something?
In normal execution (without debugging) my program waits for input, so I can profile it without debugging. But what if a program doesn't has such "waiting points"?
My test application looks like that:
package my.visualvm.example;
import java.util.Scanner;
public class MainClass {
public static void main(String[] args) {
System.out.println("Starting Application: " + MainClass.class.getSimpleName());
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
double value = scanner.nextDouble();
if (value == 0d) {
break;
}
System.out.println(Powa.powaPowa(value));
}
System.out.println("Stopping Application: " + MainClass.class.getSimpleName());
}
}
Other class:
package my.visualvm.example;
final class Powa {
private Powa() {
}
static double powaPowa(double powa) {
return Math.pow(powa, 2);
}
}
Set the breakpoint to suspend the current thread only.
I need to make a program, which can be executed in single instance. I tried to create a temporary file and delete it before exit program.
public static boolean isLocked() {
File f = new File("lock.txt");
return f.exists();
}
public static void lock() {
String fname = "lock.txt";
File f = new File(fname);
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void unlock() {
File f = new File("lock.txt");
f.delete();
}
In frame
private void initialize() {
lock();
}
private void setFrameHandler() {
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
unlock();
}
});
}
Problem occurs if program is finished with emergency (e.g. electricity cuts). File does not remove, and running a new instance is impossible.
How to make a reliable single-instance verification?
You could check for another instance of the program at startup using the GetProcesses method as described here
But that only works depending on the scenario you have (might not see all processes of other users)
Another thing you could do is simply checking, if a specific file is locked via File.Open
File.Open ("path.lock", FileMode.OpenOrCreate, FileAccess.ReadWrite);
As long as you keep the resulting FileStream open in your program no other program can open the file in that mode either. This is basically how Unix lock files work too. Of course you have to catch an IOException (hinting you to a locked file).
Disclaimer: I did not try that code out so please check if I gave you the right parameters.
Edit: You could also check out this Code-Project article on how to do it with the win32 API
Another attempt using windows messaging has been done here
A simple approach to this on a single machine is to write a 'PID file', which is literally a file containing the operating system's ID of the process currently running. You create this when you start your "critical" work, and remove it on successful completion.
Since it is unlikely that the process would be started again with the same PID, you can simply check to see if the PID file already exists, and if so, if that process is still running.
This question already has answers here:
How can I restart a Java application?
(13 answers)
Closed 9 years ago.
In many software, after we make any changes, the software has to be restarted for the changes to take effect, and sometimes, there is an option to restart the software automatically. How can I implement this in Java?
This is what I have tried:
int o = JOptionPane.showConfirmDialog(
frame,
"<html>The previously selected preferences have been changed.<br>Watch must restart for the changes to take effect.<br> Restart now?</html>",
"Restart now?", JOptionPane.YES_NO_OPTION);
if(o == JOptionPane.YES_OPTION) {
try {
Process p = new ProcessBuilder("java", "Watch").start();
} catch(IOException e) {
e.printStackTrace();
}
frame.dispose();
However, this doesn't seem to work. The application just terminates. What am I missing here? Thanks in advance!
This looks interesting: Make your application restart on its own
Basically, you create a script to run your app. In your app, if the user choses to restart, a restart file is created, then the app exits. Upon exiting, the startup script checks for the existence of a restart file. If exists, call the app again.
I think this is hard using just the facilities of the JVM alone.
I've never done this, but if you really want to terminate the whole JVM in which your current application is running and start a completely new instance of it, I would probably try something along these lines:
From your main application thread, start a shell script / batch file (e.g. using Runtime.getRuntime().exec("...")` that does the following steps:
Forks or uses some other system facility of starting the next step(s) in the background.
Maybe wait some time so you can be sure the old instance is dead. Or wait until some kind of PID file or similar thing is removed telling you that the old instance is gone.
Start a new JVM with your applications main class, probably giving it some command line argument or setting some system property to notify this new instance that it is in fact, an automatically restarted instance (so it can react to this e.g. by continuing where your originally left off).
In parallel to step 1 in your first main app instance, maybe wait a small amount of time (to make sure the background stuff is actually executed) and call System.exit(0); or some other method of shutting down.
Maybe there is a simpler way, it's just the first way that I could think of.
What about the next:
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
buildAndShowGui(args);
}
});
}
public static void buildAndShowGui(final String[] args) {
final JFrame frame = new JFrame("Window");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setSize(100, 400);
frame.setLayout(new FlowLayout());
JButton button = new JButton("Click!");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int option = JOptionPane.showConfirmDialog(frame, "Restart?");
if (option == JOptionPane.YES_OPTION) {
frame.dispose();
restart(args);
}
}
});
frame.add(button);
frame.setVisible(true);
frame.toFront();
}
public static void restart(String[] args) {
main(args);
}
I have a question.
Is it possible to use the hotswap without using breakpoints ?
When notch made prelude of chambered (http://www.youtube.com/user/Nizzotch?feature=playlist-comment#p/u) he used the hotswap without having to :
- add breakpoints
- save
- remove breakpoint
- resume
In this video it's too fast to see that, but i can't find old ones.
Do you have an idea ? eclipse-options, macro, plugins ... ?
Thank you
Depends on your JVM, but hotswap in Eclipse worked for me with no tricks on the Sun's HotSpot JVM back in the times of Java 1.5. Here's a related Sun's bug. Which JVM are you using?
public class Test {
private static int ctr = 0;
public static void main(String[] args) {
while (true) {
method();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
System.err.println("Interrupted");
}
}
}
private static void method() {
System.out.println(ctr);
}
}
I changed System.out.println(ctr); to System.out.println(ctr++);, and my output altered to an increasing sequence.
My Goal
I am attempting to make a Java program in which a user can select any .class or .jar file from their computer. My program will then pop up a JInternalFrame with a JEditorPane in it as the console, capturing any console output from the user's program. When the user's program closes (calls System.exit(int status);), my program must not close along with it. My program might also have such features as a button to immediately stop the user's program and others an IDE would. My program need not compile Java code, only run .class and .jar files.
My Experience
I have made a small test version of this program wherein I got two specific files from a package and had the user click one of two buttons, each representing one of the two programs. A press of a button calls the following method:
private void run(Class runnable)
{
java.lang.reflect.Method[] m = runnable.getMethods();
boolean hasMain = false;
for (int i = 0; i < m.length; i++)
{
if (m[i].getName().equals("main") && m[i].getParameterTypes()[0].isArray() && m[i].getParameterTypes()[0].getName().contains("java.lang.String"))
try
{
Object invoke = m[i].invoke(null, (Object)globalArgs);
hasMain = true;
hub.setExtendedState(Hub.ICONIFIED);
numPrograms++;
}
catch (Throwable t)
{
java.util.logging.Logger.getLogger(Hub.class.getName()).log(java.util.logging.Level.SEVERE, null, t);
javax.swing.JOptionPane.showMessageDialog(null, "Could not run " + runnable.getName(), "Error in invocation", javax.swing.JOptionPane.ERROR_MESSAGE);
}
finally
{
break;
}
}
if (!hasMain)
javax.swing.JOptionPane.showMessageDialog(null, runnable.getName()
+ " does not have a public static main method that\nreturns void and takes in an array of Strings",
"No main method", javax.swing.JOptionPane.ERROR_MESSAGE);
}
This method successfully calls either program's main method and runs a copy of said program. However, when any of the programs this hub has started calls the System.exit(int status) command, the hub closes, too. Also, I haven't the slightest clue as to how to capture console output.
My Questions
Does anyone have any experience or advice they would be willing to share to help me make a fully-functional program that can...
Open and run a compiled Java file (remember that .jar files may have more than one class with main(String[] args) method)
Catch System.exit(int status); so that the hub program handles the internal program's exiting
Catch new java.io.PrintStream().println(Object o) and similar calls and place their output in a JEditorPane
Make a button that, when pressed, stops the internal program from running
Possibly make all JFrames the internal program uses into JInternalFrames and place them in a JDesktopPane
If you don't want the other program (which you call through it's main method) to be able to shut down the JVM you're running in, you have, as I see it, three options:
1. Using a SecurityManager
Set up the SecurityManager so that it prevents the System.exit call:
public class Test {
public static void main(String args[]) {
SecurityManager sm = System.getSecurityManager();
System.setSecurityManager(new SecurityManager() {
#Override
public void checkExit(int status) {
throw new SecurityException("Client program exited.");
}
});
try {
System.out.println("hello");
System.exit(0);
System.out.println("world");
} catch (SecurityException se) {
System.out.println(se.getMessage());
}
}
}
Prints:
hello
Client program exited.
This is probably the nicest solution. This is the way application servers prevent an arbitrary servlet from terminating the entire server.
2. Separate JVM
Run the other program in a separate JVM, using for instance ProcessBuilder
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException {
ProcessBuilder pb = new ProcessBuilder("java", "other.Program");
pb.redirectErrorStream();
Process p = pb.start();
InputStream is = p.getInputStream();
int ch;
while ((ch = is.read()) != -1)
System.out.print((char) ch);
is.close();
System.out.println("Client program done.");
}
}
3. Use shutdown hooks instead
Don't disallow the termination of the JVM, but instead add shutdown-hooks that cleans up the "hub" and exits gracefully. (This option probably only makes sense if your running one "external" program at a time.)
import java.io.*;
public class Test {
public static void main(String args[]) throws IOException {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
System.out.println("Uninitializing hub...");
System.out.println("Exiting gracefully.");
}
});
// Run client program
System.out.println("Running... running... running...");
System.exit(0);
}
}
Prints:
Running... running... running...
Uninitializing hub...
Exiting gracefully.