@Override
    String applicable(Method[] getters) throws InvalidObjectException {

      final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;

      Class targetClass = getTargetClass();
      Constructor[] constrs = targetClass.getConstructors();

      List<Constructor> annotatedConstrList = OpenTypeUtil.newList();
      for (Constructor constr : constrs) {
        if (Modifier.isPublic(constr.getModifiers())
            && constr.getAnnotation(propertyNamesClass) != null) {
          annotatedConstrList.add(constr);
        }
      }

      if (annotatedConstrList.isEmpty()) {
        return "no constructor has @ConstructorProperties annotation";
      }

      annotatedConstructors = OpenTypeUtil.newList();

      Map<String, Integer> getterMap = OpenTypeUtil.newMap();
      String[] itemNames = getItemNames();
      for (int i = 0; i < itemNames.length; i++) {
        getterMap.put(itemNames[i], i);
      }

      Set<BitSet> getterIndexSets = OpenTypeUtil.newSet();
      for (Constructor constr : annotatedConstrList) {
        String[] propertyNames =
            ((ConstructorProperties) constr.getAnnotation(propertyNamesClass)).value();

        Type[] paramTypes = constr.getGenericParameterTypes();
        if (paramTypes.length != propertyNames.length) {
          final String msg = "Number of constructor params does not match "
              + "@ConstructorProperties annotation: " + constr;
          throw new InvalidObjectException(msg);
        }

        for (int i = 0; i < paramTypes.length; i++) {
          paramTypes[i] = fixType(paramTypes[i]);
        }

        int[] paramIndexes = new int[getters.length];
        for (int i = 0; i < getters.length; i++) {
          paramIndexes[i] = -1;
        }
        BitSet present = new BitSet();

        for (int i = 0; i < propertyNames.length; i++) {
          String propertyName = propertyNames[i];
          if (!getterMap.containsKey(propertyName)) {
            String msg = "@ConstructorProperties includes name " + propertyName
                + " which does not correspond to a property";
            for (String getterName : getterMap.keySet()) {
              if (getterName.equalsIgnoreCase(propertyName)) {
                msg += " (differs only in case from property " + getterName + ")";
              }
            }
            msg += ": " + constr;
            throw new InvalidObjectException(msg);
          }
          int getterIndex = getterMap.get(propertyName);
          paramIndexes[getterIndex] = i;
          if (present.get(getterIndex)) {
            final String msg = "@ConstructorProperties contains property " + propertyName
                + " more than once: " + constr;
            throw new InvalidObjectException(msg);
          }
          present.set(getterIndex);
          Method getter = getters[getterIndex];
          Type propertyType = getter.getGenericReturnType();
          if (!propertyType.equals(paramTypes[i])) {
            final String msg = "@ConstructorProperties gives property " + propertyName + " of type "
                + propertyType + " for parameter " + " of type " + paramTypes[i] + ": " + constr;
            throw new InvalidObjectException(msg);
          }
        }

        if (!getterIndexSets.add(present)) {
          final String msg = "More than one constructor has a @ConstructorProperties "
              + "annotation with this set of names: " + Arrays.toString(propertyNames);
          throw new InvalidObjectException(msg);
        }

        Constr c = new Constr(constr, paramIndexes, present);
        annotatedConstructors.add(c);
      }

      for (BitSet a : getterIndexSets) {
        boolean seen = false;
        for (BitSet b : getterIndexSets) {
          if (a == b) {
            seen = true;
          } else if (seen) {
            BitSet u = new BitSet();
            u.or(a);
            u.or(b);
            if (!getterIndexSets.contains(u)) {
              Set<String> names = new TreeSet<>();
              for (int i = u.nextSetBit(0); i >= 0; i = u.nextSetBit(i + 1)) {
                names.add(itemNames[i]);
              }
              final String msg = "Constructors with @ConstructorProperties annotation "
                  + " would be ambiguous for these items: " + names;
              throw new InvalidObjectException(msg);
            }
          }
        }
      }

      return null;
    }
Builder if the target class has a constructor that is annotated with @ConstructorProperties so
we can derive the corresponding getters.
geode-core/src/main/java/org/apache/geode/management/internal/OpenTypeConverter.java