I have the following restart method, which is working:
public static void restart(String[] args) {
ArrayList<String> commands = new ArrayList<String>();
List<String> jvmArgs = ManagementFactory.getRuntimeMXBean().getInputArguments();
// Java
commands.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
// Jvm arguments
for (String jvmArg : jvmArgs) {
commands.add(jvmArg);
}
// Classpath
commands.add("-cp");
commands.add(ManagementFactory.getRuntimeMXBean().getClassPath());
// Class to be executed
commands.add(BaseUI.class.getName());
// Command line arguments
File workingDir = null; // Null working dir means that the child uses the same working directory
String[] env = null; // Null env means that the child uses the same environment
String[] commandArray = new String[commands.size()];
commandArray = commands.toArray(commandArray);
try {
Runtime.getRuntime().exec(commandArray, env, workingDir);
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}
}
I want to put the Look And Feel configuration on the main method of my main application but, while restarting, the execution does not enter in that part of the code. So, obviously, the Look and Feel is not changed at all.
Is there any workaround to solve this?
Related
I'm trying to make a function that reboot the javafx application, On windows 10 works perfectly but on Windows 7 it doesn't, I search for this solution and it was perfect, then I test it on Windows 10 and nothing, the app just turn off. Also I test it watching for an exception inside the log file and it doesn't throw any Exception.
Something specific must be made in order to work also on windows 7? maybe a different approach? Thanks.
this is the code:
//Restart app the current Java application, with parameter you can pass a Runnable to do before restart app, null if not
public static void restartApplication(Runnable runBeforeRestart) throws IOException {
try {
/**
* Sun property pointing the main class and its arguments.
* Might not be defined on non Hotspot VM implementations.
*/
final String SUN_JAVA_COMMAND = "sun.java.command";
// java binary
String java = System.getProperty("java.home") + "/bin/java";
// vm arguments
List<String> vmArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
StringBuffer vmArgsOneLine = new StringBuffer();
for (String arg : vmArguments) {
// if it's the agent argument : we ignore it otherwise the
// address of the old application and the new one will be in conflict
if (!arg.contains("-agentlib")) {
vmArgsOneLine.append(arg);
vmArgsOneLine.append(" ");
}
}
// init the command to execute, add the vm args
final StringBuffer cmd = new StringBuffer("\"" + java + "\" " + vmArgsOneLine);
// program main and program arguments
String[] mainCommand = System.getProperty(SUN_JAVA_COMMAND).split(" ");
// program main is a jar
if (mainCommand[0].endsWith(".jar")) {
// if it's a jar, add -jar mainJar
cmd.append("-jar " + new File(mainCommand[0]).getPath());
} else {
// else it's a .class, add the classpath and mainClass
cmd.append("-cp \"" + System.getProperty("java.class.path") + "\" " + mainCommand[0]);
}
// finally add program arguments
for (int i = 1; i < mainCommand.length; i++) {
cmd.append(" ");
cmd.append(mainCommand[i]);
}
// execute the command in a shutdown hook, to be sure that all the
// resources have been disposed before restarting the application
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
Runtime.getRuntime().exec(cmd.toString());
} catch (IOException e) {
logToFile.log(e, "info", "The application fail to restart, applying the command");
}
}
});
// execute some custom code before restarting
if (runBeforeRestart!= null) {
runBeforeRestart.run();
}
// Wait for 2 seconds before restart
//TimeUnit.SECONDS.sleep(2);
// exit
System.exit(0);
} catch (Exception e) {
// something went wrong
logToFile.log(e, "info", "The application fail to restart generally");
}
}
Update: Searching for other approach I found out a solution, It's test it on both Windows OS and works
here it's the code:
//Restart app the current Java application, with parameter you can pass a Runnable to do before restart app, null if not
public static void restartApplication(Runnable runBeforeRestart, Integer TimeToWaitToExecuteTask) throws IOException {
try {
// execute some custom code before restarting
if (runBeforeRestart != null) {
// Wait for 2 seconds before restart if null
if (TimeToWaitToExecuteTask != null) {
TimeUnit.SECONDS.sleep(TimeToWaitToExecuteTask);
} else {
TimeUnit.SECONDS.sleep(2);
}
runBeforeRestart.run();
}
final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
final File currentJar = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().toURI());
/* is it a jar file? */
if (!currentJar.getName().endsWith(".jar"))
return;
/* Build command: java -jar application.jar */
final ArrayList<String> command = new ArrayList<String>();
command.add(javaBin);
command.add("-jar");
command.add(currentJar.getPath());
final ProcessBuilder builder = new ProcessBuilder(command);
builder.start();
System.exit(0);
} catch (Exception e) {
// something went wrong
logToFile.log(e, "info", "The application fail to restart generally");
}
}
I'm looking for a way to run adb commands directly from a java application. While search on Stack Overflow I found the following solution for running shell commands,
public class Utils {
private static final String[] WIN_RUNTIME = {"cmd.exe", "/C"};
private static final String[] OS_LINUX_RUNTIME = {"/bin/bash", "-l", "-c"};
private Utils() {
}
private static <T> T[] concat(T[] first, T[] second) {
T[] result = Arrays.copyOf(first, first.length + second.length);
System.arraycopy(second, 0, result, first.length, second.length);
return result;
}
public static List<String> runProcess(boolean isWin, String... command) {
System.out.print("command to run: ");
for (String s : command) {
System.out.print(s);
}
System.out.print("\n");
String[] allCommand = null;
try {
if (isWin) {
allCommand = concat(WIN_RUNTIME, command);
} else {
allCommand = concat(OS_LINUX_RUNTIME, command);
}
ProcessBuilder pb = new ProcessBuilder(allCommand);
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String _temp = null;
List<String> line = new ArrayList<String>();
while ((_temp = in.readLine()) != null) {
//System.out.println("temp line: " + _temp);
line.add(_temp);
}
System.out.println("result after command: " + line);
return line;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
This works perfectly, however I couldn't find a solution to add the adb.exe path into the shell commands so that I can execute adb commands.
My project structure is given below,
I'm trying to append the adb path along with the system default shell path using the following way,
Utils.runProcess(true, "/resources/adb.exe devices");
Is there any way to append the adb.exe path from resources into the shell command?
Use the full path to adb.exe that way you don't need to add it to %PATH%.
eg. If you open cmd and run C:\...\adb.exe devices it will work
Alternatively execute this command in the shell to set your path,
setx path "%path%;C:\..."
Edit: Add the adb.exe in your resources folder in the same package as your calling class. Then load it and write it to another location that you happen to know (or generate a path relative to where your jar is located eg.System.getProperty("user.dir");
)
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("adb.exe").getFile());
// now copy this file to a location you already know eg. C:\...\temp\adb.exe
And then invoke adb.exe with the path that you have
I'm trying to create a program that creates a copy of itself and deletes the original project folder.
(FYI: Project has its own JRE inside it)
(FYI: This program runs on Windows)
So:
To be able to do that, other than my primary main method, there is a second main method in the class called SelfUpdater.
Inside my main thread I copy the project to a second folder.
And then run the SelfUpdater's main method inside this second project folder:
This should mean that I'm running a whole new instance, totally unrelated to the first java.exe (which already gets closed with system.exit(0) as soon as new instance starts).
But when I try to delete the first folder, I get the error "Error deleting old client.java.io.IOException: Unable to delete file". Actually It deletes some of the files, but I can't delete Application.exe and its lib folder.
Its folder is not open in windows. It is not being used by anything else. I can't delete the file manually either (Windows says it is in use). And as soon as the second java.exe is terminated, I can delete it.
I can't give a total working example, But my in my main thread I call this following method:
public static void selfUpdate() {
try {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String rootPath = System.getProperty("user.dir");
String path = null;
File parentFolder = null;
File originalClientFolder = new File(rootPath);
parentFolder = originalClientFolder.getParentFile();
File secondClientFolder = new File(parentFolder.getAbsolutePath() + separator + "runLAST");
FileUtils.copyDirectory(originalClientFolder, secondClientFolder);
path = secondClientFolder.getAbsolutePath() + separator + "jre8" + separator + "bin" + separator + "java";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, SelfUpdater.class.getName(), downloadURL, rootPath);
processBuilder.directory(secondClientFolder);
processBuilder.start();
System.exit(0);
} catch (Exception ex) {
}
}
And my SelfUpdater class' main is:
public static void main(String[] args) {
try {
String originalClientFolderPath = args[1];
//
File oldClientFolder = new File(originalClientFolderPath);
System.out.println("Deleting old client recursively. Folder: " + oldClientFolder.getAbsolutePath());
try {
FileUtils.deleteDirectory(oldClientFolder);
} catch (Exception ex) {
}
}
}
Appearently, I forgot to change the classpath.
I'm thinking about leaving the question, since people may need such code part.
But at the end, method that's being called is changed to this:
public static void selfUpdate() {
try {
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String rootPath = System.getProperty("user.dir");
String path = null;
File parentFolder = null;
File originalClientFolder = new File(rootPath);
parentFolder = originalClientFolder.getParentFile();
File secondClientFolder = new File(parentFolder.getAbsolutePath() + separator + "runLAST");
FileUtils.copyDirectory(originalClientFolder, secondClientFolder);
// ADDED: --------------------------------------------------------
String origialClientFolderName = originalClientFolder.getName();
classpath = classpath.replace(origialClientFolderName, "runLAST");
// ---------------------------------------------------------------
path = secondClientFolder.getAbsolutePath() + separator + "jre8" + separator + "bin" + separator + "java";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, SelfUpdater.class.getName(), downloadURL, rootPath);
processBuilder.directory(secondClientFolder);
processBuilder.start();
System.exit(0);
} catch (Exception ex) {
}
}
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java code to execute a .sh file
I write the code in a .sh file with one parameter in /root/new_scripts/setpermission.sh and run it: setpermission.sh contains:
chmod 777 $1
It executed successfully from linux console by typing /root/new_scripts/setpermission.sh location . But when i tried to run it using java code using:
Java full code:
String fileLocation = BASE_DIR + domain + SUB_DIR_CAKE + fileName;
File newFile = new File(fileLocation);
System.out.println("Permission file location: " + fileLocation);
if(newFile.exists()) {
String command;
String[] commandArray;
command = "/root/new_scripts/setpermission.sh";
File commandFile = new File(command);
if(commandFile.exists()) {
System.out.println("\n\n\n\n\nFILE EXISTS");
} else {
System.out.println("\n\n\n\n\nFILE NOT EXISTS");
}
commandArray = new String[]{"/bin/sh", command, newFile.toString()};
try {
Process p = Runtime.getRuntime().exec(commandArray);
return "HERE OK";
} catch (Exception e) {
e.printStackTrace();
return e.getMessage();
}
} else {
return "file not exists";
}
and it returns HERE OK
Please post the Java code that you're using to attempt this. However, by making a few assumptions, you probably need to find and use the fully-qualified path to "sh", as the Java ProcessBuilder won't make use of a set "PATH" environment variable.
try this:
String command;
String[] commandArray;
command = "./new_scripts/setpermission.sh";
commandArray = new String[]{"/bin/sh", command, fileLocation, permission};
try {
Process p = Runtime.getRuntime().exec(commandArray);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I've been using the following code to open Office Documents, PDF, etc. on my windows machines using Java and it's working fine, except for some reason when a filename has embedded it within it multiple contiguous spaces like "File[SPACE][SPACE]Test.doc".
How can I make this work? I'm not averse to canning the whole piece of code... but I'd rather not replace it with a third party library that calls JNI.
public static void openDocument(String path) throws IOException {
// Make forward slashes backslashes (for windows)
// Double quote any path segments with spaces in them
path = path.replace("/", "\\").replaceAll(
"\\\\([^\\\\\\\\\"]* [^\\\\\\\\\"]*)", "\\\\\\\"$1\"");
String command = "C:\\Windows\\System32\\cmd.exe /c start " + path + "";
Runtime.getRuntime().exec(command);
}
EDIT: When I run it with the errant file windows complains about finding the file. But... when I run the command line directly from the command line it runs just fine.
If you are using Java 6 you can just use the open method of java.awt.Desktop to launch the file using the default application for the current platform.
Not sure if this will help you much... I use java 1.5+'s ProcessBuilder to launch external shell scripts in a java program. Basically I do the following: ( although this may not apply because you don't want to capture the commands output; you actually wanna fire up the document - but, maybe this will spark something that you can use )
List<String> command = new ArrayList<String>();
command.add(someExecutable);
command.add(someArguemnt0);
command.add(someArgument1);
command.add(someArgument2);
ProcessBuilder builder = new ProcessBuilder(command);
try {
final Process process = builder.start();
...
} catch (IOException ioe) {}
The issue may be the "start" command you are using, rather than your file name parsing. For example, this seems to work well on my WinXP machine (using JDK 1.5)
import java.io.IOException;
import java.io.File;
public class test {
public static void openDocument(String path) throws IOException {
path = "\"" + path + "\"";
File f = new File( path );
String command = "C:\\Windows\\System32\\cmd.exe /c " + f.getPath() + "";
Runtime.getRuntime().exec(command);
}
public static void main( String[] argv ) {
test thisApp = new test();
try {
thisApp.openDocument( "c:\\so\\My Doc.doc");
}
catch( IOException e ) {
e.printStackTrace();
}
}
}