Skip to content

@Aspect aspect not correctly applied to Java 8 lambda-defined @Beans [SPR-11807] #16427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue May 19, 2014 · 7 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented May 19, 2014

Josh Long opened SPR-11807 and commented

In the example below, I define an aspect which I expect to be applied to all beans of type CommandLineRunner, it isn't if the bean is defined as a lambda on java version "1.8.0_05" on OSX.

(java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode))


package demo;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.stereotype.Component;

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Application {


    /*   @Bean
       CommandLineRunner good() {
           return new CommandLineRunner() {
               @Override
               public void run(String... args) throws Exception {
                   System.out.println(String.join(",", args));
               }
           };
       }
   */
    @Bean
    CommandLineRunner bad() {
        return (args) -> System.out.println(String.join(",", args));
    }

    public static void main(String[] args) throws Exception {

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);

        applicationContext.getBeansOfType(CommandLineRunner.class).forEach((k, v) -> System.out.println(k + '=' + v));

        for (int i = 0; i < 4; i++) {
            applicationContext.getBeansOfType(CommandLineRunner.class).forEach((k, v) -> {
                try {
                    v.run(args);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

@Component
@Aspect
class WrappingAspect {

    @After("execution(* org.springframework.boot.CommandLineRunner.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("invoked after " + joinPoint.toLongString());
    }

}

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>org.demo</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<name>demo</name>
	<description>Demo project</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.0.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>


	<dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>


		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<properties>
        <spring.version>4.0.4.RELEASE</spring.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<start-class>demo.Application</start-class>
		<java.version>1.8</java.version>
	</properties>
 

</project>

Affects: 4.0.4

Issue Links:

1 votes, 9 watchers

@spring-projects-issues
Copy link
Collaborator Author

Nick Williams commented

Is this still planned for being fixed in Spring 4.2?

@spring-projects-issues
Copy link
Collaborator Author

Stéphane Nicoll commented

Nick, the fix version is set so that's the current plan yes (same answer for your other comment).

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

This turns out to be a problem in AspectJ's PointcutExpressionImpl:

public boolean couldMatchJoinPointsInType(Class aClass) {
    ResolvedType matchType = world.resolve(aClass.getName());

Instead of using the given Class reference, it tries to re-resolve it by name within its own abstraction. And lambda-defined classes can't be resolved/loaded that way; they only have the Class reference itself.

Within AspectJ, this means it'll end up with a MissingResolvedTypeWithKnownSignature for the match type which eventually leads to a ReflectionWorldException:

org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException: warning can't determine modifiers of missing type org.springframework.context.annotation.configuration.ConfigurationClassAspectIntegrationTests$Application$$Lambda$1.793315160
 [Xlint:cantFindType]

Andy Clement, do you see an easy way out here?

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I'll commit the test that I was using for this, marking it as ignored for the time being: ConfigurationClassAspectIntegrationTests.withInnerClassAndLambdaExpression

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Andy Clement commented

I'll look out for that test appearing and dive into a bit. I have some thoughts on how we can get this to work (obviously with changes to AspectJ).

@spring-projects-issues
Copy link
Collaborator Author

Andy Clement commented

I have a fix for this coming in AspectJ 1.8.6 (due soon) - it passes the test case included in ConfigurationClassAspectIntegrationTests. Work done under this AspectJ issue: https://bugs.eclipse.org/bugs/show_bug.cgi?id=468351

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Resolved through an upgrade to AspectJ 1.8.6 as the suggested version in our POMs.
Applications explicitly an declaring AspectJ version need to follow that upgrade for this to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants