views:

103

answers:

4

I am trying to integrate a non-Java executable into a Java webapp on the server-side (Linux).

Some details about the executable:
Written in C++. The executable takes some input either from stdin or file and generates an output file. The executable is not designed to be a long running process i.e it generates an output and then dies out.

While starting an individual process for the executable is fairly inexpensive, the number of calls made to it can be high. This can result in spawning too many processes which could degrade server performance.

How can I write some wrapper or utility (in Java) around this exe, that I can run efficiently as either

  1. a thread from within my Java app
  2. a long-running external process

PS: I know that I can start an external process using Runtime or ProcessBuilder in Java and could probably make it multi-threaded and use some queueing too, but that does not solve the issue of starting the process over and over again.

+1  A: 

if you:

a) Can modify the source code.

I would recommend you yo create a long running process and expose it as a webservice. This way the process will only be sitting there waiting to be invoked.

b) Have the source code/headers but you can't modify it.

Probably a good idea would be to integrate it as library and invoke it from java, either with JNI or JNA, although this may be painfully hard.

C) Don't have the source code or can't modify it.

Then there are not much options, you have to create a thread queue and from there throttle the process creation.

OscarRyz
Thanks Oscar. I was thinking along the same lines. We have access to to the source code, but no one with time/expertise to play with C++. I also looked at JNI and will probably explore this a bit before committing to option C. I am inclined to accept your answer, but would like to leave the question open for discussion for a couple of days.
Thimmayya
That's ok. What I would do ( not having a lot of C++ experience my self ) is going for option C, throttle directly from Java. At least you can control how many process you machine can run, and restrict it. You may also add a properties file somewhere so yo can increase/decrease that value when needed.
OscarRyz
@Thimmayya. You can always, just "upvote" the answer while we wait :)
OscarRyz
A: 

How many processes is "too many"? I suggest measuring the performance before going further. It may be the case that you can start and run many more processes without problem than you expect, especially since the code of the program will be shared in memory across all instances.

Adam Goode
50 is probably too many, but I need to get a better answer from IT. Will update.
Thimmayya
+1  A: 

If starting up the C++ application takes too long, it is almost a certainty that you are going to have to write some C++ code to avoid this.

One alternative is to refactor the C++ into a library with a suitable API, and use JNI or JNA to call the API from Java. However, JNI / JNA are difficult to use and have the tendency to destabilize the JVM. When something goes wrong (e.g. your JVM crashes), debugging is difficult.

A better alternative is to refactor the C++ application to run as a daemon process. Replace the 'main' entry point with code that sits in a loop doing the following:

while (true) {
    read request from a socket / pipe
    process request
    write answer to socket / pipe
}

If you use a pipe, you can have your Java webapp launch the C++ application using Runtime.exec(...) and then read and write messages via the pipe streams. If you use an (IPC or network) socket, you could do the same or make the C++ application multi-threaded so that it can handle more than one request at a time.

One issue that you will need to consider is multi-threading. You web container (the thing that runs your webapp) is likely to be multi-threaded by default, so you will need to implement the Java side to cope with the multi- or single-threaded nature of the C++ side. This might be as simple as making the Java-side object that is used to make requests a singleton with synchronized methods. However, that could be a performance bottleneck.

Stephen C
+1  A: 

Throtteling in Java can be done using a suitable Executor. There are plenty easily available in Executors - I think the fixed size thread pool is exactly what you need.

http://java.sun.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29

Thorbjørn Ravn Andersen