You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by kw...@apache.org on 2015/05/20 16:39:20 UTC

svn commit: r1680581 - in /sling/trunk/bundles/extensions/models: api/src/main/java/org/apache/sling/models/factory/ impl/src/main/java/org/apache/sling/models/impl/ impl/src/main/java/org/apache/sling/models/impl/validation/ impl/src/test/java/org/apa...

Author: kwin
Date: Wed May 20 14:39:19 2015
New Revision: 1680581

URL: http://svn.apache.org/r1680581
Log:
SLING-3709 improve exception handling by using dedicated exception classes instead of the one global result object

Added:
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementException.java
Modified:
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementsException.java
    sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/ModelClassException.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidation.java
    sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidationImpl.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/PostConstructTest.java
    sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java

Added: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementException.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementException.java?rev=1680581&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementException.java (added)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementException.java Wed May 20 14:39:19 2015
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.models.factory;
+
+import java.lang.reflect.AnnotatedElement;
+
+/**
+ * Exception which is used whenever one element (field, method or constructor) could not be set.
+ * @see MissingElementsException
+ */
+public class MissingElementException extends RuntimeException {
+
+    private static final long serialVersionUID = 5782291184414886658L;
+    private final AnnotatedElement element;
+
+    public MissingElementException(AnnotatedElement element, Throwable cause) {
+        super("Could not inject " + element, cause);
+        this.element = element;
+    }
+
+    public AnnotatedElement getElement() {
+        return element;
+    }
+
+}

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementsException.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementsException.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementsException.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/MissingElementsException.java Wed May 20 14:39:19 2015
@@ -18,13 +18,14 @@
  */
 package org.apache.sling.models.factory;
 
-import java.lang.reflect.AnnotatedElement;
+import java.util.ArrayList;
 import java.util.Collection;
 
 /**
  * Exception which is triggered whenever a Sling Model cannot be instantiated
- * due to some missing elements (i.e. required fields/methods/constructor params
+ * due to some missing elements (i.e. required fields/methods/constructor parameters
  * could not be injected).
+ * Contains a number of {@link MissingElementException}s.
  * 
  * @see ModelFactory
  *
@@ -32,29 +33,37 @@ import java.util.Collection;
 public final class MissingElementsException extends RuntimeException {
     private static final long serialVersionUID = 7870762030809272254L;
 
-    private final Collection<? extends AnnotatedElement> missingElements;
+    private Collection<MissingElementException> missingElements;
 
-    private String formatString;
-
-    private Class<?> type;
-
-    public MissingElementsException(String format, Collection<? extends AnnotatedElement> elements, Class<?> type) {
-        super();
-        this.formatString = format;
-        this.missingElements = elements;
-        this.type = type;
+    
+    public MissingElementsException(String message) {
+        super(message);
+        missingElements = new ArrayList<MissingElementException>();
     }
 
     @Override
     public String getMessage() {
-        return String.format(formatString, missingElements, type);
+        StringBuilder message = new StringBuilder(super.getMessage());
+        for (MissingElementException e : missingElements) {
+            message.append('\n');
+            message.append(e.getMessage());
+            if (e.getCause() != null) {
+                message.append(" caused by ");
+                message.append(e.getCause().getMessage());
+            }
+        }
+        return message.toString();
     }
 
-    public Class<?> getType() {
-        return type;
+    public void addMissingElementExceptions(MissingElementException e) {
+        missingElements.add(e);
     }
-
-    public Collection<? extends AnnotatedElement> getMissingElements() {
+    
+    public boolean isEmpty() {
+        return missingElements.isEmpty();
+    }
+    
+    public Collection<MissingElementException> getMissingElements() {
         return missingElements;
     }
 }

Modified: sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/ModelClassException.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/ModelClassException.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/ModelClassException.java (original)
+++ sling/trunk/bundles/extensions/models/api/src/main/java/org/apache/sling/models/factory/ModelClassException.java Wed May 20 14:39:19 2015
@@ -32,4 +32,8 @@ public final class ModelClassException e
     public ModelClassException(String message) {
         super(message);
     }
+    
+    public ModelClassException(String message, Throwable e) {
+        super(message, e);
+    }
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java Wed May 20 14:39:19 2015
@@ -45,6 +45,7 @@ import java.util.concurrent.ConcurrentMa
 import javax.annotation.PostConstruct;
 
 import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -65,10 +66,10 @@ import org.apache.sling.models.annotatio
 import org.apache.sling.models.factory.InvalidAdaptableException;
 import org.apache.sling.models.factory.InvalidResourceException;
 import org.apache.sling.models.factory.InvalidValidationModelException;
+import org.apache.sling.models.factory.MissingElementException;
 import org.apache.sling.models.factory.MissingElementsException;
 import org.apache.sling.models.factory.ModelClassException;
 import org.apache.sling.models.factory.ModelFactory;
-import org.apache.sling.models.impl.Result.FailureType;
 import org.apache.sling.models.impl.model.ConstructorParameter;
 import org.apache.sling.models.impl.model.InjectableElement;
 import org.apache.sling.models.impl.model.InjectableField;
@@ -182,8 +183,12 @@ public class ModelAdapterFactory impleme
 
     public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType> type) {
         Result<AdapterType> result = internalCreateModel(adaptable, type);
-        result.logFailures(log);
-        return result.getModel();
+        if (!result.wasSuccessfull()) {
+            log.error("Could not adapt to model", result.getThrowable());
+            return null;
+        } else {
+            return result.getValue();
+        }
     }
 
     @Override
@@ -196,19 +201,21 @@ public class ModelAdapterFactory impleme
             throw new IllegalArgumentException("Given type is null");
         }
         Result<ModelType> result = internalCreateModel(adaptable, type);
-        result.throwException(log);
-        return result.getModel();
+        if (!result.wasSuccessfull()) {
+            throw result.getThrowable();
+        }
+        return result.getValue();
     }
 
     @Override
     public boolean canCreateFromAdaptable(Object adaptable, Class<?> modelClass) throws ModelClassException {
-        return innerCanCreateFromAdaptable(adaptable, modelClass);
+        return internalCanCreateFromAdaptable(adaptable, modelClass);
     }
 
-    private boolean innerCanCreateFromAdaptable(Object adaptable, Class<?> requestedType) throws ModelClassException {
+    private boolean internalCanCreateFromAdaptable(Object adaptable, Class<?> requestedType) throws ModelClassException {
         ModelClass<?> modelClass = getImplementationTypeForAdapterType(requestedType, adaptable);
         if (!modelClass.hasModelAnnotation()) {
-            throw new ModelClassException(String.format("Model class '%s' does not have a model annotation", modelClass));
+            throw new ModelClassException(String.format("Model class '%s' does not have a model annotation", modelClass.getType()));
         }
 
         Class<?>[] declaredAdaptable = modelClass.getModelAnnotation().adaptables();
@@ -250,13 +257,12 @@ public class ModelAdapterFactory impleme
 
     @SuppressWarnings("unchecked")
     private <ModelType> Result<ModelType> internalCreateModel(Object adaptable, Class<ModelType> requestedType) {
-        Result<ModelType> result = new Result<ModelType>();
+        Result<ModelType> result;
         ThreadInvocationCounter threadInvocationCounter = invocationCountThreadLocal.get();
         if (threadInvocationCounter.isMaximumReached()) {
             String msg = String.format("Adapting %s to %s failed, too much recursive invocations (>=%s).",
                     new Object[] { adaptable, requestedType, threadInvocationCounter.maxRecursionDepth });
-            result.addFailure(FailureType.OTHER, msg);
-            return result;
+            return new Result<ModelType>(new ModelClassException(msg));
         };
         threadInvocationCounter.increase();
         try {
@@ -264,8 +270,8 @@ public class ModelAdapterFactory impleme
             ModelClass<ModelType> modelClass = getImplementationTypeForAdapterType(requestedType, adaptable);
 
             if (!modelClass.hasModelAnnotation()) {
-                result.addFailure(FailureType.NO_MODEL_ANNOTATION, modelClass.getType());
-                return result;
+                String msg = String.format("Provided Adapter class does not have a Model annotation: %s", modelClass.getType());
+                return new Result<ModelType>(new ModelClassException(msg));
             }
             boolean isAdaptable = false;
 
@@ -277,24 +283,27 @@ public class ModelAdapterFactory impleme
                 }
             }
             if (!isAdaptable) {
-                result.addFailure(FailureType.ADAPTABLE_DOES_NOT_MATCH, modelClass.getType());
+            	String msg = String.format("Adaptables (%s) are not acceptable for the model class: %s", StringUtils.join(declaredAdaptable), modelClass.getType());
+            	return new Result<ModelType>(new InvalidAdaptableException(msg)); 
             } else {
-                if (!validateModel(modelAnnotation, adaptable, result)) {
-                    return result;
+                RuntimeException t = validateModel(modelAnnotation, adaptable);
+                if (t != null) {
+                    return new Result<ModelType>(t);
                 }
                 if (modelClass.getType().isInterface()) {
-                    InvocationHandler handler = createInvocationHandler(adaptable, modelClass, result);
-                    if (handler != null) {
-                        ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handler);
-                        result.setModel(model);
+                    Result<InvocationHandler> handlerResult = createInvocationHandler(adaptable, modelClass);
+                    if (handlerResult.wasSuccessfull()) {
+                        ModelType model = (ModelType) Proxy.newProxyInstance(modelClass.getType().getClassLoader(), new Class<?>[] { modelClass.getType() }, handlerResult.getValue());
+                        result = new Result<ModelType>(model);
+                    } else {
+                        return new Result<ModelType>(handlerResult.getThrowable());
                     }
                 } else {
                     try {
-                        ModelType model = createObject(adaptable, modelClass, result);
-                        result.setModel(model);
-                        return result;
+                        result = createObject(adaptable, modelClass);
                     } catch (Exception e) {
-                        result.addFailure(FailureType.OTHER, "Unable to create object", e);
+                        String msg = String.format("Unable to create model %s", modelClass.getType());
+                        return new Result<ModelType>(new ModelClassException(msg, e));
                     }
                 }
             }
@@ -304,11 +313,10 @@ public class ModelAdapterFactory impleme
         }
     }
     
-    private <ModelType> boolean validateModel(Model modelAnnotation, Object adaptable, Result<ModelType> result) {
+    private RuntimeException validateModel(Model modelAnnotation, Object adaptable) {
         if (modelAnnotation.validation() != ValidationStrategy.DISABLED) {
             if (modelValidation == null) {
-                result.addFailure(FailureType.VALIDATION_NOT_AVAILABLE);
-                return false;
+                return new ModelClassException("Sling Validation Bundle is not there, therefore no validation can be performed.");
             }
             Resource resource = null;
             if (adaptable instanceof SlingHttpServletRequest) {
@@ -317,15 +325,12 @@ public class ModelAdapterFactory impleme
                 resource = (Resource)adaptable;
             }
             if (resource != null) {
-                if (!modelValidation.validate(resource, modelAnnotation.validation() == ValidationStrategy.REQUIRED, result)) {
-                    return false;
-                }
+                return modelValidation.validate(resource, modelAnnotation.validation() == ValidationStrategy.REQUIRED);
             } else {
-                result.addFailureWithParameters(FailureType.ADAPTABLE_NOT_USABLE_FOR_VALIDATION, adaptable.getClass().getName());
-                return false;
+                return new ModelClassException("Sling Validation can only be performed if model is adaptable from either SlingHttpServletRequest or Resource.");
             }
         }
-        return true;
+        return null;
     }
 
     private static interface InjectCallback {
@@ -333,10 +338,9 @@ public class ModelAdapterFactory impleme
          * Is called each time when the given value should be injected into the given element
          * @param element
          * @param value
-         * @param result
-         * @return true if injection was successful otherwise false
+         * @return an InjectionResult
          */
-        public boolean inject(InjectableElement element, Object value, Result<?> result);
+        public RuntimeException inject(InjectableElement element, Object value);
     }
 
     private class SetFieldCallback implements InjectCallback {
@@ -348,8 +352,8 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(InjectableElement element, Object value, Result<?> result) {
-            return setField((InjectableField) element, object, value, result);
+        public RuntimeException inject(InjectableElement element, Object value) {
+            return setField((InjectableField) element, object, value);
         }
     }
 
@@ -362,8 +366,8 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(InjectableElement element, Object value, Result<?> result) {
-            return setMethod((InjectableMethod) element, methods, value, result);
+        public RuntimeException inject(InjectableElement element, Object value) {
+            return setMethod((InjectableMethod) element, methods, value);
         }
     }
 
@@ -376,14 +380,14 @@ public class ModelAdapterFactory impleme
         }
 
         @Override
-        public boolean inject(InjectableElement element, Object value, Result<?> result) {
-            return setConstructorParameter((ConstructorParameter)element, parameterValues, value, result);
+        public RuntimeException inject(InjectableElement element, Object value) {
+            return setConstructorParameter((ConstructorParameter)element, parameterValues, value);
         }
     }
 
-    private boolean injectElement(final InjectableElement element, final Object adaptable, 
+    private RuntimeException injectElement(final InjectableElement element, final Object adaptable, 
             final Model modelAnnotation, final DisposalCallbackRegistry registry,
-            final InjectCallback callback, Result<?> result) {
+            final InjectCallback callback) {
 
         InjectAnnotationProcessor annotationProcessor = null;
         String source = element.getSource();
@@ -408,15 +412,19 @@ public class ModelAdapterFactory impleme
         String name = getName(element, annotationProcessor);
         Object injectionAdaptable = getAdaptable(adaptable, element, annotationProcessor);
 
+        RuntimeException lastInjectionException = null;
         if (injectionAdaptable != null) {
             // find the right injector
             for (Injector injector : sortedInjectors) {
                 if (source == null || source.equals(injector.getName())) {
                     if (name != null || injector instanceof AcceptsNullName) {
                         Object value = injector.getValue(injectionAdaptable, name, element.getType(), element.getAnnotatedElement(), registry);
-                        if (callback.inject(element, value, result)) {
-                            wasInjectionSuccessful = true;
-                            break;
+                        if (value != null) {
+                            lastInjectionException = callback.inject(element, value);
+                            if (lastInjectionException == null) {
+                                wasInjectionSuccessful = true;
+                                break;
+                            }
                         }
                     }
                 }
@@ -424,24 +432,39 @@ public class ModelAdapterFactory impleme
         }
         // if injection failed, use default
         if (!wasInjectionSuccessful) {
-            wasInjectionSuccessful = injectDefaultValue(element, annotationProcessor, callback, result);
+            Result<Boolean> defaultInjectionResult = injectDefaultValue(element, annotationProcessor, callback);
+            if (defaultInjectionResult.wasSuccessfull()) {
+                // log previous injection error, if there was any
+                if (lastInjectionException != null) {
+                    log.warn("Although falling back to default value worked, injection into {} failed because of: " + lastInjectionException.getMessage(), element.getAnnotatedElement(), lastInjectionException);
+                }
+                wasInjectionSuccessful = defaultInjectionResult.getValue();
+            } else {
+                return defaultInjectionResult.getThrowable();
+            }
         }
 
         // if default is not set, check if mandatory
         if (!wasInjectionSuccessful) {
             if (element.isOptional(annotationProcessor)) {
                 if (element.isPrimitive()) {
-                    injectPrimitiveInitialValue(element, callback, result);
+                    RuntimeException throwable = injectPrimitiveInitialValue(element, callback);
+                    if (throwable != null) {
+                        return throwable;
+                    }
                 }
             } else {
-                return false;
+                if (lastInjectionException != null) {
+                    return lastInjectionException;
+                } else {
+                    return new ModelClassException("No injector returned a non-null value!");
+                }
             }
         }
-        
-        return true;
+        return null;
     }
 
-    private <ModelType> InvocationHandler createInvocationHandler(final Object adaptable, final ModelClass<ModelType> modelClass, final Result<ModelType> result) {
+    private <ModelType> Result<InvocationHandler> createInvocationHandler(final Object adaptable, final ModelClass<ModelType> modelClass) {
         InjectableMethod[] injectableMethods = modelClass.getInjectableMethods();
         final Map<Method, Object> methods = new HashMap<Method, Object>();
         SetMethodsCallback callback = new SetMethodsCallback(methods);
@@ -449,19 +472,19 @@ public class ModelAdapterFactory impleme
 
         DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
         registerCallbackRegistry(handler, registry);
-        Set<Method> requiredMethods = new HashSet<Method>();
 
+        MissingElementsException missingElements = new MissingElementsException("Could not create all mandatory methods for interface of model " + modelClass);
         for (InjectableMethod method : injectableMethods) {
-            if (!injectElement(method, adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
-                requiredMethods.add(method.getMethod());
+            RuntimeException t = injectElement(method, adaptable, modelClass.getModelAnnotation(), registry, callback);
+            if (t != null) {
+                missingElements.addMissingElementExceptions(new MissingElementException(method.getAnnotatedElement(), t));
             }
         }
         registry.seal();
-        if (!requiredMethods.isEmpty()) {
-            result.addFailure(FailureType.MISSING_METHODS, requiredMethods, modelClass.getType());
-            return null;
+        if (!missingElements.isEmpty()) {
+            return new Result<InvocationHandler>(missingElements);
         }
-        return handler;
+        return new Result<InvocationHandler>(handler);
     }
 
     private void registerCallbackRegistry(Object object, DisposalCallbackRegistryImpl registry) {
@@ -469,14 +492,13 @@ public class ModelAdapterFactory impleme
         disposalCallbacks.put(reference, registry);
     }
 
-    private <ModelType> ModelType createObject(final Object adaptable, final ModelClass<ModelType> modelClass, final Result<ModelType> result)
+    private <ModelType> Result<ModelType> createObject(final Object adaptable, final ModelClass<ModelType> modelClass)
             throws InstantiationException, InvocationTargetException, IllegalAccessException {
         DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
 
         ModelClassConstructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, modelClass);
         if (constructorToUse == null) {
-            result.addFailure(FailureType.NO_USABLE_CONSTRUCTOR, modelClass.getType());
-            return null;
+            return new Result<ModelType>(new ModelClassException("Unable to find a useable constructor for model " + modelClass.getType()));
         }
 
         final ModelType object;
@@ -487,10 +509,12 @@ public class ModelAdapterFactory impleme
             // instantiate with constructor injection
             // if this fails, make sure resources that may be claimed by injectors are cleared up again
             try {
-                object = newInstanceWithConstructorInjection(constructorToUse, adaptable, modelClass, registry, result);
-                if (object == null) {
+                Result<ModelType> result = newInstanceWithConstructorInjection(constructorToUse, adaptable, modelClass, registry);
+                if (!result.wasSuccessfull()) {
                     registry.onDisposed();
-                    return null;
+                    return result;
+                } else {
+                    object = result.getValue();
                 }
             } catch (InstantiationException ex) {
                 registry.onDisposed();
@@ -508,31 +532,27 @@ public class ModelAdapterFactory impleme
 
         InjectCallback callback = new SetFieldCallback(object);
 
-        Set<Field> requiredFields = new HashSet<Field>();
-
         InjectableField[] injectableFields = modelClass.getInjectableFields();
+        MissingElementsException missingElements = new MissingElementsException("Could not inject all required fields into " + modelClass.getType());
         for (InjectableField field : injectableFields) {
-            if (!injectElement(field, adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
-                requiredFields.add(field.getField());
+            RuntimeException t = injectElement(field, adaptable, modelClass.getModelAnnotation(), registry, callback);
+            if (t != null) {
+                missingElements.addMissingElementExceptions(new MissingElementException(field.getAnnotatedElement(), t));
             }
         }
 
         registry.seal();
-        if (!requiredFields.isEmpty()) {
-            result.addFailure(FailureType.MISSING_FIELDS, requiredFields, modelClass.getType());
-            return null;
+        if (!missingElements.isEmpty()) {
+            return new Result<ModelType>(missingElements);
         }
         try {
             invokePostConstruct(object);
-            return object;
         } catch (InvocationTargetException e) {
-            result.addFailure(FailureType.FAILED_CALLING_POST_CONSTRUCT, e.getCause());
-            return null;
+            return new Result<ModelType>(new ModelClassException("Post-construct method has thrown an exception for model " + modelClass.getType(), e));
         } catch (IllegalAccessException e) {
-            result.addFailure(FailureType.FAILED_CALLING_POST_CONSTRUCT, e);
-            return null;
+            new Result<ModelType>(new ModelClassException("Could not call post-construct method for model " + modelClass.getType(), e));
         }
-
+        return new Result<ModelType>(object);
     }
 
     /**
@@ -543,9 +563,9 @@ public class ModelAdapterFactory impleme
      */
     @SuppressWarnings("unchecked")
     private <ModelType> ModelClassConstructor<ModelType> getBestMatchingConstructor(Object adaptable, ModelClass<ModelType> type) {
-        ModelClassConstructor[] constructors = type.getConstructors();
+        ModelClassConstructor<ModelType>[] constructors = type.getConstructors();
 
-        for (ModelClassConstructor constructor : constructors) {
+        for (ModelClassConstructor<ModelType> constructor : constructors) {
             // first try to find the constructor with most parameters and @Inject annotation
             if (constructor.hasInjectAnnotation()) {
                 return constructor;
@@ -567,42 +587,51 @@ public class ModelAdapterFactory impleme
         return null;
     }
 
-    private <ModelType> ModelType newInstanceWithConstructorInjection(final ModelClassConstructor<ModelType> constructor, final Object adaptable,
-            final ModelClass<ModelType> modelClass, final DisposalCallbackRegistry registry, final Result<ModelType> result)
+    private <ModelType> Result<ModelType> newInstanceWithConstructorInjection(final ModelClassConstructor<ModelType> constructor, final Object adaptable,
+            final ModelClass<ModelType> modelClass, final DisposalCallbackRegistry registry)
             throws InstantiationException, InvocationTargetException, IllegalAccessException {
         ConstructorParameter[] parameters = constructor.getConstructorParameters();
 
-        Set<AnnotatedElement> requiredParameters = new HashSet<AnnotatedElement>();
         List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameters.length]));
         InjectCallback callback = new SetConstructorParameterCallback(paramValues);
 
+        MissingElementsException missingElements = new MissingElementsException("Required constructor parameters were not able to be injected on model " + modelClass.getType());
         for (int i = 0; i < parameters.length; i++) {
-            if (!injectElement(parameters[i], adaptable, modelClass.getModelAnnotation(), registry, callback, result)) {
-                requiredParameters.add(parameters[i].getAnnotatedElement());
+            RuntimeException t = injectElement(parameters[i], adaptable, modelClass.getModelAnnotation(), registry, callback);
+            if (t != null) {
+                missingElements.addMissingElementExceptions(new MissingElementException(parameters[i].getAnnotatedElement(), t));
             }
         }
-        if (!requiredParameters.isEmpty()) {
-            result.addFailure(FailureType.MISSING_CONSTRUCTOR_PARAMS, requiredParameters, modelClass.getType());
-            return null;
+        if (!missingElements.isEmpty()) {
+            return new Result<ModelType>(missingElements);
         }
-        return constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()]));
+        return new Result<ModelType>(constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()])));
     }
 
-    private boolean injectDefaultValue(InjectableElement point, InjectAnnotationProcessor processor,
-            InjectCallback callback, Result<?> result) {
-
+    private Result<Boolean> injectDefaultValue(InjectableElement point, InjectAnnotationProcessor processor,
+            InjectCallback callback) {
         if (processor != null) {
             if (processor.hasDefault()) {
-                return callback.inject(point, processor.getDefault(), result);
+                RuntimeException t = callback.inject(point, processor.getDefault());
+                if (t == null) {
+                    return new Result<Boolean>(Boolean.TRUE);
+                } else {
+                    return new Result<Boolean>(t);
+                }
             }
         }
 
         Object value = point.getDefaultValue();
         if (value != null) {
-            return callback.inject(point, value, result);
+            RuntimeException t = callback.inject(point, value);
+            if (t == null) {
+                return new Result<Boolean>(Boolean.TRUE);
+            } else {
+                return new Result<Boolean>(t);
+            }
         }
         else {
-            return false;
+            return new Result<Boolean>(Boolean.FALSE);
         }
     }
 
@@ -615,7 +644,7 @@ public class ModelAdapterFactory impleme
      * @param callback Inject callback
      * @param result
      */
-    private void injectPrimitiveInitialValue(InjectableElement point, InjectCallback callback, Result<?> result) {
+    private RuntimeException injectPrimitiveInitialValue(InjectableElement point, InjectCallback callback) {
         Type primitiveType = ReflectionUtil.mapWrapperClasses(point.getType());
         Object value = null;
         if (primitiveType == int.class) {
@@ -636,8 +665,10 @@ public class ModelAdapterFactory impleme
             value = Character.valueOf('\u0000');
         }
         if (value != null) {
-            callback.inject(point, value, result);
-        };
+            return callback.inject(point, value);
+        } else {
+            return new ModelClassException(String.format("Unknown primitive type %s", primitiveType.toString()));
+        }
     }
     
     private Object getAdaptable(Object adaptable, InjectableElement point, InjectAnnotationProcessor processor) {
@@ -711,76 +742,70 @@ public class ModelAdapterFactory impleme
         }
     }
 
-    private boolean setField(InjectableField injectableField, Object createdObject, Object value, Result<?> result) {
-        if (value != null) {
-            Field field = injectableField.getField();
-            value = adaptIfNecessary(value, field.getType(), field.getGenericType(), result);
-            // value may now be null due to the adaptation done above
-            if (value == null) {
-                return false;
-            }
+    private RuntimeException setField(InjectableField injectableField, Object createdObject, Object value) {
+        Field field = injectableField.getField();
+        Result<Object> result = adaptIfNecessary(value, field.getType(), field.getGenericType());
+        if (result.wasSuccessfull()) {
             boolean accessible = field.isAccessible();
             try {
                 if (!accessible) {
                     field.setAccessible(true);
                 }
-                field.set(createdObject, value);
-                return true;
+                field.set(createdObject, result.getValue());
             } catch (Exception e) {
-                log.error("unable to inject field", e);
-                return false;
+                return new ModelClassException("Could not inject field due to reflection issues", e);
             } finally {
                 if (!accessible) {
                     field.setAccessible(false);
                 }
             }
+            return null;
         } else {
-            return false;
+            return result.getThrowable();
         }
     }
 
-    private boolean setMethod(InjectableMethod injectableMethod, Map<Method, Object> methods, Object value, Result<?> result) {
-        if (value != null) {
-            Method method = injectableMethod.getMethod();
-            value = adaptIfNecessary(value, method.getReturnType(), method.getGenericReturnType(), result);
-            // value may now be null due to the adaptation done above
-            if (value == null) {
-                return false;
-            }
-            methods.put(method, value);
-            return true;
+    private RuntimeException setMethod(InjectableMethod injectableMethod, Map<Method, Object> methods, Object value) {
+        Method method = injectableMethod.getMethod();
+        Result<Object> result = adaptIfNecessary(value, method.getReturnType(), method.getGenericReturnType());
+        if (result.wasSuccessfull()) {
+            methods.put(method, result.getValue());
+            return null;
         } else {
-            return false;
+            return result.getThrowable();
         }
     }
 
-    private boolean setConstructorParameter(ConstructorParameter constructorParameter, List<Object> parameterValues, Object value, Result<?> result) {
-        if (value != null && constructorParameter.getParameterType() instanceof Class<?>) {
-            value = adaptIfNecessary(value, (Class<?>) constructorParameter.getParameterType(), constructorParameter.getGenericType(), result);
-            // value may now be null due to the adaptation done above
-            if (value == null) {
-                return false;
+    private RuntimeException setConstructorParameter(ConstructorParameter constructorParameter, List<Object> parameterValues, Object value) {
+        if (constructorParameter.getParameterType() instanceof Class<?>) {
+            Result<Object> result = adaptIfNecessary(value, (Class<?>) constructorParameter.getParameterType(), constructorParameter.getGenericType());
+            if (result.wasSuccessfull() ) {
+                parameterValues.set(constructorParameter.getParameterIndex(), result.getValue());
+                return null;
+            } else {
+                return result.getThrowable();
             }
-            parameterValues.set(constructorParameter.getParameterIndex(), value);
-            return true;
         } else {
-            return false;
+            return new ModelClassException(String.format("Constructor parameter with index %d is not a class!", constructorParameter.getParameterIndex()));
         }
     }
 
-    private Object adaptIfNecessary(Object value, Class<?> type, Type genericType, Result<?> parentResult) {
+    private Result<Object> adaptIfNecessary(final Object value, final Class<?> type, final Type genericType) {
+        final Object adaptedValue;
         if (!isAcceptableType(type, genericType, value)) {
             Class<?> declaredType = type;
             if (isModelClass(value, type) && canCreateFromAdaptable(value, type)) {
                 Result<?> result = internalCreateModel(value, type);
-                if (result.getModel() == null) {
-                    parentResult.appendFailures(result);
-                    value = null;
+                if (result.wasSuccessfull()) {
+                    adaptedValue = result.getValue();
                 } else {
-                    value = result.getModel();
+                    return new Result<Object>(new ModelClassException(String.format("Could not create model from %s: %s", value.getClass(), result.getThrowable().getMessage()), result.getThrowable()));
                 }
             } else if (value instanceof Adaptable) {
-                value = ((Adaptable) value).adaptTo(type);
+                adaptedValue = ((Adaptable) value).adaptTo(type);
+                if (adaptedValue == null) {
+                    return new Result<Object>(new ModelClassException(String.format("Could not adapt from %s to %s", value.getClass(), type)));
+                } 
             } else if (genericType instanceof ParameterizedType) {
                 ParameterizedType parameterizedType = (ParameterizedType) genericType;
                 Class<?> collectionType = (Class<?>) declaredType;
@@ -793,14 +818,22 @@ public class ModelAdapterFactory impleme
                             Object adapted = ((Adaptable) valueObject).adaptTo((Class<?>) parameterizedType.getActualTypeArguments()[0]);
                             if (adapted != null) {
                                 result.add(adapted);
+                            } else {
+                                return new Result<Object>(new ModelClassException(String.format("Could not adapt from %s to %s within the collection", value.getClass(), type)));
                             }
                         }
                     }
-                    value = result;
+                    adaptedValue = result;
+                } else {
+                    return new Result<Object>(new ModelClassException(String.format("%s is neither a parametererized Collection or List", collectionType)));
                 }
+            } else {
+                return new Result<Object>(new ModelClassException(String.format("Could not adapt from %s to %s, because this class is not adaptable!", value.getClass(), type)));
             }
+            return new Result<Object>(adaptedValue);
+        } else {
+            return new Result<Object>(value);
         }
-        return value;
     }
 
     private static boolean isAcceptableType(Class<?> type, Type genericType, Object value) {

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/Result.java Wed May 20 14:39:19 2015
@@ -18,204 +18,71 @@
  */
 package org.apache.sling.models.impl;
 
-import java.lang.reflect.AnnotatedElement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.sling.models.factory.InvalidAdaptableException;
-import org.apache.sling.models.factory.ModelClassException;
-import org.apache.sling.models.factory.MissingElementsException;
-import org.slf4j.Logger;
-
-public class Result<ModelType> {
-
-    public enum FailureType {
-        ADAPTABLE_DOES_NOT_MATCH("Adaptable is not acceptable for the model class: %s"),
-        FAILED_CALLING_POST_CONSTRUCT("Failure calling post-construct method"),
-        NO_MODEL_ANNOTATION("Provided Adapter class does not have a Model annotation: %s"),
-        NO_USABLE_CONSTRUCTOR("Unable to find a useable constructor: %s"),
-        OTHER("Unclassified problem: %s"),
-        MISSING_METHODS("Required methods %s on model %s were not able to be injected."),
-        MISSING_FIELDS("Required fields %s on model %s were not able to be injected."),
-        MISSING_CONSTRUCTOR_PARAMS("Required constructor parameters %s on model %s were not able to be injected."), 
-        ADAPTABLE_NOT_USABLE_FOR_VALIDATION("Can not call Sling Validation in case the adaptable is neiter SlingHttpServletRequest or Resource (adaptable is'%s')"),
-        VALIDATION_NOT_AVAILABLE("Sling Validation Bundle is not there, therefore no validation can be performed."),
-        VALIDATION_MODEL_NOT_FOUND("Sling Validation model could not be found"),
-        VALIDATION_MODEL_INVALID("Sling Validation model is invalid"),
-        VALIDATION_RESULT_RESOURCE_INVALID("Model is invalid according to Sling Validation");
-
-        private String message;
-
-        private FailureType(String msg) {
-            this.message = msg;
-        }
-    }
-    
-    private static class Failure {
-        private FailureType failureType;
-
-        private Throwable failureException;
-
-        private String failureMessage;
-
-        private Set<? extends AnnotatedElement> missingElements;
-
-        private Class<?> clazz;
-
-        private String getMessage() {
-            if (failureMessage != null) {
-                return failureMessage;
-            } else if (failureType != null) {
-                return failureType.message;
-            } else {
-                return null;
-            }
-        }
-
-        public void log(Logger log) {
-
-            if (failureType != null) {
-                switch (failureType) {
-                case MISSING_CONSTRUCTOR_PARAMS:
-                case MISSING_FIELDS:
-                case MISSING_METHODS:
-                    log.error(String.format(failureType.message, missingElements, clazz));
-                    break;
-                case ADAPTABLE_DOES_NOT_MATCH:
-                case NO_MODEL_ANNOTATION:
-                case NO_USABLE_CONSTRUCTOR:
-                    log.error(String.format(failureType.message, clazz));
-                    break;
-                case OTHER:
-                default:
-                    log.error(getMessage(), failureException);
-                    break;
-                }
-            }
-        }
-
-        public void throwException() {
-            RuntimeException e = null;
-            if (failureType != null) {
-                final String msg = getMessage();
-                switch (failureType) {
-                case ADAPTABLE_DOES_NOT_MATCH:
-                    e = new InvalidAdaptableException(msg);
-                    break;
-                case FAILED_CALLING_POST_CONSTRUCT:
-                case NO_MODEL_ANNOTATION:
-                case NO_USABLE_CONSTRUCTOR:
-                case VALIDATION_NOT_AVAILABLE:
-                case ADAPTABLE_NOT_USABLE_FOR_VALIDATION:
-                    e = new ModelClassException(msg);
-                    break;
-                case MISSING_CONSTRUCTOR_PARAMS:
-                case MISSING_FIELDS:
-                case MISSING_METHODS:
-                    e = new MissingElementsException(failureType.message, missingElements, clazz);
-                    break;
-                case VALIDATION_MODEL_NOT_FOUND:
-                case VALIDATION_RESULT_RESOURCE_INVALID:
-                case VALIDATION_MODEL_INVALID:
-                    throw (RuntimeException)failureException;
-                default:
-                    e = new RuntimeException(msg);
-                    break;
-                }
-            }
-            if (e != null) {
-                if (failureException != null) {
-                    e.initCause(failureException);
-                }
-                throw e;
-            }
-        }
-        
-    }
-
-    private ModelType model;
-    
-    private List<Failure> failures = new ArrayList<Failure>();
-
-    public ModelType getModel() {
-        return model;
-    }
-
-    public void logFailures(Logger log) {
-        for (Failure failure : failures) {
-            failure.log(log);
-        }
-    }
-    
-    public void addFailure(FailureType type) {
-        Failure f = new Failure();
-        f.failureType = type;
-        failures.add(f);
-    }
-
-    public void addFailure(FailureType type, Class<?> clazz) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.clazz = clazz;
-        failures.add(f);
-    }
-
-    public void addFailure(FailureType type, Throwable e) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.failureException = e;
-        failures.add(f);
-    }
-
-    public void addFailure(FailureType type, Set<? extends AnnotatedElement> requiredElements, Class<?> clazz) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.missingElements = requiredElements;
-        f.clazz = clazz;
-        failures.add(f);
-    }
-    
-    public void addFailureWithParameters(FailureType type, Object... parameters) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.failureMessage = String.format(type.message, parameters);
-        failures.add(f);
-    }
-
-    public void addFailure(FailureType type, String msg) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.failureMessage = msg;
-        failures.add(f);
-    }
-
-    public void addFailure(FailureType type, String msg, Throwable e) {
-        Failure f = new Failure();
-        f.failureType = type;
-        f.failureMessage = msg;
-        f.failureException = e;
-        failures.add(f);
-    }
-
-    public void setModel(ModelType model) {
-        this.model = model;
-    }
-
-    public void throwException(Logger log) {
-        // log all failures save the last if multiple failures exist
-        if (failures.size() > 1) {
-            for (int i = 0; i < failures.size() - 2; i++) {
-                failures.get(i).log(log);
-            }
-        }
-        // throw the last failure as exception
-        if (failures.size() >= 1) {
-            failures.get(failures.size() - 1).throwException();
-        }
+/**
+ * This class encapsulates a value of a generic class in case of success or the
+ * {@link RuntimeException}s in case of an error. It is used because the
+ * different instantiation methods for models don't all allow exceptions to be
+ * thrown. Also throwing and catching exceptions would decrease the runtime performance.
+ * Therefore this class is used to throw the exception only if necessary.
+ */
+public class Result<SuccessObjectType> {
+    private final RuntimeException t;
+    private final SuccessObjectType object;
+
+    /**
+     * instantiate with one throwable (i.e. failure)
+     * 
+     * @param throwable
+     */
+    public Result(RuntimeException throwable) {
+        this.t = throwable;
+        this.object = null;
+    }
+
+    /**
+     * instantate with a model (i.e. success)
+     * 
+     * @param model
+     */
+    public Result(SuccessObjectType object) {
+        this.object = object;
+        this.t = null;
+    }
+
+    /**
+     * 
+     * @return the encapsulated exception
+     * @throws IllegalStateException
+     *             in case this object does not represent a failure
+     */
+    public RuntimeException getThrowable() {
+        if (t == null) {
+            throw new IllegalStateException("No throwable available");
+        }
+        return t;
+    }
+
+    /**
+     * 
+     * @return the encapsulated success value
+     * @throws IllegalStateException
+     *             in case this object does not represent a success
+     */
+    public SuccessObjectType getValue() {
+        if (object == null) {
+            throw new IllegalStateException(
+                    "Success object is not set, but rather an exception is encapsulated: " + t.getMessage(), t);
+        }
+        return object;
+    }
+
+    /**
+     * 
+     * @return {@code true} in case this object represents a success, otherwise
+     *         {@code false}
+     */
+    public boolean wasSuccessfull() {
+        return object != null;
     }
 
-    public void appendFailures(Result<?> result) {
-        failures.addAll(result.failures);
-    }
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidation.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidation.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidation.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidation.java Wed May 20 14:39:19 2015
@@ -16,8 +16,9 @@
  */
 package org.apache.sling.models.impl.validation;
 
+import javax.annotation.Nonnull;
+
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.models.impl.Result;
 
 public interface ModelValidation {
 
@@ -25,8 +26,8 @@ public interface ModelValidation {
      * Calls the Sling Validation for the given resource.
      * @param resource
      * @param required if {@code true} validation fails even if no appropriate validation model could be found.
-     * @return {@code true} if validation was successful, otherwise {@code false}
+     * @return {@code null} if validation was successful, otherwise an exception
      */
-    public abstract <ModelType> boolean validate(Resource resource, boolean required, Result<ModelType> result);
+    public abstract RuntimeException validate(@Nonnull Resource resource, boolean required);
 
 }

Modified: sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidationImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidationImpl.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidationImpl.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/main/java/org/apache/sling/models/impl/validation/ModelValidationImpl.java Wed May 20 14:39:19 2015
@@ -22,8 +22,6 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.factory.InvalidResourceException;
 import org.apache.sling.models.factory.InvalidValidationModelException;
-import org.apache.sling.models.impl.Result;
-import org.apache.sling.models.impl.Result.FailureType;
 import org.apache.sling.validation.api.ValidationModel;
 import org.apache.sling.validation.api.ValidationResult;
 import org.apache.sling.validation.api.ValidationService;
@@ -41,14 +39,13 @@ public class ModelValidationImpl impleme
     private static final Logger log = LoggerFactory.getLogger(ModelValidationImpl.class);
     
     @Override
-    public <ModelType> boolean validate(Resource resource, boolean required, Result<ModelType> result) {
+    public RuntimeException validate(Resource resource, boolean required) {
         try {
             ValidationModel validationModel = validation.getValidationModel(resource);
             if (validationModel == null) {
                 String error = String.format("Could not find validation model for resource '%s' with type '%s'", resource.getPath(), resource.getResourceType());
                 if (required) {
-                    result.addFailure(FailureType.VALIDATION_MODEL_NOT_FOUND, new InvalidValidationModelException(error));
-                    return false;
+                    return new InvalidValidationModelException(error);
                 } else {
                     log.warn(error);
                 }
@@ -56,19 +53,17 @@ public class ModelValidationImpl impleme
                 try {
                     ValidationResult validationResult = validation.validate(resource, validationModel);
                     if (!validationResult.isValid()) {
-                        result.addFailure(FailureType.VALIDATION_RESULT_RESOURCE_INVALID, new InvalidResourceException(validationResult, resource.getPath()));
-                        return false;
+                        return new InvalidResourceException(validationResult, resource.getPath());
                     } 
                 } catch (SlingValidationException e) {
-                    result.addFailure(FailureType.VALIDATION_MODEL_INVALID, new InvalidValidationModelException(e));
-                    return false;
+                    return new InvalidValidationModelException(e);
                 }
             }
         } catch (IllegalStateException e) {
-            result.addFailure(FailureType.VALIDATION_MODEL_INVALID, new SlingValidationException(e.getMessage(), e));
+            return new InvalidValidationModelException(e);
         }
         
-        return true;
+        return null;
     }
 
     

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/PostConstructTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/PostConstructTest.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/PostConstructTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/PostConstructTest.java Wed May 20 14:39:19 2015
@@ -82,8 +82,8 @@ public class PostConstructTest {
         try {
             factory.createModel(resource, FailingPostConstuctModel.class);
         } catch (ModelClassException e) {
-            assertTrue(e.getMessage().contains("post-construct"));
-            assertEquals("FAIL", e.getCause().getMessage());
+            assertTrue(e.getMessage().contains("Post-construct"));
+            assertEquals("FAIL", e.getCause().getCause().getMessage());
             thrown = true;
         }
         assertTrue(thrown);

Modified: sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java?rev=1680581&r1=1680580&r2=1680581&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java (original)
+++ sling/trunk/bundles/extensions/models/impl/src/test/java/org/apache/sling/models/impl/ResourceModelClassesTest.java Wed May 20 14:39:19 2015
@@ -200,8 +200,7 @@ public class ResourceModelClassesTest {
         try {
             factory.createModel(res, ResourceModelWithRequiredField.class);
         } catch (MissingElementsException e) {
-            assertEquals(ResourceModelWithRequiredField.class, e.getType());
-            assertEquals("required", ((Field) e.getMissingElements().iterator().next()).getName());
+            assertEquals("required", ((Field) e.getMissingElements().iterator().next().getElement()).getName());
             thrown = true;
         }
         assertTrue(thrown);