/** java.io.ObjectStreamClass#getFields() */
 public void test_getFields() {
   ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
   ObjectStreamField[] osfArray = osc.getFields();
   assertTrue(
       "Array of fields should be of length 2 but is instead of length: " + osfArray.length,
       osfArray.length == 2);
 }
Exemple #2
0
  static void print(ObjectStreamClass desc) {
    System.out.println("Class name      : " + desc.getName());
    System.out.println("SerialVersionUID: " + desc.getSerialVersionUID());
    System.out.println("ObjectStreamFields");
    ObjectStreamField[] fields = desc.getFields();
    int numPrim = 0;
    int numObj = 0;
    for (int i = 0; i < fields.length; i++) {
      ObjectStreamField f = fields[i];
      String fieldName = "<fieldName unknown>";
      try {
        fieldName = f.getName();
      } catch (NoSuchMethodError e) {
        // ignore. ObjectStreamField.getName did not exist in JDK 1.1
      }

      if (f.isPrimitive()) {
        numPrim++;
        System.out.println("" + i + ". " + f.getType().getName() + " " + fieldName);
      } else {
        numObj++;
        String ts = "<unknown>";
        try {
          ts = f.getTypeString();
        } catch (NoSuchMethodError e) {
          // ignore. ObjectStreamField.getTypeString did not exist in JDK 1.1
          ts = "<field type unknown>";
        }
        System.out.println("" + i + ". " + ts + " " + fieldName);
      }
    }
    System.out.println("# primitive fields:" + numPrim + " # object ref fields:" + numObj);
  }
  public void test_specialTypes() {
    Class<?> proxyClass =
        Proxy.getProxyClass(this.getClass().getClassLoader(), new Class[] {Runnable.class});

    ObjectStreamClass proxyStreamClass = ObjectStreamClass.lookup(proxyClass);

    assertEquals(
        "Proxy classes should have zero serialVersionUID",
        0,
        proxyStreamClass.getSerialVersionUID());
    ObjectStreamField[] proxyFields = proxyStreamClass.getFields();
    assertEquals("Proxy classes should have no serialized fields", 0, proxyFields.length);

    ObjectStreamClass enumStreamClass = ObjectStreamClass.lookup(Thread.State.class);

    assertEquals(
        "Enum classes should have zero serialVersionUID", 0, enumStreamClass.getSerialVersionUID());
    ObjectStreamField[] enumFields = enumStreamClass.getFields();
    assertEquals("Enum classes should have no serialized fields", 0, enumFields.length);
  }
  private void checkFields(Object obj, ObjectStreamClass desc) {
    int numFields;
    try {
      numFields = (Integer) GET_NUM_OBJ_FIELDS_METHOD.invoke(desc, (Object[]) null);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    }

    if (numFields > 0) {
      int numPrimFields;
      ObjectStreamField[] fields = desc.getFields();
      Object[] objVals = new Object[numFields];
      numPrimFields = fields.length - objVals.length;
      try {
        GET_OBJ_FIELD_VALUES_METHOD.invoke(desc, obj, objVals);
      } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
        throw new RuntimeException(e);
      }
      for (int i = 0; i < objVals.length; i++) {
        if (objVals[i] instanceof String
            || objVals[i] instanceof Number
            || objVals[i] instanceof Date
            || objVals[i] instanceof Boolean
            || objVals[i] instanceof Class) {
          // filter out common cases
          continue;
        }

        // Check for circular reference.
        if (checked.containsKey(objVals[i])) {
          continue;
        }

        ObjectStreamField fieldDesc = fields[numPrimFields + i];
        Field field;
        try {
          field = (Field) GET_FIELD_METHOD.invoke(fieldDesc, (Object[]) null);
        } catch (IllegalAccessException e) {
          throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
          throw new RuntimeException(e);
        }

        field.getName();
        simpleName = field.getName();
        fieldDescription = field.toString();
        check(objVals[i]);
      }
    }
  }
  /**
   * Serializes the given class to the getCurrentDirectory() directory. The static
   * serializedInstance() method of clazz will be called to get an examplar of clazz. This examplar
   * will then be serialized out to a file stored in getCurrentDirectory().
   *
   * @param clazz the class to serialize.
   * @throws RuntimeException if clazz cannot be serialized. This exception has an informative
   *     message and wraps the originally thrown exception as root cause.
   * @see #getCurrentDirectory()
   */
  private void serializeClass(Class clazz, Map<String, List<String>> classFields)
      throws RuntimeException {
    File current = new File(getCurrentDirectory());

    if (!current.exists() || !current.isDirectory()) {
      throw new IllegalStateException(
          "There is no "
              + current.getAbsolutePath()
              + " directory. "
              + "\nThis is where the serialized classes should be. "
              + "Please run serializeCurrentDirectory() first.");
    }

    try {
      Field field = clazz.getDeclaredField("serialVersionUID");

      int modifiers = field.getModifiers();
      boolean _static = Modifier.isStatic(modifiers);
      boolean _final = Modifier.isFinal(modifiers);
      field.setAccessible(true);

      if (!_static || !_final || !(23L == field.getLong(null))) {
        throw new RuntimeException(
            "Class " + clazz + " does not define static final " + "long serialVersionUID = 23L");
      }

      int numFields = getNumNonSerialVersionUIDFields(clazz);

      if (numFields > 0) {
        Method method = clazz.getMethod("serializableInstance");
        Object object = method.invoke(null);

        File file = new File(current, clazz.getName() + ".ser");
        boolean created = file.createNewFile();

        FileOutputStream out = new FileOutputStream(file);
        ObjectOutputStream objOut = new ObjectOutputStream(out);
        objOut.writeObject(object);
        out.close();
      }

      // Make entry in list of class fields.
      ObjectStreamClass objectStreamClass = ObjectStreamClass.lookup(clazz);
      String className = objectStreamClass.getName();
      ObjectStreamField[] fields = objectStreamClass.getFields();
      @SuppressWarnings("Convert2Diamond")
      List<String> fieldList = new ArrayList<>();

      for (ObjectStreamField objectStreamField : fields) {
        String fieldName = objectStreamField.getName();
        fieldList.add(fieldName);
      }

      classFields.put(className, fieldList);
    } catch (NoSuchFieldException e) {
      throw new RuntimeException(
          ("There is no static final long field "
              + "'serialVersionUID' in "
              + clazz
              + ". Please make one and set it "
              + "to 23L."));
    } catch (NoSuchMethodException e) {
      throw new RuntimeException(
          "Class " + clazz + "does not " + "have a public static serializableInstance constructor.",
          e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(
          "The method serializableInstance() of " + "class " + clazz + " is not public.", e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(
          "Unable to statically call the "
              + "serializableInstance() method of class "
              + clazz
              + ".",
          e);
    } catch (IOException e) {
      throw new RuntimeException(
          "Could not create a new, writeable file "
              + "in "
              + getCurrentDirectory()
              + " when trying to serialize "
              + clazz
              + ".",
          e);
    }
  }
 public void testSerialization() {
   ObjectStreamClass osc = ObjectStreamClass.lookup(ObjectStreamClass.class);
   assertEquals(0, osc.getFields().length);
 }