I am a fresher and I have created a java swing application, which is running perfectly.
I want to add a functionality in this application that when user exit or close this application from anywhere like close from task manager, or force stop or by some other methods. Application will restart automatically after some time.
Is it possible to do so?
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
final File currentJar = new File(MyClassInTheJar.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);
}
},
5000);
read https://docs.oracle.com/javase/6/docs/api/java/util/Timer.html
Related
Using java.lang.ProcessBuilder on a Java application running on a Linux machine (Ubuntu 18.04 specifically), what can be done such that the command executed would be able to run and not throw Permission Denied.
Here's the code:
boolean isWindows = System.getProperty("os.name")
.toLowerCase().startsWith("windows");
ProcessBuilder builder = new ProcessBuilder();
if (isWindows) {
builder.directory(new File(System.getProperty("user.home")));
builder.command("cmd.exe", "/c", command);
} else {
builder.directory(new File(System.getenv("HOME")));
builder.command("sh", "-c", command);
}
Process process = builder.start();
Tested on Ubuntu 18.04:
import java.io.File;
public class Application {
public static void main(String[] args) throws Exception{
boolean isWindows = System.getProperty("os.name")
.toLowerCase().startsWith("windows");
ProcessBuilder builder = new ProcessBuilder();
if (isWindows) {
builder.directory(new File(System.getProperty("user.home")));
builder.command("cmd.exe", "/c", "");
} else {
builder.directory(new File(System.getenv("HOME")));
// i used the docker command as an example, because it needs a root access (default configuration of Docker)
builder.command("/bin/bash", "-c", "sudo docker image ls > result.txt 2> errors.txt");
}
Process process = builder.start();
// When running the command java Application in terminal, i noticed that when prompted to type the root password
// the program exits so i decided to make the current thread sleep for 5 seconds, to give me time to type the password
Thread.sleep(5000);
}
}
Hope that will be helpful :)
I'm writing a program that includes a feature where the user can type in Java code into a text box and be able to compile and run it. The error I get is:
The two directories shown at the top are correct, and the command works when I do it manually through command prompt from the same working directory. I'm using Windows 10, and also here's the code:
public Process compile() throws IOException {
save(); //saves changes to source file
System.out.println(file.getCanonicalPath());
ProcessBuilder processBuilder = new ProcessBuilder("javac", file.getCanonicalPath());
processBuilder.directory(new File(settingsFile.getJdkPath()));
System.out.println(processBuilder.directory());
Process process = processBuilder.start(); //Throws exception
this.compiledFile = new File(file.getParentFile(), file.getName().replace(".java", ".class"));
return process;
}
File to compile:
Working directory:
Using this code, I was able to compile a Test.java file into a Test.class file on my Desktop.
import java.io.IOException;
public class App {
public static Process compile() throws IOException {
String myFilePath = "C:\\Users\\redacted\\Desktop\\Test.java";
String javacPath = "C:\\Program Files\\Java\\jdk1.8.0_171\\bin\\javac.exe";
ProcessBuilder processBuilder = new ProcessBuilder(javacPath, myFilePath);
return processBuilder.start();
}
public static void main(String[] args) throws IOException {
Process process = compile();
}
}
Using String javacPath = "javac.exe"; also worked, but that could be because my JDK bin is on my PATH variable.
There is something wrong with your paths or permissions in the ProcessBuilder constructor call.
I'd like to start a JavaFX application, if it isn't already running.
The JavaFX application is packaged in a JAR container, which is in the classpath of the calling application. The calling application should execute the JavaFX app.
The JavaFX application should not terminate if the calling application gets terminated. (therefore it needs to be in a separate process)
I tried the following approach, but even though uiProcess.isAlive() returns true, the JavaFX application is never visible.
// caller main thread
String[] startOptions = new String[]{"java", "-jar", "javafx-ui.jar"};
Process uiProcess = new ProcessBuilder(startOptions).start();
+++++++++++++++++++++++++++++++++++++++
UPDATE:
I created a helper class which takes the JAR name and tries to execute it. Unfortunately this doesn't work. But if I copy the the logged CLI command and execute the command in a terminal, the app is started as expected. If I print System.getProperty("java.class.path") property, I see that my javafx-ui.jar is on the classpath.
Usage:
ProcessExecutor processExecutor = new ProcessExecutor();
processExecutor.executeJarByName("javafx-ui.jar");
Executor:
public class ProcessExecutor {
private List<Process> processes;
private static Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);
/**
* Default constructor
*/
public ProcessExecutor() {
processes = new ArrayList<>();
}
/**
* Executes jar in a standalone process
*
* #param jarName
*/
public Process executeJarByName(String jarName) throws IOException {
String[] command = new String[]{"java", "-jar", jarName};
ProcessBuilder builder = createProcessBuilder(command);
Process process = builder.start();
processes.add(process);
if (process.isAlive()) {
Optional<ProcessHandle> processHandle = ProcessHandle.of(process.pid());
if (processHandle.isPresent()) {
ProcessHandle.Info processInfo = processHandle.get().info();
logger.info("COMMAND: {}", processInfo.command().orElse(""));
logger.info("CLI: {}", processInfo.commandLine().orElse(""));
logger.info("USER: {}", processInfo.user().orElse(""));
logger.info("START TIME: {}", processInfo.startInstant().orElse(null));
logger.info("TOTAL CPU: {}", processInfo.totalCpuDuration().orElse(null));
}
}
return process;
}
private ProcessBuilder createProcessBuilder(String[] command) {
return new ProcessBuilder(command);
}
/**
* Kills all executed processes
*/
public void killAll() {
processes.forEach(p -> p.destroy());
}
}
I got it working, if I execute the following command, using the Java ProcessBuilder. The mainClassName needs to be the fully qualified class name of the class, containing the main() method. (including the package name)
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String javaHome = System.getProperty("java.home");
String java = javaHome + separator + "bin" + separator + "java";
String[] command = {java, "-cp", classpath, mainClassName};
ProcessBuilder builder = createProcessBuilder(command);
I am working on developing a plugin for teamcity . The requirement is to run a jar file from the code which does some custom operation. I tried with the below code, but its not working for me.Any ideas on how to run the jar, links to documentation or sample code will help me a lot to progress further
public class CustomBuildProcess extends BuildProcessAdapter
{
private static final String jarDir = "\\plugins\\teamcity-custom-plugin-agent\\lib\\metrics-17.6.4.4.jar";
#Override
public void start()
{
buildStatus = startProcess();
}
private BuildFinishedStatus startProcess() throws IOException
{
final GeneralCommandLine cmd = new GeneralCommandLine();
cmd.setExePath("java -jar C:\\BuildAgent"+jarDir);
final ExecResult result = SimpleCommandLineProcessRunner.runCommand(cmd, new byte[0]);
}
The following code worked for me.
final Runtime rTime = Runtime.getRuntime();
final Process process = rTime.exec("java -jar
C:\\TeamCity\\BuildAgent\\plugins\\teamcity-cutom-plugin-agent\\lib\\metrics-17.6.4.4.jar");
logger.progressMessage(new String(IOUtils.toByteArray(process.getInputStream())));
PrintStream printStream = new PrintStream(process.getOutputStream());
logger.progressMessage(new String(IOUtils.toByteArray(process.getErrorStream())));
i'd like to run a command that executes a shell script with the java class "DefaultExecutor", but i get this error:
Cannot run program "get_encrypted_password.sh" (in directory "C:\Temp\scripts"): CreateProcess error=2 specified file not found".
the script works well with git bash.
can someone tell me where i'm doing wrong?
public Entity updateWithEncryptedPassword(Entity entity) throws IOException {
String password = entity.getPwd();
String security_key = "00000000000000000000000000000000";
String path = "C:/Temp/scripts";
CommandLine commandLine = CommandLine.parse("get_encrypted_password.sh");
commandLine.addArgument(password);
commandLine.addArgument(security_key);
String encrypted_password = Utils.runCommandAndGetOutput(commandLine, path);
entity.setNewPwd(encrypted_password);
return super.update(entity);
}
public static String runCommandAndGetOutput(CommandLine commandLine, String path) throws IOException {
DefaultExecutor defaultExecutor = new DefaultExecutor();
defaultExecutor.setExitValue(0);
defaultExecutor.setWorkingDirectory(new File(path));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
defaultExecutor.setStreamHandler(streamHandler);
defaultExecutor.execute(commandLine);
return outputStream.toString();
}
Instead of executing "get_encrypted_password.sh", which cannot be ran under Windows, execute "bash", (probably git bash,) and pass "get_encrypted_password.sh" as a parameter to it, so that bash will execute your script.