Friday 31 January 2020

Weblogic 12c WLST compatibility with Windows Server 2016

During the course of my work I've had to support the upgrade of some legacy applications running on Weblogic 12c (WebLogic Server Version: 12.1.2.0.0) from Windows Server 2008 to Windows Server 2016. These particular domains use a WLST script for deployment, essentially tearing down and re-creating the domains when deployed. This started failing after the servers were upgraded to Windows 2016, with the following error:

Failed to get environment, environ will be empty: (0, ‘Failed to execute command ([\’sh\’, \’-c\’, \’env\’]): java.io.IOException: Cannot run program “sh”: CreateProcess error=2, The system cannot find the file specified’)

This happens because the built-in WLST Jython interpreter is unable to recognise the OS version (Windows 2016) that it is running on. Upgrading the Weblogic installation itself was not an available option in this case, sow e updated the WLST to accept the newer operating system:

  1. Open the following jar file: \wlserver\common\wlst\modules\jython-modules.jar
  2. In that jython-modules.jar file, edit the file javashell.py file and search for the _getOsType function on line 136:
    def _getOsType( os=None ):
        """Select the OS behavior based on os argument, 'python.os' registry
        setting and 'os.name' Java property.
        os: explicitly select desired OS. os=None to autodetect, os='None' to
        disable
        """
        os = str(os or sys.registry.getProperty( "python.os" ) or \
                   System.getProperty( "os.name" ))
             
        _osTypeMap = (
            ( "nt", ( 'nt', 'Windows NT', 'Windows NT 4.0', 'WindowsNT',
                      'Windows 2000', 'Windows 2003', 'Windows XP', 'Windows CE',
                      'Windows Vista', 'Windows Server 2008', 'Windows 7', 'Windows 8' )),
            ( "dos", ( 'dos', 'Windows 95', 'Windows 98', 'Windows ME' )),
            ( "mac", ( 'mac', 'MacOS', 'Darwin' )),
            ( "None", ( 'None', )),
            )
        foundType = None
        for osType, patterns in _osTypeMap:
            for pattern in patterns:
                if os.startswith( pattern ):
                    foundType = osType
                    break
            if foundType:
                break
        if not foundType:
            foundType = "posix" # default - posix seems to vary most widely
     
        return foundType
    
  3. Edit the _getOsType function to add the missing OS version, and for safety, set it to default to "nt" instead of "posix" if the OS is not recognised (we've seen some variations of what Jython detects as the OS):
    def _getOsType( os=None ):
        """Select the OS behavior based on os argument, 'python.os' registry
        setting and 'os.name' Java property.
        os: explicitly select desired OS. os=None to autodetect, os='None' to
        disable
        """
        os = str(os or sys.registry.getProperty( "python.os" ) or \
                   System.getProperty( "os.name" ))
             
        _osTypeMap = (
            ( "nt", ( 'nt', 'Windows NT', 'Windows NT 4.0', 'WindowsNT',
                      'Windows 2000', 'Windows 2003', 'Windows XP', 'Windows CE',
                      'Windows Vista', 'Windows Server 2008', 'Windows Server 2012 R2', 'Windows 7', 'Windows 8', 'Windows 10', 'Windows NT (unknown)' )),
            ( "dos", ( 'dos', 'Windows 95', 'Windows 98', 'Windows ME' )),
            ( "mac", ( 'mac', 'MacOS', 'Darwin' )),
            ( "None", ( 'None', )),
            )
        foundType = None
        for osType, patterns in _osTypeMap:
            for pattern in patterns:
                if os.startswith( pattern ):
                    foundType = osType
                    break
            if foundType:
                break
        if not foundType:
            foundType = "nt" # default to NT
     
        return foundType
    

WLST will now be able to detect the OS, or default to NT if it doesn't; either way, it will now again be able to work correctly on Windows.