Application Server Solutions for Microsoft IIS and ASP.NET
       solutions   products   partners   company   support   downloads         store
BlueDragon Self-Help: FAQ
Back to Search >  Back to Search Results

Faq ID 40
Product ServletExec
Category Known Limitations and Workarounds
Question Can I invoke a native program from my Java code?
Answer Yes.
This is typically done using code somewhat like this (for example):
java.lang.Process p = java.lang.Runtime.getRuntime().exec("C:\myNativeProgram.exe")
But there is much more to doing that than most people understand and it does require very careful coding and extensive testing.
A very common issue is when the native program being invoked is passed parameters and/or outputs data. It is not uncommon for code attempting this approach to encounter hanging of the entire JVM.
The Javadocs for java.lang.Process indicate that using the standard input or output streams can cause deadlock and/or blocking conditions. In New Atlanta's testing (using a standalone Java program... not ServletExec) it was observed that hanging would occur depending on the options being passed to the executable being invoked (AppCmd.exe for example).
One way that we've found which works well to avoid hanging issues is to have your code write a batch file that redirects all output to a file. Then use Runtime.exec() to invoke that batch file. Your code may then go read the file that contains the redirected output. We found this approach especially helpful when invoking native programs that output a lot of data.
java.lang.Process exposes 3 streams. Any native program being invoked this way may or may not place data on any or all of those streams. Regardless of whether your code needs to use those streams, it should always clean them up as follows:

finally
{
   if(p != null)
   {
      InputStream is  = p.getInputStream();
      OutputStream os = p.getOutputStream();
      InputStream err = p.getErrorStream();
	   
       if(is != null)
    	  try{ is.close(); }catch( IOException ignored ){}
    		   
       if(os != null)
    	  try{ os.close(); }catch( IOException ignored ){}
    		   
       if(err != null)
    	  try{ err.close(); }catch( IOException ignored ){}
   }
}

Otherwise the JVM in which your code is running could suffer from a Resource leak which could cause erratic behavior and/or hanging or crashing.
Some have asked if it is possible to invoke StartServletExec.bat from their own java code. While it may be possible to do this using the techniques described above, we do not recommend it. The techniques described above would be for invoking relatively simple, "short-lived" programs. ServletExec is an Application Server which stays up and running (in the best case) forever. We do not believe that Runtime.exec() would be well-suited for invoking a long-lived program such as ServletExec. If you wish to run some java code which itself starts up ServletExec (in an attempt to "wrap" ServletExec with your own java program) then here are some tips for doing that, but please understand that we've never tested it so we offer no guarantees:
  1. Startup your Java program specifying the same "JVM options" as those used to startup your SE AS instance. To understand what is meant by "JVM options" please see the bottom of SE FAQ #318 where it shows:
    java [ JVM options ] classname [ program arguments ]
  2. Have your java program mimick what the JVM interpreter (java.exe) does by invoking the static main() method of the classname. For example, with SE AS the classname is "ServletExec" (no quotes) (you can see this by examining your StartServletExec.bat file), so your code would simply call ServletExec.main() passing a String array that contains the program arguments.
SE FAQ #2 explains another way to run SE from within a different JVM.
Some very old answers to the "Runtime.exec() hangs what do I do?" question include:
  • For SE ISAPI:
    You need to allow the IIS admin service and the WWW Publishing service to interact with the desktop. You can do this by using the services control panel to edit the properties for these services. By selecting a service and clicking on "Startup" you can check the box: "Allow service to interact with desktop". Note that once your native program is running in this manner, it will need to be closed before you will be able to completely shut down IIS
  • For SE NSAPI running on Solaris:
    You can fix this problem by adding 'CGIWAIPid on' to magnus.conf and by using the reference version of the JDK instead of the production version.



   
company media information terms of use privacy policy contact us