5

I'm trying to run ApacheDS instance from my java application.
I use such run() method of ScriptWrapper class to execute script that is shipped with ApacheDS to run it:

public class ScriptWrapper implements Serializable {
    private String scriptPath;

    protected Process run(List<String> params) throws IOException {
        LOGGER.debug("Executing script="+scriptPath);
        params.add(0, scriptPath);

        if(workDir != null) {
            return Runtime.getRuntime().exec(params.toArray(new String[params.size()]), envp.toArray(new String[envp.size()]), new File(workDir));
        } else {
            return Runtime.getRuntime().exec(params.toArray(new String[params.size()]));
        }
    }
}

But the problem is, that when tomcat on which this app runs, is terminated and/or ScriptWrapper is garbage collected, the instance of ApacheDS also terminates. How to keep it alive?

EDIT: Thank you for your answers. I've decided to address the problem in different way and daemonized the process with script comming with binary ApacheDS installation.

Michał Kowalczyk
  • 358
  • 1
  • 5
  • 21

4 Answers4

0

Your main process should wait for it's children before ending.

The object Process has a method waitFor(). You can create a new thread and then run and wait for any other process.

Pablo Lozano
  • 10,122
  • 2
  • 38
  • 59
0

Technically you can prevent your object from being garbage collected by holding reference of the ScriptWrapper.

You can use singleton to hold reference. As your object is referenced actively it won't be collected by GC.

public class ScriptWrapper {
  private static ScriptWrapper uniqueInstance;

  private ScriptWrapper () {
    }

  public static synchronized ScriptWrapper getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new ScriptWrapper ();
    }
    return uniqInstance;
  }

  protected Process run(List<String> params) throws IOException {
        LOGGER.debug("Executing script="+scriptPath);
        params.add(0, scriptPath);

      if(workDir != null) {
             return Runtime.getRuntime().exec(params.toArray(new String[params.size()]), envp.toArray(new String[envp.size()]), new File(workDir));
       } else {
         return Runtime.getRuntime().exec(params.toArray(new String[params.size()]));
      }
  }

}

Hope this could help you !.

Alpesh Gediya
  • 3,706
  • 1
  • 25
  • 38
  • Java API for Process says: The subprocess is not killed when there are no more references to the Process object, but rather the subprocess continues executing asynchronously – Pablo Lozano May 17 '13 at 11:56
0

I wonder by calling a shell or the command on windows to exec your command would that work?

Runtime.getRuntime().exec( "/bin/bash -c yourCommand yourOptions &" ).waitFor();

The Bash & (ampersand) is a builtin control operator used to fork processes. From the Bash man page, "If a command is terminated by the control operator &, the shell executes the command in the background in a subshell".

I am not sure how windows would work out try maybe

Runtime.getRuntime().exec( "command.exe yourCommand yourOptions" ).waitFor();
Paul Whelan
  • 16,574
  • 12
  • 50
  • 83
0

In windows it is like this

Process p = Runtime.getRuntime().exec( "cmd /c yourCommand yourOptions");

you need not put p.waitFor()..

K Adithyan
  • 386
  • 4
  • 12