From 4e32e896abd97ac691dc343ec163aa37e1a37fa3 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Thu, 6 May 2010 00:26:13 +0000 Subject: [PATCH] SPR-6941 git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3314 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../ExpressionInvocationTargetException.java | 49 +++++++++++++++++++ .../expression/spel/ast/MethodReference.java | 6 ++- .../spel/MethodInvocationTests.java | 26 +++++++++- 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java b/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java new file mode 100644 index 00000000000..4268039b44c --- /dev/null +++ b/org.springframework.expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002-2010 the original author or authors. + * + * Licensed 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.springframework.expression; + +/** + * This exception wraps (as cause) a checked exception thrown by some method that SpEL invokes. + * It differs from a SpelEvaluationException because this indicates the occurrence of a checked exception + * that the invoked method was defined to throw. SpelEvaluationExceptions are for handling (and wrapping) + * unexpected exceptions. + * + * @author Andy Clement + * @since 3.0.3 + */ +public class ExpressionInvocationTargetException extends EvaluationException { + + public ExpressionInvocationTargetException(int position, String message, Throwable cause) { + super(position, message, cause); + } + + public ExpressionInvocationTargetException(int position, String message) { + super(position, message); + } + + public ExpressionInvocationTargetException(String expressionString, String message) { + super(expressionString, message); + } + + public ExpressionInvocationTargetException(String message, Throwable cause) { + super(message, cause); + } + + public ExpressionInvocationTargetException(String message) { + super(message); + } + +} diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java index cd3dfb7acf8..c7e9ca18a02 100644 --- a/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java +++ b/org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.expression.AccessException; import org.springframework.expression.EvaluationContext; import org.springframework.expression.EvaluationException; +import org.springframework.expression.ExpressionInvocationTargetException; import org.springframework.expression.MethodExecutor; import org.springframework.expression.MethodResolver; import org.springframework.expression.TypedValue; @@ -123,8 +124,9 @@ public class MethodReference extends SpelNodeImpl { if (rootCause instanceof RuntimeException) { throw (RuntimeException)rootCause; } else { - throw new SpelEvaluationException( getStartPosition(), rootCause, SpelMessage.EXCEPTION_DURING_METHOD_INVOCATION, - this.name, state.getActiveContextObject().getValue().getClass().getName(), rootCause.getMessage()); + throw new ExpressionInvocationTargetException( getStartPosition(), + "A problem occurred when trying to execute method '"+this.name+"' on object of type '"+state.getActiveContextObject().getValue().getClass().getName()+"'", + rootCause); } } } diff --git a/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java b/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java index 9564a9cced1..29286ea68f9 100644 --- a/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java +++ b/org.springframework.expression/src/test/java/org/springframework/expression/spel/MethodInvocationTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.springframework.expression.AccessException; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionInvocationTargetException; import org.springframework.expression.MethodExecutor; import org.springframework.expression.MethodFilter; import org.springframework.expression.MethodResolver; @@ -146,7 +147,7 @@ public class MethodInvocationTests extends ExpressionTestCase { Assert.fail(); } catch (Exception e) { // 4 means it will throw a checked exception - this will be wrapped - if (!(e instanceof SpelEvaluationException)) { + if (!(e instanceof ExpressionInvocationTargetException)) { e.printStackTrace(); Assert.fail("Should have been wrapped"); } @@ -183,6 +184,29 @@ public class MethodInvocationTests extends ExpressionTestCase { } } + @Test + public void testMethodThrowingException_SPR6941_2() { + // Test method on inventor: throwException() + // On 1 it will throw an IllegalArgumentException + // On 2 it will throw a RuntimeException + // On 3 it will exit normally + // In each case it increments the Inventor field 'counter' when invoked + + SpelExpressionParser parser = new SpelExpressionParser(); + Expression expr = parser.parseExpression("throwException(#bar)"); + + eContext.setVariable("bar",4); + try { + expr.getValue(eContext); + Assert.fail(); + } catch (ExpressionInvocationTargetException e) { + Throwable t = e.getCause(); + Assert.assertEquals("org.springframework.expression.spel.testresources.Inventor$TestException", t.getClass().getName()); + return; + } + Assert.fail("Should not be a SpelEvaluationException"); + } + @Test public void testMethodFiltering_SPR6764() { SpelExpressionParser parser = new SpelExpressionParser();