docs: protected void fileOpen() throws InternalLogException, LogAllocationException,
                      LogIncompatibleException
      {
          if (tc.isEntryEnabled())
              Tr.entry(tc, "fileOpen", this);
  
          final boolean fileColdStarting;
  
          // Open the file, creating it if it does not already exist.
          try
          {
              try
              {
                  final File pFile = new File(_logDirectory, _fileName);
  
                  // Determine if the log file exists or is zero bytes long. In either of
                  // these cases, we consider it to be a cold start of the file.
                  fileColdStarting = ((!pFile.exists()) || (pFile.length() == 0));
  
                  if (fileColdStarting)
                  {
                      Tr.info(tc, "CWRLS0006_RECOVERY_LOG_CREATE", _logDirectory + File.separator + _fileName);
                  }
  
                  // Open/Create the file.
                  // _fileBuffer = (MappedByteBuffer) AccessController.doPrivileged(
                  _fileBuffer = (MappedByteBuffer) Configuration.getAccessController()
                                  .doPrivileged(
                                                new java.security.PrivilegedExceptionAction()
                                                {
                                                    @Override
                                                    public java.lang.Object run() throws Exception
                                                    {
                                                        if (tc.isEntryEnabled())
                                                            Tr.entry(tc, "run", this);
  
  //              _file = new RandomAccessFile(pFile, "rw");
                                                        _file = RLSAccessFile.getRLSAccessFile(pFile); // @255605C
                                                        _fileChannel = _file.getChannel();
  
                                                        // NB - this limits us to a maximum file size
                                                        // of 2GB. This is the max value of an int and
                                                        // is also the maximum amount of data that
                                                        // can be held in a MappedByteBuffer.
                                                        final int fileLength = (int) _file.length();
  
                                                        final int fileSizeBytes = _fileSize * 1024;
  
                                                        // In the event that the log file already exists and it's bigger
                                                        // than the required file size ensure that we map the entire
                                                        // contents of the file.             
                                                        final int sizeToMap = fileLength > fileSizeBytes ? fileLength : fileSizeBytes;
  
                                                        // Feature 731093 default for noMemoryMappedFIles flag is operating system dependent
                                                        String osName = System.getProperty("os.name");
                                                        if (osName != null)
                                                            osName = osName.toLowerCase();
                                                        if (tc.isDebugEnabled())
                                                            Tr.debug(tc, "Working on operating system " + osName);
                                                        // If not specified - default is false
                                                        boolean noMemoryMappedFiles = Boolean.getBoolean("com.ibm.ws.recoverylog.spi.NoMemoryMappedFiles");
                                                        // If Windows and HA enabled, or z/OS (feature 731093) then we want the default to be non-memory mapped
                                                        if (osName != null
                                                            && ((Configuration.HAEnabled() && osName.startsWith("windows")) || osName.startsWith("z/os") || osName.startsWith("os/390")))
                                                        {
                                                            final String propertyValue = System.getProperty("com.ibm.ws.recoverylog.spi.NoMemoryMappedFiles");
                                                            if (propertyValue == null || !(propertyValue.equalsIgnoreCase("false")))
                                                                noMemoryMappedFiles = true;
                                                        }
                                                        if (tc.isDebugEnabled())
                                                            Tr.debug(tc, "NoMemoryMappedFiles flag is " + noMemoryMappedFiles);
  
                                                        Object fileBuffer = null;
  
                                                        if (!noMemoryMappedFiles)
                                                        {
                                                            try
                                                            {
                                                                fileBuffer = _fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, sizeToMap);
                                                                _isMapped = true;
                                                            }
                                                            catch (Throwable t)
                                                            {
                                                                if (tc.isEventEnabled())
                                                                    Tr.event(tc, "Mapping of recovery log file failed. Using non-mapped file.", t);
                                                                if (tc.isEventEnabled())
                                                                    Tr.event(tc, "Resetting file Channel position to '0' from :", _fileChannel.position());
                                                                _fileChannel.position(0); //An Exception in the map method can leave an incorrect position (PM14310)
                                                            }
                                                        }
                                                        else
                                                        {
                                                            if (tc.isEventEnabled())
                                                                Tr.event(tc, "Recovery log has been instructed not to use a mapped-file model.");
                                                        }
  
                                                        if (fileBuffer == null)
                                                        {
                                                            // Either we were instructed not to use a mapped buffer or the
                                                            // attempt to use one failed. Allocate a direct byte buffer
                                                            // and read the FileChannel into the buffer.  write()s to the
                                                            // direct byte buffer will not be reflected by the FileChannel
                                                            // until a force() is made on the LogFileHandle.
  
                                                            final ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(sizeToMap);
  
                                                            if (fileColdStarting)
                                                            {
                                                                _fileChannel.write(directByteBuffer, 0);
                                                                _fileChannel.force(true);
                                                            }
  
                                                            _fileChannel.read(directByteBuffer);
                                                            directByteBuffer.rewind();
                                                            _isMapped = false;
  
                                                            if (tc.isDebugEnabled())
                                                                Tr.debug(tc, "A direct byte buffer has been allocated successfully.");
  
                                                            fileBuffer = directByteBuffer;
                                                        }
  
                                                        if (tc.isEntryEnabled())
                                                            Tr.exit(tc, "run", fileBuffer);
                                                        return fileBuffer;
                                                    }
                                                });
              } catch (java.security.PrivilegedActionException exc)
              {
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "338", this);
                  throw new LogAllocationException(exc);
              } catch (Throwable exc)
              {
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "343", this);
                  throw new InternalLogException(exc);
              }
          } catch (LogAllocationException exc)
          {
              FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "351", this);
              _fileBuffer = null;
              if (_file != null)
                  fileClose(); // @255605A
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "fileOpen", exc);
              throw exc;
          } catch (Throwable exc)
          {
              FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "359", this);
              _fileBuffer = null;
              if (_file != null)
                  fileClose(); // @255605A
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "fileOpen", "InternalLogException");
              throw new InternalLogException(exc);
          }
  
          if (fileColdStarting)
          {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "Log File " + this._fileName + " is cold starting");
  
              // The file did not exist when this call was issued and has been created above.
              // Write an empty log header into the file to ensure that it can't be confused
              // with a corrupt log file in the event of a crash before we fully initialize 
              // it.
              try
              {
                  writeFileHeader(false);
              } catch (InternalLogException exc)
              {
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "388", this);
                  fileClose(); // @255605A
                  _file = null;
                  _fileChannel = null;
                  _fileBuffer = null;
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "fileOpen", exc);
                  throw exc;
              } catch (Throwable exc)
              {
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "396", this);
                  fileClose(); // @255605A
                  _file = null;
                  _fileChannel = null;
                  _fileBuffer = null;
                  if (tc.isEntryEnabled())
                      Tr.exit(tc, "fileOpen", "InternalLogException");
                  throw new InternalLogException(exc);
              }
          }
          else
          {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "Log File " + this._fileName + " is warm starting");
  
              // The file already existed on disk before this method was called. We must load
              // the header information from this file.
              readFileHeader();
          }
  
          // First check whether invalid. invalid trumps incompatible. 
          if (!_logFileHeader.valid())
          {
              if (tc.isDebugEnabled())
                  Tr.debug(tc, "Log File " + this._fileName + " is not valid");
              try
              {
  //        Dont close channel as it will free a lock - wait until file close
  //        _fileChannel.close(); // @255605D
                  _file.close();
              } catch (java.io.IOException exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "423", this);
              } catch (Throwable exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "429", this);
              }
  
              _fileBuffer = null;
              _file = null;
              _fileChannel = null;
              _logFileHeader = null;
  
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "fileOpen", "InternalLogException");
              throw new InternalLogException();
          }
  
          // If the header incompatible (created by an unsupported version of the RLS) then throw an exception.
          if (!_logFileHeader.compatible())
          {
              try
              {
  //        Dont close channel as it will free a lock - wait until file close
  //        _fileChannel.close(); // @255605D
                  _file.close();
              } catch (java.io.IOException exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "423", this);
              } catch (Throwable exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "429", this);
              }
  
              _fileBuffer = null;
              _file = null;
              _fileChannel = null;
              _logFileHeader = null;
  
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "fileOpen", "LogIncompatibleException");
              throw new LogIncompatibleException();
          }
  
          if (!serviceCompatible())
          {
              try
              {
  //        Dont close channel as it will free a lock - wait until file close
  //        _fileChannel.close(); // @255605D
                  _file.close();
              } catch (java.io.IOException exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "423", this);
              } catch (Throwable exc)
              {
                  // The file could not even be closed! There is nothing that can be done in this situation.
                  // Simply allow the LogIncompatibleException exception to be passed back up the stack.
                  FFDCFilter.processException(exc, "com.ibm.ws.recoverylog.spi.LogFileHandle.fileOpen", "429", this);
              }
  
              _fileBuffer = null;
              _file = null;
              _fileChannel = null;
              _logFileHeader = null;
  
              if (tc.isEntryEnabled())
                  Tr.exit(tc, "fileOpen", "LogIncompatibleException");
              throw new LogIncompatibleException();
          }
  
          if (tc.isEntryEnabled())
              Tr.exit(tc, "fileOpen");
      }