Best method of triggering a shell script from Java

2019-04-16 00:09发布

I have a shell script which I'd like to trigger from a J2EE web app.

The script does lots of things - processing, FTPing, etc - it's a legacy thing.

It takes a long time to run.

I'm wondering what is the best approach to this. I want a user to be able to click on a link, trigger the script, and display a message to the user saying that the script has started. I'd like the HTTP request/response cycle to be instantaneous, irrespective of the fact that my script takes a long time to run.

I can think of three options:

  • Spawn a new thread during the processing of the user's click. However, I don't think this is compliant with the J2EE spec.
  • Send some output down the HTTP response stream and commit it before triggering the script. This gives the illusion that the HTTP request/response cycle has finished, but actually the thread processing the request is still sat there waiting for the shell script to finish. So I've basically hijacked the containers HTTP processing thread for my own purpose.
  • Create a wrapper script which starts my main script in the background. This would let the request/response cycle to finish normally in the container.

All the above would be using a servlet and Runtime.getRuntime().exec().

This is running on Solaris using Oracle's OC4J app server, on Java 1.4.2.

Please does anyone have any opinions on which is the least hacky solution and why?

Or does anyone have a better approach? We've got Quartz available, but we don't want to have to reimplement the shell script as a Java process.

Thanks.

8条回答
我欲成王,谁敢阻挡
2楼-- · 2019-04-16 00:42

Is it necessary for your application to evaluate output from the script you are starting, or is this a simple fire-and-forget job? If it's not required, you can 'abuse' the fact that Runtime.getRuntime().exec() will return immediately with the process continuing to run in the background. If you actually wanted to wait for the script/process to finish, you would have to invoke waitFor() on the Process object returned by exec().

If the process you are starting writes anything to stdout or stderr, be sure to redirect these to either log files or /dev/null, otherwise the process will block after a while, since stdout and stderr are available as InputStreams with limited buffering capabilites through the Process object.

查看更多
聊天终结者
3楼-- · 2019-04-16 00:43

You mentioned Quartz so let's go for an option #4 (which is IMO the best of course):

PS: The biggest problem may be to find documentation and this is the best source I've been able to find: How to use NativeJob?

查看更多
登录 后发表回答