docs: @FFDCIgnore(Throwable.class)
      void introspectMBeanAttributes(MBeanServer mbeanServer, ObjectName mbean, PrintWriter writer) {
          try {
              // Dump the description and the canonical form of the object name
              writer.println();
              writer.print(mbeanServer.getMBeanInfo(mbean).getDescription());
              writer.println(" (" + mbean.getCanonicalName() + ")");
  
              // Iterate over the attributes of the mbean.  For each, capture the name
              // and then attempt format the attribute.
              String indent = INDENT;
              MBeanAttributeInfo[] attrs = mbeanServer.getMBeanInfo(mbean).getAttributes();
              for (MBeanAttributeInfo attr : attrs) {
                  StringBuilder sb = new StringBuilder();
                  sb.append(indent).append(attr.getName()).append(": ");
                  sb.append(getFormattedAttribute(mbeanServer, mbean, attr, indent));
                  writer.println(sb.toString());
              }
          } catch (Throwable t) {
              Throwable rootCause = t;
              while (rootCause.getCause() != null) {
                  rootCause = rootCause.getCause();
              }
              StringBuilder sb = new StringBuilder();
              sb.append("<<Introspection failed: ");
              sb.append(rootCause.getMessage() != null ? rootCause.getMessage() : rootCause);
              sb.append(">>");
              writer.println(sb.toString());
          }
      }