1

I have a utility where Jmeter sends a request and the utility sends back response to Jmeter. When load increases, the Utility shuts down with an "EXCEPTION_ACCESS_VIOLATION".

Since it is an error, I am not able to handle it in a catch block. I made a second utility to restart the first utility when the error occurs. Below is the code of the second, restart, utility. In this second utility's code, at the second while, my program sometimes hangs. How do I detect this and restart the process?

public static void main(String[] args)
{
    String line = null;
    String currPID = null;
    try
    {
        while(true)
        {
            Process process = Runtime.getRuntime().exec("java -XX:+HeapDumpOnOutOfMemoryError -Xms250M -Xmx500M -XX:ErrorFile=NUL ws ");
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((line = input.readLine()) != null) //Program stucks at this Line
            {
                if(line.trim().length() != 0)
                {
                    if(line.startsWith("PID"))
                    {
                        currPID = line.substring(line.indexOf("@")+1);
                    }
                }
            }
            System.out.println("Ended");
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

I analysed process through jvisualvm where i found two java process is in running mode when i start second(restart) utility. I can see first utility is restarting regularly because its PID is changing frequently in jvisualvm and same happening in task manager. Everything is going on very well manner.

After sometime i found only one process is in Jvisualvm ie second(restart) utility. It means first utility JVM is crashed just guessing not sure. Something unusual is happening here. Because if JVM is crashed so It should be restarted. So i opened task manager and found first utility PID exists there but it is not changing as happening in starting. If i kill the process(first utility) explicitly from task manager. Seconds utility again restarts first utility same thing happens again, After some time first utility disappeared from jvisualvm, exists in taskmanager and delete process from taskmanager. What needs to do?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Deepak
  • 143
  • 1
  • 13
  • You can handle an error in a `catch` block by adding a catch block to catch class `Error` in addition to `Exception`, or just `Throwable` if this is test code. See here for further detail: http://stackoverflow.com/questions/15190164/catching-all-java-lang-error-for-logging-purposes-and-allowing-them-to-work-thei – JoshDM Oct 07 '13 at 15:10
  • But where put catch block for error. It could break normal flow of program. – Deepak Oct 07 '13 at 17:49
  • The intent at the moment is to try and capture the stack trace of the error. The simplest way to do this is to replace `(Exception e)` with `(Throwable e)`; the proper way to do this is to add a second catch block after your existing one to `catch (Error err)`. – JoshDM Oct 07 '13 at 17:55
  • You will need to elaborate as to what your `ws` utility does. Are you certain that multiple instances are not being created by your endless loop? – JoshDM Oct 07 '13 at 18:21
  • Actually error is not occurring in above code. Error is coming in utility, whom above code is restarting. It restart several time when utility gets error. But some times after restarting, Above code stuck at this line **while ((line = input.readLine()) != null)**. Code is stuck in input.readLine() method. If any doubt than feel free to discuss. Thanks. – Deepak Oct 07 '13 at 18:22
  • ws program runs at 9090 port on which Jmeter sends request. WS program takes HTTP request at 9090 port, perform some (encrypt & decrypt operation using JACOB.dll) operation and sends back to response. Jmeter sends request continuously then near about 50000(variate) it exits with some error(Excess_Violation_Error). So I made a above restart application. And rest is in above comment. – Deepak Oct 07 '13 at 18:39
  • Single instance are running. Because when ws.java exit with error than above program restart to ws. – Deepak Oct 07 '13 at 18:42
  • Please confirm you receive `Excess_Violation_Error` and not `Access_Violation_Error`. – JoshDM Oct 07 '13 at 19:27
  • An unexpected error has been detected by Java Runtime Environment: EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x03b2c4ad, pid=4148, tid=3780. JVM terminates with above statement. – Deepak Oct 08 '13 at 04:42
  • That is a much different error than "EXCESS_VIOLATION_ERROR". – JoshDM Oct 08 '13 at 12:04

3 Answers3

2

Try using .ready() function.

try {
      if (stdError.ready()) 
      {
            while((line= stdError.readLine()) != null){
                logger.error(line);
            }
      }
}

Do the same for the stdout.

It worked like a charm for me.

1

Your problem with hanging appears to be at the call to readLine.

readLine is for reading lines. The method will not return until the call is sure the end of line has been reached. It expects either a newline character or the complete cease of communications.

Is your first utility not sending a new line char?

Does your first utility fail to close the stream?

Your while call will hang indefinitely if the answer to both questions is yes.

You might be better off consuming with a custom implementation of the Scanner class.

JoshDM
  • 4,939
  • 7
  • 43
  • 72
  • Thanks for edit my question. I am OK with your first question. Not able to understand your second question. Just elaborating you process: When i start first utility using second utility, first utility prints its own PID(using S.o.println) on console (for ex: PID@7700) And will continue start listening at port 9090. Second utility just take console output of first utility. When first utility terminates along with error then second while loop of Restart utility breaks. Second utility will restart first utility again. What extra needs to do in first utility according to your second question? – Deepak Oct 09 '13 at 06:41
  • Please edit your main post to include a capture of the output from the first utility. – JoshDM Oct 09 '13 at 12:00
  • Is the error data passed to the second utility from the first utility when the first utility breaks? If not, you may need to do as Ulaga recommends and change your `BufferedReader` constructor to call `getErrorStream()`. – JoshDM Oct 09 '13 at 12:02
  • I can see error data on second utility console which is passed by first utility but not printed because it gives OutOfMemoryException. Second utility doesn't want anything from first utility. If i don't put second while than second utility would not wait termination of first utility so just for debugging purpose I prints PID of first utility – Deepak Oct 09 '13 at 18:46
  • Which utility is throwing the OOM, the first utility which presents the data, or the second utility which reads the data? It is possible the second utility hangs on this error because it is incomplete text and does not constitute a full "line" expected by `readLine()` – JoshDM Oct 09 '13 at 18:48
  • Second utility. But its not a problem. I have just explained reason why am i not printing error. – Deepak Oct 09 '13 at 19:05
  • At hanging time just for checking I send request to first utility through browser in three different tabs and found in two tabs chrome circle is rolling counter-clockwise and in third tab chrome circle is started rolling counter-clockwise and changed in clockwise rolling But not getting any response on any tab like my html page or any error page. – Deepak Oct 10 '13 at 11:59
1

Try to use getErrorStream() it'll catches the error message, if you use getInputStream() it'll reads only the success message or feedback messages.

for ex: if you execute the following command & read the process message using getInputStream(),

Process process = Runtime.getRuntime().exec("net use u: \\sharedIP\sharedFolder");
BufferedReader input = new BufferedReader(new inputStreamReader(process.getInputStream()));

you can only get feedback messages like "network drive connected successfully" but not the error messages.

if you use getErrorStream() to read the process message it'll read the error messages like "the network drive was not found". when the process executed it'll give a message to either getInputStream() or getErrorStream(). so use both method to read the message from the process, if i'm correct this'll work. I'm just trying to give you an idea but i'm not sure.

Ulaga
  • 863
  • 1
  • 8
  • 17