Forum Discussion

yoharaaj's avatar
yoharaaj
New Contributor
8 years ago

Receiving JVM error in jenkins when using testrunner.bat

Team,

We are doing Continuous Integration with Jenkins by using SoapUI NG TestRunner. Daily 50 plus jobs are running in it. At times, we could see the below error in the job log,

-------------------------------------------------------------------------------
The process cannot access the file because it is being used by another process.
C:\Users\...\AppData\Local\Temp\jfxrtpath
The process cannot access the file because it is being used by another process.
The process cannot access the file because it is being used by another process.
C:\Users\...\AppData\Local\Temp\readyxmx
The process cannot access the file because it is being used by another process.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Invalid maximum heap size: -Xmx
Build step 'Execute Windows batch command' marked build as failure Recording test results

 

readyapi.bat had -Xmx2048m. Not sure what caused this issue. We believe, it is not following any patterns , it occurs randomly for some jobs. Please suggest solution for this issue and let us know, if you need any further details.

 

  • I have encountered this issue and raised it with SmartBear support.

     

    I only saw it when I started two instances of TestRunner.bat at exactly the same time. I thought the issue was lines 31 to 33 of TestRunner.bat (I'm using version 1.7) which is
     
    "%JAVA%" -cp "%CLASSPATH%" com.eviware.soapui.tools.JfxrtLocator > %TEMP%\jfxrtpath
    set /P JFXRTPATH= < %TEMP%\jfxrtpath
    del %TEMP%\jfxrtpath

     
    To me it appears if two independent instances of TestRunner.bat are started at the same time they are both trying to write and manipulate the same file, which would explain the initial error message you see:

     

    The process cannot access the file because it is being used by another process.
    C:\Users\...\AppData\Local\Temp\jfxrtpath

     

    The response I got was:

     

    The error you faced doesn't indicate any problem with the tool. For some reason, TestRunner's Java VM cannot just recognize the -Xmx option when you run the second instance of the runner. The option denotes the maximum heap size that can be used by the tool. Your system should have enough free RAM to start the tool's process. To avoid the situation, you can specify a hardcoded value for the Java option by following the steps below:
    - open the "C:\Program Files\SmartBear\ReadyAPI-1.7.0-m-SNAPSHOT"\bin\testrunner.bat" file in a text editor (as an Administrator);
    - locate the following lines in the file:
    rem uncomment to override memory limit
    rem set READY_XMX=4000m
    - uncomment the second line specifying a maximum heap size that is enough to run your project, e.g.
    set READY_XMX=1024m
    - save your changes.

    The setting above allocates 1 Gb of RAM for each TestRunner's Java VM. That is, your system must have at least 2 Gb of RAM to create two TestRunner instances simultaneously. You can specify another size in megabytes (e.g. set READY_XMX=768m) or gygabytes (e.g. set READY_XMX=2g).

    Please let us know if you need anymore assistance on this matter.

     

    On pointing out the details of the TestRunner.bat I then got the response:

     

    Actually, there is no issue with the batch file. The files you listed (jfxrtpath, readypermsize, readyxmx) are auxiliary. The script creates and deletes them before running TestRunner's Java VM. Therefore, all TestRunner instances aren't sharing them during the runtime. The files are created to calculate certain settings for the VM. In your case, the jfxrtpath and readypermsize files are simply empty so the fact that they are locked by one TestRunner instance doesn't affect another instance anyhow. Locking readyxmx affects the other instance, but creating a unique version of the file for each TestRunner instance may not work for you as expected. This is because of how the file's value is calculated. Basically, Ready! API and TestRunner try to allocate a half of available free memory for the -Xmx option. That is, if two TestRunner instances are run simultaneously, they potentially can consume all your free memory. Therefore, to avoid the situation, you just need to specify a hardcoded value for the -Xmx option as we mentioned before. This ensures that your TestRunner instances' memory consumption is balanced.

    I hope this helps.

     

    I ended up working around this issue by just not starting two instances of TestRunner at exactly the same time.

     

    If the above support comments do not help, you might want to raise the issue with support yourself.

  • Radford's avatar
    Radford
    Super Contributor

    I have encountered this issue and raised it with SmartBear support.

     

    I only saw it when I started two instances of TestRunner.bat at exactly the same time. I thought the issue was lines 31 to 33 of TestRunner.bat (I'm using version 1.7) which is
     
    "%JAVA%" -cp "%CLASSPATH%" com.eviware.soapui.tools.JfxrtLocator > %TEMP%\jfxrtpath
    set /P JFXRTPATH= < %TEMP%\jfxrtpath
    del %TEMP%\jfxrtpath

     
    To me it appears if two independent instances of TestRunner.bat are started at the same time they are both trying to write and manipulate the same file, which would explain the initial error message you see:

     

    The process cannot access the file because it is being used by another process.
    C:\Users\...\AppData\Local\Temp\jfxrtpath

     

    The response I got was:

     

    The error you faced doesn't indicate any problem with the tool. For some reason, TestRunner's Java VM cannot just recognize the -Xmx option when you run the second instance of the runner. The option denotes the maximum heap size that can be used by the tool. Your system should have enough free RAM to start the tool's process. To avoid the situation, you can specify a hardcoded value for the Java option by following the steps below:
    - open the "C:\Program Files\SmartBear\ReadyAPI-1.7.0-m-SNAPSHOT"\bin\testrunner.bat" file in a text editor (as an Administrator);
    - locate the following lines in the file:
    rem uncomment to override memory limit
    rem set READY_XMX=4000m
    - uncomment the second line specifying a maximum heap size that is enough to run your project, e.g.
    set READY_XMX=1024m
    - save your changes.

    The setting above allocates 1 Gb of RAM for each TestRunner's Java VM. That is, your system must have at least 2 Gb of RAM to create two TestRunner instances simultaneously. You can specify another size in megabytes (e.g. set READY_XMX=768m) or gygabytes (e.g. set READY_XMX=2g).

    Please let us know if you need anymore assistance on this matter.

     

    On pointing out the details of the TestRunner.bat I then got the response:

     

    Actually, there is no issue with the batch file. The files you listed (jfxrtpath, readypermsize, readyxmx) are auxiliary. The script creates and deletes them before running TestRunner's Java VM. Therefore, all TestRunner instances aren't sharing them during the runtime. The files are created to calculate certain settings for the VM. In your case, the jfxrtpath and readypermsize files are simply empty so the fact that they are locked by one TestRunner instance doesn't affect another instance anyhow. Locking readyxmx affects the other instance, but creating a unique version of the file for each TestRunner instance may not work for you as expected. This is because of how the file's value is calculated. Basically, Ready! API and TestRunner try to allocate a half of available free memory for the -Xmx option. That is, if two TestRunner instances are run simultaneously, they potentially can consume all your free memory. Therefore, to avoid the situation, you just need to specify a hardcoded value for the -Xmx option as we mentioned before. This ensures that your TestRunner instances' memory consumption is balanced.

    I hope this helps.

     

    I ended up working around this issue by just not starting two instances of TestRunner at exactly the same time.

     

    If the above support comments do not help, you might want to raise the issue with support yourself.

    • yoharaaj's avatar
      yoharaaj
      New Contributor

      Thanks for the detailed explanation. So if my understanding is correct,
      If 2 independent Testrunner access the jfxrtpath / readyxmx file at same time, then this issue may occur. So the hardcoded Xmx value in Testrunner.bat would help to resolve this issue.

      Also, do we need to hardcode the Xmx available in the ready-api.bat too?

      • Radford's avatar
        Radford
        Super Contributor

        I've got to be honest and say that we didn't try out the support suggestions. We were lucky we were in a position where we could just avoid starting two TestRunner sessions at the same time, and at the time that was the quickest/simplest solution, and I didn't want to get into hard coding values.

         

        I pasted the support responses as they might help you, plus it will give a starting point if you do raise a new call with Smartbear.

         

        If you do get any further with this either by trying out the support suggestion or from a new support case, please could you post back here as I'd be interested to know the details. Thanks.

  • KevinK's avatar
    KevinK
    Regular Visitor

    I've come up with a solution to the "The process cannot access the file because it is being used by another process." error.

     

    Simply generate a temp filename randomly on the fly, this method also uses a lock file since %random% in batch files isn't particularly random and collisions can occur if multiple runs execute at once.  Temp file generation is at the top and the other alteration is down when CLASSPATH is being set, prefixing jfxrtpath with %tempFile%:

     

    @echo off
    
    
    :getTemp
    set "tempFile=testrunner_%random%"
    set "lockFile=%temp%\%tempFile%.lock"
    9>&2 2>nul (2>&9 8>"%lockFile%" call :begin %*) || goto :getTemp
    
    :begin
    echo The unique tempfile for this process is "%tempfile%"
    
    set SOAPUI_HOME=%~dp0
    if exist "%SOAPUI_HOME%..\jre\bin" goto SET_BUNDLED_JAVA
    
    if exist "%JAVA_HOME%" goto SET_SYSTEM_JAVA
    
    echo JAVA_HOME is not set, unexpected results may occur.
    echo Set JAVA_HOME to the directory of your local JDK to avoid this message.
    goto SET_SYSTEM_JAVA
    
    :SET_BUNDLED_JAVA
    set JAVA=%SOAPUI_HOME%..\jre\bin\java
    goto END_SETTING_JAVA
    
    :SET_SYSTEM_JAVA
    set JAVA=java
    
    :END_SETTING_JAVA
    
    
    rem init classpath
    
    set CLASSPATH=%SOAPUI_HOME%soapui-5.3.0.jar;%SOAPUI_HOME%..\lib\*
    "%JAVA%" -cp "%CLASSPATH%" com.eviware.soapui.tools.JfxrtLocator > %TEMP%\%tempFile%_jfxrtpath
    set /P JFXRTPATH= < %TEMP%\%tempFile%_jfxrtpath
    del %TEMP%\%tempFile%_jfxrtpath
    set CLASSPATH=%CLASSPATH%;%JFXRTPATH%
    
    rem JVM parameters, modify as appropriate
    set JAVA_OPTS=-Xms128m -Xmx1024m -Dsoapui.properties=soapui.properties "-Dsoapui.home=%SOAPUI_HOME%\"
    
    if "%SOAPUI_HOME%\" == "" goto START
        set JAVA_OPTS=%JAVA_OPTS% -Dsoapui.ext.libraries="%SOAPUI_HOME%ext"
        set JAVA_OPTS=%JAVA_OPTS% -Dsoapui.ext.listeners="%SOAPUI_HOME%listeners"
        set JAVA_OPTS=%JAVA_OPTS% -Dsoapui.ext.actions="%SOAPUI_HOME%actions"
    
    :START
    
    rem ********* run soapui testcase runner ***********
    
    "%JAVA%" %JAVA_OPTS% com.eviware.soapui.tools.SoapUITestCaseRunner %*
    
    2>nul del "%lockFile%"