List of usage examples for java.lang.reflect Field getDeclaringClass
@Override
public Class<?> getDeclaringClass()
From source file:org.jgentleframework.core.factory.support.ElementAspectFactory.java
/** * Analyses field./*ww w . ja va 2 s .c o m*/ * * @param interceptors * the given array containing all interceptors * @param map * the given map containing the interceptors according to their * matchers. * @param definition * the definition of target class declaring the given field. * @param field * the given field * @return returns the corresponding FieldAspectPair if the interceptors * according to the given field are existed, if not, returns * <code>null</code>. */ public FieldAspectPair analysesField(FieldInterceptor[] interceptors, Map<Interceptor, Matcher<Definition>> map, Definition definition, final Field field) { Assertor.notNull(interceptors, "The given interceptor must not be null !!"); Assertor.notNull(map, "The given map must not be null !!"); Assertor.notNull(definition, "The given definition must not be null !!"); Assertor.notNull(field, "The given field must not be null !!"); FieldAspectPair result = new FieldAspectPair(field); List<FieldInterceptor> list = new ArrayList<FieldInterceptor>(); /* * Search on given interceptor array. */ for (FieldInterceptor interceptor : interceptors) { Matcher<Definition> matcher = map.get(interceptor); if (matcher != null && matcher.matches(definition)) { if (!Utils.validatesInterceptConditioner(matcher, definition, interceptor)) { continue; } else { FieldAnnotatedWithMatcher pointcutField = (ReflectUtils.isCast(FieldAnnotatedWithMatcher.class, matcher) ? (FieldAnnotatedWithMatcher) matcher : null); TypeAnnotatedWithMatcher pointcutType = (ReflectUtils.isCast(TypeAnnotatedWithMatcher.class, matcher) ? (TypeAnnotatedWithMatcher) matcher : null); MethodAnnotatedWithMatcher pointcutMethod = (ReflectUtils.isCast( MethodAnnotatedWithMatcher.class, matcher) ? (MethodAnnotatedWithMatcher) matcher : null); if (pointcutField != null) { FieldFilter fieldFilter = pointcutField.getFieldFilter(); if (fieldFilter != null && fieldFilter.matches(new BasicFieldMatchingAspectPair(field, definition)) && !list.contains(interceptor)) { list.add(interceptor); } } else if (pointcutType != null) { ClassFilter classFilter = pointcutType.getClassFilter(); if (classFilter != null && classFilter.matches( new BasicTypeMatchingAspectPair(field.getDeclaringClass(), field, definition)) && !list.contains(interceptor)) { list.add(interceptor); } } else if (pointcutMethod != null) { MethodFilter methodFilter = pointcutMethod.getMethodFilter(); if (methodFilter != null && methodFilter .matches(new BasicMethodConstructorMatchingAspectPair(null, definition)) && !list.contains(interceptor)) { list.add(interceptor); } } else { if (log.isFatalEnabled()) log.fatal( "Could not intercept the given interceptor !! The declared matcher is not supported !", new MatchingException()); } } } } if (list.size() == 0) return result; else result.addAll(list); return result; }
From source file:org.scub.foundation.framework.core.oval.validator.AbstractValidator.java
/** * validates the field and getter constrains of the given object. if the given object is a class the static fields and getters are validated. * @param violationsInformations the violations informations * @param validatedObject the object to validate, cannot be null * @param clazz the class for validateObject * @param violations the constraints violations list * @param profiles the profiles array/*w ww .j av a 2s .co m*/ * @param attributePrefix the attribute prefix for the attribute name constraint failed construction * @param clazzHierarchy the class list hierarchy in case of nested Collection validation * @param validatedFields the validated fields. * @return the list of failed constraint violation informations */ protected ValidationInformation validateInformationObject( List<ConstraintViolationInformation> violationsInformations, final Object validatedObject, final Class<?> clazz, final List<ConstraintViolation> violations, final String[] profiles, String attributePrefix, List<Class<?>> clazzHierarchy, Set<String> validatedFields) { LOGGER.debug("Protected validate object '" + clazz.getSimpleName() + QUOTE + (StringUtils.isNotBlank(attributePrefix) ? " corresponding to '" + attributePrefix + QUOTE : "")); assert validatedObject != null; assert clazz != null; assert violations != null; // abort if the root class has been reached if (clazz == Object.class) { LOGGER.debug("Validation ignored"); return null; } currentlyValidatedObjects.get().getLast().add(validatedObject); final ClassChecks classCheck = getClassChecks(clazz); // validate field constraints for (final Field field : classCheck.constrainedFields) { final Collection<Check> checks = classCheck.checksForFields.get(field); LOGGER.debug("Browse field '" + clazz.getSimpleName() + POINT + field.getName() + "' which have " + checks.size() + " check(s)"); if (checks != null && checks.size() > 0) { final Object valueToValidate = ReflectionUtils.getFieldValue(field, validatedObject); final OValContext ctx = ContextCache.getFieldContext(field); // for all field checks for (final Check check : checks) { LOGGER.debug("Browse field '" + clazz.getSimpleName() + POINT + field.getName() + "' check '" + check.getClass().getSimpleName() + QUOTE); if (check instanceof EachObjectValidCheck && valueToValidate instanceof List<?>) { LOGGER.debug( "Browse field '" + clazz.getSimpleName() + POINT + field.getName() + "' as a list"); // validate each object in the Collection final List<?> collectionToValidate = (List<?>) valueToValidate; final List<Class<?>> nestedClazzHierarchy = new ArrayList<Class<?>>(); nestedClazzHierarchy.addAll(clazzHierarchy); int i = 0; for (Object object : collectionToValidate) { if (i == 0) { nestedClazzHierarchy.add(object.getClass()); } // construction of the nested attribut prefix String nestedAttributePrefix = (attributePrefix.isEmpty() ? field.getDeclaringClass().getSimpleName() : attributePrefix) + POINT; nestedAttributePrefix += field.getName() + ".[[" + i + "]]"; LOGGER.debug("Validate list item '" + nestedAttributePrefix + "'"); validateInformationObject(violationsInformations, object, object.getClass(), violations, profiles, nestedAttributePrefix, nestedClazzHierarchy, validatedFields); i++; } } else { if (check.getClass().equals(AssertValidCheck.class) && valueToValidate != null) { LOGGER.debug("Browse field as an object '" + field.getName() + QUOTE); String nestedAttributePrefix = (attributePrefix.isEmpty() ? field.getDeclaringClass().getSimpleName() : attributePrefix) + POINT; nestedAttributePrefix += field.getName(); LOGGER.debug("Assert valid: '" + nestedAttributePrefix + "'"); validateInformationObject(violationsInformations, valueToValidate, valueToValidate.getClass(), violations, profiles, nestedAttributePrefix, new ArrayList<Class<?>>(), validatedFields); continue; } final List<ConstraintViolation> localViolations = new ArrayList<ConstraintViolation>(); LOGGER.debug("Check constraint '" + check.getClass().getSimpleName() + QUOTE); checkConstraint(localViolations, check, validatedObject, valueToValidate, ctx, profiles, false); addValidatedField(validatedFields, check, attributePrefix, clazzHierarchy, profiles); constraintViolationsManagement(violationsInformations, localViolations, violations, check.getTarget(), attributePrefix, clazzHierarchy); } } } } // validate constraints on getter methods for (final Method getter : classCheck.constrainedMethods) { final Collection<Check> checks = classCheck.checksForMethodReturnValues.get(getter); LOGGER.debug("Browse getter '" + clazz.getSimpleName() + POINT + getter.getName() + "' which have " + checks.size() + " check(s)"); if (checks != null && checks.size() > 0) { final Object valueToValidate = ReflectionUtils.invokeMethod(getter, validatedObject); final OValContext ctx = ContextCache.getMethodReturnValueContext(getter); for (final Check check : checks) { LOGGER.debug("Browse getter '" + clazz.getSimpleName() + POINT + getter.getName() + "' check '" + check.getClass().getSimpleName() + QUOTE); final List<ConstraintViolation> localViolations = new ArrayList<ConstraintViolation>(); LOGGER.debug("Check constraint '" + check.getClass().getSimpleName() + QUOTE); checkConstraint(localViolations, check, validatedObject, valueToValidate, ctx, profiles, false); addValidatedField(validatedFields, check, attributePrefix, clazzHierarchy, profiles); constraintViolationsManagement(violationsInformations, localViolations, violations, check.getTarget(), attributePrefix, clazzHierarchy); } } } // validate object constraints LOGGER.debug("Browse class '" + clazz.getSimpleName() + "' which have " + classCheck.checksForObject.size() + " check(s)"); if (classCheck.checksForObject.size() > 0) { final OValContext ctx = ContextCache.getClassContext(clazz); for (final Check check : classCheck.checksForObject) { final List<ConstraintViolation> localViolations = new ArrayList<ConstraintViolation>(); LOGGER.debug("Check constraint '" + check.getClass().getSimpleName() + QUOTE); checkConstraint(localViolations, check, validatedObject, validatedObject, ctx, profiles, false); addValidatedField(validatedFields, check, attributePrefix, clazzHierarchy, profiles); constraintViolationsManagement(violationsInformations, localViolations, violations, check.getTarget(), attributePrefix, clazzHierarchy); } } // if the super class is annotated to be validatable also validate it against the object LOGGER.debug("Validate superclass '" + clazz.getSuperclass().getSimpleName() + "'"); validateInformationObject(violationsInformations, validatedObject, clazz.getSuperclass(), violations, profiles, attributePrefix, clazzHierarchy, validatedFields); return new ValidationInformation(violationsInformations, validatedFields); }
From source file:com.hiperf.common.ui.server.storage.impl.PersistenceHelper.java
private static PropertyDescriptor getPropertyDescriptor(PropertyDescriptor[] pds, Field f) throws PersistenceException { PropertyDescriptor pd = null; for (PropertyDescriptor p : pds) { if (f.getName().equals(p.getName())) { pd = p;//from w ww. j ava 2s . c om break; } } if (pd == null) throw new PersistenceException("PropertyDescriptor not found for " + f.getName() + " in class " + f.getDeclaringClass().getName()); return pd; }
From source file:org.apache.camel.dataformat.bindy.BindyFixedLengthFactory.java
public void bind(String record, Map<String, Object> model, int line) throws Exception { int pos = 1;//from ww w .j a v a 2 s . c om int counterMandatoryFields = 0; DataField dataField; StringBuilder result = new StringBuilder(); String token; int offset; int length; Field field; String pattern; // Iterate through the list of positions // defined in the @DataField // and grab the data from the line Collection c = dataFields.values(); Iterator itr = c.iterator(); while (itr.hasNext()) { dataField = (DataField) itr.next(); offset = dataField.pos(); length = dataField.length(); ObjectHelper.notNull(offset, "Position/offset is not defined for the field: " + dataField.toString()); ObjectHelper.notNull(offset, "Length is not defined for the field: " + dataField.toString()); if (offset - 1 <= -1) { throw new IllegalArgumentException( "Offset/Position of the field " + dataField.toString() + " cannot be negative!"); } token = record.substring(offset - 1, offset + length - 1); if (dataField.trim()) { token = token.trim(); } // Check mandatory field if (dataField.required()) { // Increment counter of mandatory fields ++counterMandatoryFields; // Check if content of the field is empty // This is not possible for mandatory fields if (token.equals("")) { throw new IllegalArgumentException("The mandatory field defined at the position " + pos + " is empty for the line: " + line); } } // Get Field to be setted field = annotatedFields.get(offset); field.setAccessible(true); if (LOG.isDebugEnabled()) { LOG.debug("Pos/Offset: " + offset + ", Data: " + token + ", Field type: " + field.getType()); } Format<?> format; // Get pattern defined for the field pattern = dataField.pattern(); // Create format object to format the field format = FormatFactory.getFormat(field.getType(), pattern, getLocale(), dataField.precision()); // field object to be set Object modelField = model.get(field.getDeclaringClass().getName()); // format the data received Object value = null; if (!token.equals("")) { try { value = format.parse(token); } catch (FormatException ie) { throw new IllegalArgumentException( ie.getMessage() + ", position: " + offset + ", line: " + line, ie); } catch (Exception e) { throw new IllegalArgumentException( "Parsing error detected for field defined at the position/offset: " + offset + ", line: " + line, e); } } else { value = getDefaultValueForPrimitive(field.getType()); } field.set(modelField, value); ++pos; } if (LOG.isDebugEnabled()) { LOG.debug("Counter mandatory fields: " + counterMandatoryFields); } if (pos < totalFields) { throw new IllegalArgumentException("Some fields are missing (optional or mandatory), line: " + line); } if (counterMandatoryFields < numberMandatoryFields) { throw new IllegalArgumentException("Some mandatory fields are missing, line: " + line); } }
From source file:org.kuali.kra.award.AwardTemplateSyncServiceImpl.java
/** * This method /* w w w . j a v a 2s .c om*/ * * @param awardTemplateObject * @param awardObject */ protected boolean syncTargetCheck(Object awardTemplateObject, Object awardObject, AwardTemplateSyncScope[] scopes, java.util.Stack<AwardTemplateSyncScope[]> scopeStack, Award award, AwardTemplate awardTemplate) throws Exception { List<Field> allFields = new ArrayList<Field>(); findAllFields(awardObject.getClass(), allFields); boolean result = false; AwardTemplateSyncScope[] effectiveScopes; for (Field field : allFields) { try { if (field.isAnnotationPresent(AwardSyncable.class)) { scopeStack.push(field.getAnnotation(AwardSyncable.class).scopes()); effectiveScopes = getEffectiveScope(scopeStack); if (AwardTemplateSyncScope.isInScope(effectiveScopes, scopes)) { result = checkTargetField(awardTemplateObject, awardObject, field, scopeStack, award, awardTemplate); } else { //not in scope. } scopeStack.pop(); } else if (field.isAnnotationPresent(AwardSyncableList.class)) { scopeStack.push(field.getAnnotation(AwardSyncableList.class).scopes()); effectiveScopes = getEffectiveScope(scopeStack); if (AwardTemplateSyncScope.isInScope(effectiveScopes, scopes)) { result = checkTargetList(awardTemplateObject, awardObject, field, scopes, scopeStack, award, awardTemplate); } else { if (LOG.isDebugEnabled()) LOG.debug(String.format("Skipped (not in scope(s) %s) list:%s.%s", ArrayUtils.toString(scopes), awardObject.getClass().toString(), field.getName())); } scopeStack.pop(); } else { if (LOG.isTraceEnabled()) { LOG.trace(String.format("Skipped (No Annotation):%s.%s", awardObject.getClass().toString(), field.getName())); } } if (result) break; } catch (IllegalStateException ise) { throw new RuntimeException(String.format("IllegalStateException while processing %s.%s", field.getDeclaringClass(), field.getName()), ise); } } return result; }
From source file:org.kuali.kra.award.AwardTemplateSyncServiceImpl.java
/** * This method //from w w w. j av a 2 s . c o m * * @param awardTemplateObject * @param awardObject */ protected boolean syncSourceCheck(Object awardTemplateObject, Object awardObject, AwardTemplateSyncScope[] scopes, java.util.Stack<AwardTemplateSyncScope[]> scopeStack, Award award, AwardTemplate awardTemplate) throws Exception { List<Field> allFields = new ArrayList<Field>(); findAllFields(awardObject.getClass(), allFields); boolean result = false; AwardTemplateSyncScope[] effectiveScopes; for (Field field : allFields) { try { if (field.isAnnotationPresent(AwardSyncable.class)) { scopeStack.push(field.getAnnotation(AwardSyncable.class).scopes()); effectiveScopes = getEffectiveScope(scopeStack); if (AwardTemplateSyncScope.isInScope(effectiveScopes, scopes)) { result = checkSourceField(awardTemplateObject, awardObject, field, scopeStack, award, awardTemplate); } else { //not in scope. } scopeStack.pop(); } else if (field.isAnnotationPresent(AwardSyncableList.class)) { scopeStack.push(field.getAnnotation(AwardSyncableList.class).scopes()); effectiveScopes = getEffectiveScope(scopeStack); if (AwardTemplateSyncScope.isInScope(effectiveScopes, scopes)) { result = checkSourceList(awardTemplateObject, awardObject, field, scopes, scopeStack, award, awardTemplate); } else { if (LOG.isDebugEnabled()) LOG.debug(String.format("Skipped (not in scope(s) %s) list:%s.%s", ArrayUtils.toString(scopes), awardObject.getClass().toString(), field.getName())); } scopeStack.pop(); } else { if (LOG.isTraceEnabled()) { LOG.trace(String.format("Skipped (No Annotation):%s.%s", awardObject.getClass().toString(), field.getName())); } } if (result) break; } catch (IllegalStateException ise) { throw new RuntimeException(String.format("IllegalStateException while processing %s.%s", field.getDeclaringClass(), field.getName()), ise); } } return result; }
From source file:org.projectforge.business.gantt.GanttChartDao.java
/** * Ignores all field values in output which are equal to the values of the corresponding task. */// ww w .j a v a2s. co m private XmlObjectWriter getXmlGanttObjectWriter() { final XmlObjectWriter xmlGanttObjectWriter = new XmlObjectWriter() { @Override protected boolean ignoreField(final Object obj, final Field field) { if (super.ignoreField(obj, field) == true) { return true; } if (obj instanceof GanttTask) { final TaskTree taskTree = taskDao.getTaskTree(); final String fieldName = field.getName(); if ("id".equals(fieldName) == true) { // Id should always be equals and needed in output for the identification of the gantt object. return false; } if ("description".equals(fieldName) == true) { return true; } final GanttTask ganttObject = (GanttTask) obj; final TaskDO task = taskTree.getTaskById((Integer) ganttObject.getId()); if (task != null) { if ("predecessor".equals(field.getName()) == true) { // Predecessor unmodified? return NumberHelper.isEqual((Integer) ganttObject.getPredecessorId(), task.getGanttPredecessorId()); } String taskFieldname = fieldMapping.get(fieldName); if (taskFieldname == null) { taskFieldname = fieldName; } for (final Field taskField : taskFields) { if (taskFieldname.equals(taskField.getName()) == true) { final Object value = BeanHelper.getFieldValue(obj, field); final Object taskValue = BeanHelper.getFieldValue(task, taskField); if (value instanceof BigDecimal) { // Needed, because 10.0 is not equal to 10.000 (if scale is different). return NumberHelper.isEqual((BigDecimal) value, (BigDecimal) taskValue); } return ObjectUtils.equals(value, taskValue) == true; } } } } return false; } @Override protected void writeField(final Field field, final Object obj, final Object fieldValue, final XmlField annotation, final Element element) { if (GanttTask.class.isAssignableFrom(field.getDeclaringClass()) == true) { final String fieldName = field.getName(); if ("id".equals(fieldName) == false) { final TaskTree taskTree = taskDao.getTaskTree(); final GanttTask ganttObject = (GanttTask) obj; final TaskDO task = taskTree.getTaskById((Integer) ganttObject.getId()); if (task != null) { String taskFieldname = fieldMapping.get(fieldName); if (taskFieldname == null) { taskFieldname = fieldName; } for (final Field taskField : taskFields) { if (taskFieldname.equals(taskField.getName()) == true) { final Object value = BeanHelper.getFieldValue(obj, field); final Object taskValue = BeanHelper.getFieldValue(task, taskField); if (taskValue != null && value == null) { // Reader should interpret this as null, so value from task will be overwritten by null. element.addAttribute(field.getName(), XmlConstants.NULL_IDENTIFIER); return; } } } } } } super.writeField(field, obj, fieldValue, annotation, element); } }; xmlGanttObjectWriter.setAliasMap(getXmlGanttObjectAliasMap()); return xmlGanttObjectWriter; }
From source file:adalid.core.AbstractDataArtifact.java
private void annotateParentProperty(Field field) { // Class<?> declaringClass = getDeclaringEntity().getDataClass(); Class<?> declaringClass = field.getDeclaringClass(); Class<? extends Annotation> annotationClass = ParentProperty.class; Class<?>[] validTypes = new Class<?>[] { declaringClass }; boolean log = depth() == 1; boolean aye = field.isAnnotationPresent(annotationClass) && XS1.checkKeyPropertyFieldAnnotation(log, field, KeyProperty.PARENT, validTypes); /**//*w w w .jav a 2s.co m*/ if (aye) { Field previous = getDeclaringArtifact().put(annotationClass, field); if (previous == null) { _annotatedWithParentProperty = true; } else if (log) { XS1.logDuplicateAnnotation(field, annotationClass, previous); } } }
From source file:org.cruk.genologics.api.impl.GenologicsAPIImpl.java
/** * Reflectively set all the attributes in {@code original} to the values given * by {@code updated}. This has the effect of making {@code original} the * same as {@code updated} but without requiring the client code to change the * object reference to {@code original}, which may be referenced in many places. * * <p>/*from www. ja va2 s. co m*/ * Where a field is a Collection, the existing collection is emptied and all the * objects from that field in {@code updated} are added in the same order to the * collection in {@code original}. Whether this order is maintained depends on * the type of collection in {@code original} (a list will maintain order, a set * typically won't). * </p> * * <p> * Fields that are static, transient or final are ignored, as are any fields annotated * with the {@code @XmlTransient} annotation. * </p> * * <p> * Note that fields within the original object that are objects themselves (as opposed to * primitives) are replaced with the new versions. References to sub objects are therefore * no longer valid. * </p> * * @param original The original object that was provided in the call and needs updating. * @param updated The version of the object returned from the LIMS with the current state. * * @throws IllegalArgumentException if either {@code original} or {@code updated} * are null, or are of different classes. */ @SuppressWarnings({ "unchecked", "rawtypes" }) protected void reflectiveUpdate(Object original, Object updated) { if (original == null) { throw new IllegalArgumentException("original cannot be null"); } if (updated == null) { throw new IllegalArgumentException("updated cannot be null"); } if (!original.getClass().equals(updated.getClass())) { throw new IllegalArgumentException("original and updated are of different classes"); } Class<?> clazz = original.getClass(); do { Map<String, java.lang.reflect.Field> fieldMap = updaterFields.get(clazz); if (fieldMap == null) { fieldMap = Collections.synchronizedMap(new HashMap<String, java.lang.reflect.Field>()); updaterFields.put(clazz, fieldMap); Class<?> currentClass = clazz; while (!Object.class.equals(currentClass)) { for (java.lang.reflect.Field field : currentClass.getDeclaredFields()) { // Skip transient and XmlTransient fields. if ((field.getModifiers() & REFLECTIVE_UPDATE_MODIFIER_MASK) == 0 && field.getAnnotation(XmlTransient.class) == null) { field.setAccessible(true); java.lang.reflect.Field clash = fieldMap.put(field.getName(), field); if (clash != null) { throw new AssertionError("There is more than one field with the name '" + field.getName() + " in the class hierarchy of " + clazz.getName() + " (" + getShortClassName(field.getDeclaringClass()) + " and " + getShortClassName(clash.getDeclaringClass()) + ")"); } } } currentClass = currentClass.getSuperclass(); } } for (java.lang.reflect.Field field : fieldMap.values()) { try { Object originalValue = field.get(original); Object updatedValue = field.get(updated); if (Collection.class.isAssignableFrom(field.getDeclaringClass())) { Collection originalCollection = (Collection) originalValue; Collection updatedCollection = (Collection) updatedValue; if (originalCollection != null) { originalCollection.clear(); if (updatedCollection != null) { originalCollection.addAll(updatedCollection); } } else { if (updatedCollection != null) { // Getting as a property should create the collection object. originalCollection = (Collection) PropertyUtils.getProperty(original, field.getName()); originalCollection.addAll(updatedCollection); } } } else if (Map.class.isAssignableFrom(field.getDeclaringClass())) { throw new AssertionError("I didn't think we'd be dealing with maps: field " + field.getName() + " on class " + field.getDeclaringClass().getName()); } else { field.set(original, updatedValue); } } catch (IllegalAccessException e) { logger.error("Cannot access the property {} on the class {}", field.getName(), field.getDeclaringClass().getName()); fieldMap.remove(field.getName()); } catch (NoSuchMethodException e) { logger.error("There is no getter method for the property {} on the class {}", field.getName(), field.getDeclaringClass().getName()); fieldMap.remove(field.getName()); } catch (InvocationTargetException e) { logger.error("Error while getting collection property {}", field.getName(), e.getTargetException()); } catch (ClassCastException e) { logger.error("Cannot cast a {} to a Collection.", e.getMessage()); } } clazz = clazz.getSuperclass(); } while (!Object.class.equals(clazz)); }
From source file:com.github.helenusdriver.driver.impl.ClassInfoImpl.java
/** * Finds all final fields in this class and all super classes up to and * excluding the first class that is not annotated with the corresponding * entity annotation./*w w w . j ava 2 s.c o m*/ * * @author paouelle * * @return a non-<code>null</code> map of all final fields and their default * values */ private Map<Field, Object> findFinalFields() { final Map<Field, Object> ffields = new HashMap<>(8); MutableObject<Object> obj = null; // lazy evaluated // go up the hierarchy until we hit the class for which we have a default // serialization constructor as that class will have its final fields // properly initialized by the ctor whereas all others will have their final // fields initialized with 0, false, null, ... for (Class<? super T> clazz = this.clazz; clazz != constructor.getDeclaringClass(); clazz = clazz .getSuperclass()) { for (final Field field : clazz.getDeclaredFields()) { final int mods = field.getModifiers(); if (Modifier.isFinal(mods) && !Modifier.isStatic(mods)) { field.setAccessible(true); // so we can access its value directly if (obj == null) { // instantiates a dummy version and access its value try { // find default ctor even if private final Constructor<T> ctor = this.clazz.getDeclaredConstructor(); ctor.setAccessible(true); // in case it was private final T t = ctor.newInstance(); obj = new MutableObject<>(t); } catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) { throw new IllegalArgumentException( "unable to instantiate object: " + this.clazz.getName(), e); } catch (InvocationTargetException e) { final Throwable t = e.getTargetException(); if (t instanceof Error) { throw (Error) t; } else if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { // we don't expect any of those throw new IllegalArgumentException( "unable to instantiate object: " + this.clazz.getName(), t); } } } try { ffields.put(field, field.get(obj.getValue())); } catch (IllegalAccessException e) { throw new IllegalArgumentException("unable to access final value for field: " + field.getDeclaringClass().getName() + "." + field.getName(), e); } } } } return ffields; }