diff --git a/aspects/aspects.gradle b/aspects/aspects.gradle index 3e3ae8fc6c..300f6263b0 100644 --- a/aspects/aspects.gradle +++ b/aspects/aspects.gradle @@ -1,5 +1,6 @@ dependencies { compile project(':spring-security-core'), - "org.springframework:spring-beans:$springVersion" + "org.springframework:spring-beans:$springVersion", + "org.springframework:spring-context:$springVersion" } \ No newline at end of file diff --git a/aspects/src/main/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj b/aspects/src/main/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj index b2d94bbcba..f2194068fb 100644 --- a/aspects/src/main/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj +++ b/aspects/src/main/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspect.aj @@ -2,11 +2,12 @@ package org.springframework.security.access.intercept.aspectj.aspect; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.access.annotation.Secured; +import org.springframework.security.access.prepost.*; import org.springframework.security.access.intercept.aspectj.AspectJCallback; -import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor; +import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor; /** - * Concrete AspectJ transaction aspect using Spring Security @Secured annotation + * Concrete AspectJ aspect using Spring Security @Secured annotation * for JDK 1.5+. * *
@@ -16,8 +17,8 @@ import org.springframework.security.access.intercept.aspectj.AspectJSecurityInte * interfaces are not inherited. This will vary from Spring AOP. * * @author Mike Wiesner - * @since 1.0 - * @version $Id$ + * @author Luke Taylor + * @since 3.1 */ public aspect AnnotationSecurityAspect implements InitializingBean { @@ -34,11 +35,19 @@ public aspect AnnotationSecurityAspect implements InitializingBean { private pointcut executionOfSecuredMethod() : execution(* *(..)) && @annotation(Secured); + /** + * Matches the execution of any method with Pre/Post annotations. + */ + private pointcut executionOfPrePostAnnotatedMethod() : + execution(* *(..)) && (@annotation(PreAuthorize) || @annotation(PreFilter) + || @annotation(PostAuthorize) || @annotation(PostFilter)); + private pointcut securedMethodExecution() : executionOfAnyPublicMethodInAtSecuredType() || - executionOfSecuredMethod(); + executionOfSecuredMethod() || + executionOfPrePostAnnotatedMethod(); - private AspectJSecurityInterceptor securityInterceptor; + private AspectJMethodSecurityInterceptor securityInterceptor; Object around(): securedMethodExecution() { if (this.securityInterceptor == null) { @@ -54,13 +63,14 @@ public aspect AnnotationSecurityAspect implements InitializingBean { return this.securityInterceptor.invoke(thisJoinPoint, callback); } - public void setSecurityInterceptor(AspectJSecurityInterceptor securityInterceptor) { + public void setSecurityInterceptor(AspectJMethodSecurityInterceptor securityInterceptor) { this.securityInterceptor = securityInterceptor; } public void afterPropertiesSet() throws Exception { - if (this.securityInterceptor == null) + if (this.securityInterceptor == null) { throw new IllegalArgumentException("securityInterceptor required"); + } } } diff --git a/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java b/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java new file mode 100644 index 0000000000..8e4a8828c5 --- /dev/null +++ b/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java @@ -0,0 +1,110 @@ +package org.springframework.security.access.intercept.aspectj.aspect; + +import java.util.Arrays; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.security.access.AccessDecisionManager; +import org.springframework.security.access.AccessDecisionVoter; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource; +import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; +import org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory; +import org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice; +import org.springframework.security.access.intercept.aspectj.AspectJMethodSecurityInterceptor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter; +import org.springframework.security.access.prepost.PrePostAnnotationSecurityMetadataSource; +import org.springframework.security.access.vote.AffirmativeBased; +import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; + +/** + * + * @author Luke Taylor + * @since 3.0.3 + */ +public class AnnotationSecurityAspectTests { + private @Mock AccessDecisionManager adm; + private @Mock AuthenticationManager authman; + private TestingAuthenticationToken anne = new TestingAuthenticationToken("anne", "", "ROLE_A"); +// private TestingAuthenticationToken bob = new TestingAuthenticationToken("bob", "", "ROLE_B"); + private AspectJMethodSecurityInterceptor interceptor; + private SecuredImpl secured = new SecuredImpl(); + private PrePostSecured prePostSecured = new PrePostSecured(); + + @Before + public final void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + interceptor = new AspectJMethodSecurityInterceptor(); + interceptor.setAccessDecisionManager(adm); + interceptor.setAuthenticationManager(authman); + interceptor.setSecurityMetadataSource(new SecuredAnnotationSecurityMetadataSource()); + AnnotationSecurityAspect secAspect = AnnotationSecurityAspect.aspectOf(); + secAspect.setSecurityInterceptor(interceptor); + } + + @After + public void clearContext() { + SecurityContextHolder.clearContext(); + } + + @Test + public void securedInterfaceMethodAllowsAllAccess() throws Exception { + secured.securedMethod(); + } + + @Test(expected=AuthenticationCredentialsNotFoundException.class) + public void securedClassMethodDeniesUnauthenticatedAccess() throws Exception { + secured.securedClassMethod(); + } + + @Test + public void securedClassMethodAllowsAccessToRoleA() throws Exception { + SecurityContextHolder.getContext().setAuthentication(anne); + secured.securedClassMethod(); + } + + // SEC-1262 + @Test(expected=AccessDeniedException.class) + public void denyAllPreAuthorizeDeniesAccess() throws Exception { + SecurityContextHolder.getContext().setAuthentication(anne); + interceptor.setSecurityMetadataSource(new PrePostAnnotationSecurityMetadataSource( + new ExpressionBasedAnnotationAttributeFactory(new DefaultMethodSecurityExpressionHandler()))); + AffirmativeBased adm = new AffirmativeBased(); + AccessDecisionVoter[] voters = new AccessDecisionVoter[] + {new PreInvocationAuthorizationAdviceVoter(new ExpressionBasedPreInvocationAdvice())}; + adm.setDecisionVoters(Arrays.asList(voters)); + interceptor.setAccessDecisionManager(adm); + prePostSecured.denyAllMethod(); + } +} + +interface SecuredInterface { + @Secured("ROLE_X") + void securedMethod(); +} + +class SecuredImpl implements SecuredInterface { + + // Not really secured because AspectJ doesn't inherit annotations from interfaces + public void securedMethod() { + } + + @Secured("ROLE_A") + public void securedClassMethod() { + } +} + +class PrePostSecured { + + @PreAuthorize("denyAll") + public void denyAllMethod() { + } +} diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationCallback.java b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationCallback.java index 6b46bd6de9..0fd833b7e5 100644 --- a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationCallback.java +++ b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationCallback.java @@ -6,8 +6,9 @@ package org.springframework.security.access.intercept.aspectj; * AspectJ processing to continue. * * @author Mike Wiesner + * @deprecated */ - +@Deprecated public interface AspectJAnnotationCallback { //~ Methods ======================================================================================================== diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationSecurityInterceptor.java b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationSecurityInterceptor.java index 5c193f1d8a..20018f6dce 100644 --- a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationSecurityInterceptor.java +++ b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJAnnotationSecurityInterceptor.java @@ -11,7 +11,9 @@ import org.aspectj.lang.JoinPoint; * AspectJ interceptor that supports @Aspect notation. * * @author Mike Wiesner + * @deprecated Use AspectJMethodSecurityInterceptor instead */ +@Deprecated public class AspectJAnnotationSecurityInterceptor extends AbstractSecurityInterceptor { //~ Instance fields ================================================================================================ diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java new file mode 100644 index 0000000000..8682056b70 --- /dev/null +++ b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJMethodSecurityInterceptor.java @@ -0,0 +1,51 @@ +package org.springframework.security.access.intercept.aspectj; + +import org.aspectj.lang.JoinPoint; +import org.springframework.security.access.intercept.InterceptorStatusToken; +import org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor; + +/** + * AspectJ {@code JoinPoint} security interceptor which wraps the {@code JoinPoint} in a {@code MethodInvocation} + * adapter to make it compatible with security infrastructure classes which only support {@code MethodInvocation}s. + *
+ * One of the {@code invoke} methods should be called from the {@code around()} advice in your aspect.
+ * Alternatively you can use one of the pre-defined aspects from the aspects module.
+ *
+ * @author Luke Taylor
+ * @since 3.0.3
+ */
+public final class AspectJMethodSecurityInterceptor extends MethodSecurityInterceptor {
+
+ /**
+ * Method that is suitable for user with @Aspect notation.
+ *
+ * @param jp The AspectJ joint point being invoked which requires a security decision
+ * @return The returned value from the method invocation
+ * @throws Throwable if the invocation throws one
+ */
+ public Object invoke(JoinPoint jp) throws Throwable {
+ return super.invoke(new MethodInvocationAdapter(jp));
+ }
+
+ /**
+ * Method that is suitable for user with traditional AspectJ-code aspects.
+ *
+ * @param jp The AspectJ joint point being invoked which requires a security decision
+ * @param advisorProceed the advice-defined anonymous class that implements {@code AspectJCallback} containing
+ * a simple {@code return proceed();} statement
+ *
+ * @return The returned value from the method invocation
+ */
+ public Object invoke(JoinPoint jp, AspectJCallback advisorProceed) {
+ Object result = null;
+ InterceptorStatusToken token = super.beforeInvocation(new MethodInvocationAdapter(jp));
+
+ try {
+ result = advisorProceed.proceedWithObject();
+ } finally {
+ result = super.afterInvocation(token, result);
+ }
+
+ return result;
+ }
+}
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptor.java b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptor.java
index 9348d4d7f1..3e23102f2f 100644
--- a/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptor.java
+++ b/core/src/main/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptor.java
@@ -37,7 +37,9 @@ import org.aspectj.lang.JoinPoint;
* Refer to {@link AbstractSecurityInterceptor} for details on the workflow.
*
* @author Ben Alex
+ * @deprecated Use AspectJMethodSecurityInterceptor instead
*/
+@Deprecated
public class AspectJSecurityInterceptor extends AbstractSecurityInterceptor {
//~ Instance fields ================================================================================================
diff --git a/core/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java b/core/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java
new file mode 100644
index 0000000000..a664c7c8e0
--- /dev/null
+++ b/core/src/main/java/org/springframework/security/access/intercept/aspectj/MethodInvocationAdapter.java
@@ -0,0 +1,61 @@
+package org.springframework.security.access.intercept.aspectj;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Method;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.reflect.CodeSignature;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Decorates a JoinPoint to allow it to be used with method-security infrastructure
+ * classes which support {@code MethodInvocation} instances.
+ *
+ * @author Luke Taylor
+ * @since 3.0.3
+ */
+public final class MethodInvocationAdapter implements MethodInvocation {
+ private final ProceedingJoinPoint jp;
+ private final Method method;
+ private final Object target;
+
+ MethodInvocationAdapter(JoinPoint jp) {
+ this.jp = (ProceedingJoinPoint)jp;
+ if (jp.getTarget() != null) {
+ target = jp.getTarget();
+ } else {
+ // SEC-1295: target may be null if an ITD is in use
+ target = jp.getSignature().getDeclaringType();
+ }
+ String targetMethodName = jp.getStaticPart().getSignature().getName();
+ Class>[] types = ((CodeSignature) jp.getStaticPart().getSignature()).getParameterTypes();
+ Class> declaringType = ((CodeSignature) jp.getStaticPart().getSignature()).getDeclaringType();
+
+ method = ClassUtils.getMethodIfAvailable(declaringType, targetMethodName, types);
+ Assert.notNull(method, "Could not obtain target method from JoinPoint: '"+ jp + "'");
+
+ }
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public Object[] getArguments() {
+ return jp.getArgs();
+ }
+
+ public AccessibleObject getStaticPart() {
+ return method;
+ }
+
+ public Object getThis() {
+ return target;
+ }
+
+ public Object proceed() throws Throwable {
+ return jp.proceed();
+ }
+}
diff --git a/core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java b/core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
index 1d377850e4..63ec450342 100644
--- a/core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
+++ b/core/src/main/java/org/springframework/security/access/method/AbstractMethodSecurityMetadataSource.java
@@ -49,7 +49,13 @@ public abstract class AbstractMethodSecurityMetadataSource implements MethodSecu
if (object instanceof MethodInvocation) {
MethodInvocation mi = (MethodInvocation) object;
Object target = mi.getThis();
- return getAttributes(mi.getMethod(), target == null ? null : target.getClass());
+ Class> targetClass = null;
+
+ if (target != null) {
+ targetClass = target instanceof Class> ? (Class>)target : target.getClass();
+ }
+
+ return getAttributes(mi.getMethod(), targetClass);
}
if (object instanceof JoinPoint) {
diff --git a/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptorTests.java b/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptorTests.java
index 2f84f5863a..fb160cbace 100644
--- a/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptorTests.java
+++ b/core/src/test/java/org/springframework/security/access/intercept/aspectj/AspectJSecurityInterceptorTests.java
@@ -15,26 +15,28 @@
package org.springframework.security.access.intercept.aspectj;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
+
import java.lang.reflect.Method;
-import java.util.List;
+import java.util.Collection;
import org.aspectj.lang.JoinPoint;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.springframework.security.MockJoinPoint;
import org.springframework.security.TargetObject;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.SecurityConfig;
-import org.springframework.security.access.intercept.aspectj.AspectJCallback;
-import org.springframework.security.access.intercept.aspectj.AspectJSecurityInterceptor;
import org.springframework.security.access.method.MethodSecurityMetadataSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.TestingAuthenticationToken;
+import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -42,33 +44,33 @@ import org.springframework.security.core.context.SecurityContextHolder;
* Tests {@link AspectJSecurityInterceptor}.
*
* @author Ben Alex
+ * @author Luke Taylor
*/
+@SuppressWarnings("deprecation")
public class AspectJSecurityInterceptorTests {
- private Mockery jmock = new JUnit4Mockery();
private TestingAuthenticationToken token;
private AspectJSecurityInterceptor interceptor;
- private AccessDecisionManager adm;
- private MethodSecurityMetadataSource mds;
- private AuthenticationManager authman;
- private AspectJCallback aspectJCallback;
+ private @Mock AccessDecisionManager adm;
+ private @Mock MethodSecurityMetadataSource mds;
+ private @Mock AuthenticationManager authman;
+ private @Mock AspectJCallback aspectJCallback;
private JoinPoint joinPoint;
//~ Methods ========================================================================================================
@Before
public final void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
SecurityContextHolder.clearContext();
token = new TestingAuthenticationToken("Test", "Password");
interceptor = new AspectJSecurityInterceptor();
- adm = jmock.mock(AccessDecisionManager.class);
- authman = jmock.mock(AuthenticationManager.class);
- mds = jmock.mock(MethodSecurityMetadataSource.class);
interceptor.setAccessDecisionManager(adm);
interceptor.setAuthenticationManager(authman);
interceptor.setSecurityMetadataSource(mds);
Method method = TargetObject.class.getMethod("countLength", new Class[] {String.class});
joinPoint = new MockJoinPoint(new TargetObject(), method);
- aspectJCallback = jmock.mock(AspectJCallback.class);
+ when(mds.getAttributes(any(JoinPoint.class))).thenReturn(SecurityConfig.createList("ROLE_USER"));
+ when(authman.authenticate(token)).thenReturn(token);
}
@After
@@ -77,33 +79,23 @@ public class AspectJSecurityInterceptorTests {
}
@Test
- @SuppressWarnings("unchecked")
public void callbackIsInvokedWhenPermissionGranted() throws Exception {
- jmock.checking(new Expectations() {{
- oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
- oneOf(authman).authenticate(token); will(returnValue(token));
- oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
- oneOf(aspectJCallback).proceedWithObject();
- }});
-
SecurityContextHolder.getContext().setAuthentication(token);
interceptor.invoke(joinPoint, aspectJCallback);
- jmock.assertIsSatisfied();
+ verify(aspectJCallback).proceedWithObject();
}
@SuppressWarnings("unchecked")
- @Test(expected=AccessDeniedException.class)
+ @Test
public void callbackIsNotInvokedWhenPermissionDenied() throws Exception {
- jmock.checking(new Expectations() {{
- oneOf(mds).getAttributes(with(any(JoinPoint.class))); will (returnValue(SecurityConfig.createList("ROLE_USER")));
- oneOf(authman).authenticate(token); will(returnValue(token));
- oneOf(adm).decide(with(token), with(aNonNull(JoinPoint.class)), with(aNonNull(List.class)));
- will(throwException(new AccessDeniedException("denied")));
- never(aspectJCallback).proceedWithObject();
- }});
+ doThrow(new AccessDeniedException("denied")).when(adm).decide(any(Authentication.class), any(), any(Collection.class));
SecurityContextHolder.getContext().setAuthentication(token);
- interceptor.invoke(joinPoint, aspectJCallback);
- jmock.assertIsSatisfied();
+ try {
+ interceptor.invoke(joinPoint, aspectJCallback);
+ fail("Expected AccessDeniedException");
+ } catch (AccessDeniedException expected) {
+ }
+ verify(aspectJCallback, never()).proceedWithObject();
}
}
diff --git a/gradle/aspectj.gradle b/gradle/aspectj.gradle
index 4d239ba55b..e366e6dc0c 100644
--- a/gradle/aspectj.gradle
+++ b/gradle/aspectj.gradle
@@ -10,15 +10,38 @@ dependencies {
compile "org.aspectj:aspectjrt:$aspectjVersion"
}
-task compileJava(dependsOn: JavaPlugin.PROCESS_RESOURCES_TASK_NAME, overwrite: true, description: 'Compiles AspectJ Source') << {
- println "Running ajc ..."
- ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: configurations.ajtools.asPath)
- ant.iajc(classpath: configurations.compile.asPath, fork: 'true', destDir: sourceSets.main.classesDir.absolutePath, source: sourceCompatibility, target: targetCompatibility,
- aspectPath: configurations.aspectpath.asPath, sourceRootCopyFilter: '**/*.java') {
- sourceroots {
- sourceSets.main.java.srcDirs.each {
- pathelement(location: it.absolutePath)
+task compileJava(overwrite: true, description: 'Compiles AspectJ Source', type: Ajc) {
+ dependsOn processResources
+ sourceSet = sourceSets.main
+ aspectPath = configurations.aspectpath
+}
+
+task compileTestJava(overwrite: true, description: 'Compiles AspectJ Test Source', type: Ajc) {
+ dependsOn processTestResources, compileJava, jar
+ sourceSet = sourceSets.test
+ aspectPath = files(configurations.aspectpath, jar.archivePath)
+}
+
+class Ajc extends DefaultTask {
+ @Input
+ SourceSet sourceSet
+
+ @Input
+ FileCollection aspectPath
+
+ @TaskAction
+ def compile() {
+ println "Running ajc ..."
+ ant.taskdef(resource: "org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties", classpath: project.configurations.ajtools.asPath)
+ ant.iajc(classpath: sourceSet.compileClasspath.asPath, fork: 'true', destDir: sourceSet.classesDir.absolutePath,
+ source: project.convention.plugins.java.sourceCompatibility,
+ target: project.convention.plugins.java.targetCompatibility,
+ aspectPath: aspectPath.asPath, sourceRootCopyFilter: '**/*.java', showWeaveInfo: 'true') {
+ sourceroots {
+ sourceSet.java.srcDirs.each {
+ pathelement(location: it.absolutePath)
+ }
}
}
}
-}
+}
\ No newline at end of file
diff --git a/gradle/javaprojects.gradle b/gradle/javaprojects.gradle
index ca5f4d9d3f..50079d8af2 100644
--- a/gradle/javaprojects.gradle
+++ b/gradle/javaprojects.gradle
@@ -22,7 +22,7 @@ dependencies {
}
testCompile 'junit:junit:4.7',
- 'org.mockito:mockito-core:1.7',
+ 'org.mockito:mockito-core:1.8.3',
'org.jmock:jmock:2.5.1',
'org.jmock:jmock-junit4:2.5.1',
'org.hamcrest:hamcrest-core:1.1',
diff --git a/samples/aspectj/src/main/resources/aspectj-context.xml b/samples/aspectj/src/main/resources/aspectj-context.xml
index b73e73a0b9..ef48497453 100644
--- a/samples/aspectj/src/main/resources/aspectj-context.xml
+++ b/samples/aspectj/src/main/resources/aspectj-context.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">