Skip to content
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

@Aspect does not work in native-image when pointcut expression uses interface #31739

Closed
imgoby opened this issue Dec 2, 2023 · 13 comments
Closed

Comments

@imgoby
Copy link

imgoby commented Dec 2, 2023

For example:

@Before(value = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && target(registry) && args(registration)", argNames = "registry, registration")

org.springframework.cloud.consul.serviceregistry.ServiceRegistry is an interface.

In JVM the code is OK, but it does not work built with native-image (Spring 6.0.11), unless I change it to:

@Before(value = "execution(* org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.register(*)) && target(registry) && args(registration)", argNames = "registry, registration")
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 2, 2023
@sbrannen sbrannen changed the title @Aspect does not work built with native-image (Spring 6.0.11 ) while pointcut expression is using interface @Aspect does not work in native-image while pointcut expression uses interface Dec 2, 2023
@sbrannen sbrannen changed the title @Aspect does not work in native-image while pointcut expression uses interface @Aspect does not work in native-image when pointcut expression uses interface Dec 2, 2023
@sbrannen
Copy link
Member

sbrannen commented Dec 2, 2023

I imagine you'll need to register runtime hints for ConsulServiceRegistry so that it can be determined via reflection within a native image that it implements ServiceRegistry.

See if that line of thinking helps you resolve the issue.

If not, please provide a minimal example application that we can run ourselves -- preferably a public Git repository or a ZIP file attached to this issue.

@sbrannen sbrannen added the status: waiting-for-feedback We need additional information before we can continue label Dec 2, 2023
@imgoby
Copy link
Author

imgoby commented Dec 2, 2023

this is the project: https://github.com/imgoby/spring-cloud-alibaba-graalvm/tree/main/spring-cloud-alibaba-consul-dubbo-provider

its dependency is https://github.com/imgoby/spring-cloud-alibaba-graalvm/tree/main/spring-cloud-alibaba-starter-dubbo

The relevant class is this:
https://github.com/imgoby/spring-cloud-alibaba-graalvm/blob/main/spring-cloud-alibaba-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java


	/**
	 * The pointcut expression for {@link ServiceRegistry#register(Registration)}.
	 */
	public static final String REGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && target(registry) && args(registration)";

	/**
	 * The pointcut expression for {@link ServiceRegistry#deregister(Registration)}.
	 */
	public static final String DEREGISTER_POINTCUT_EXPRESSION = "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.deregister(*)) && target(registry) && args(registration)";

I'm trying to modify it to an implementation class.So, some codes were changed to :
public static final String REGISTER_POINTCUT_EXPRESSION_CONSUL = "execution(* org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.register(*)) && target(registry) && args(registration)";

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 2, 2023
@imgoby
Copy link
Author

imgoby commented Dec 2, 2023

I imagine you'll need to register runtime hints for ConsulServiceRegistry so that it can be determined via reflection within a native image that it implements ServiceRegistry.

See if that line of thinking helps you resolve the issue.

If not, please provide a minimal example application that we can run ourselves -- preferably a public Git repository or a ZIP file attached to this issue.

Yes, the runtime class maybe ConsulServiceRegistry or EurekaServiceRegistry or NacosServiceRegistry or ZookeeperServiceRegistry.It is defined by user configuration

@imgoby
Copy link
Author

imgoby commented Dec 2, 2023

I understand a bit now. I may need to make the necessary modifications like this

	@Configuration
	@ConditionalOnBean(name = "org.springframework.cloud.client.serviceregistry.ServiceRegistry")
	@Aspect
	public class ConsulAspect{}
	@Configuration
	@ConditionalOnBean(name = "org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry")
	@Aspect
	public class EurekaAspect{}

@imgoby
Copy link
Author

imgoby commented Dec 2, 2023

Is that right?

@sbrannen
Copy link
Member

sbrannen commented Dec 2, 2023

I don't think @ConditionalOnBean will provide any benefit for the scenario you're encountering.

Rather, I was saying I think you'll need to register runtime hints for the use of reflection (for evaluating your AspectJ pointcut expression) within a GraalVM native image.

@sbrannen
Copy link
Member

sbrannen commented Dec 2, 2023

@imgoby
Copy link
Author

imgoby commented Dec 3, 2023

Can you provide some sample code?

@imgoby
Copy link
Author

imgoby commented Dec 3, 2023


import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportRuntimeHints;

@SpringBootApplication
@EnableDiscoveryClient
@EnableDubbo
@ImportRuntimeHints(ProviderApplication.ServiceRegistryRuntimeHints.class)
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }

    static class ServiceRegistryRuntimeHints implements RuntimeHintsRegistrar {
        @Override
        public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
            hints.reflection().registerType(org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.class,
                    MemberCategory.values());
        }
    }

}

Is this OK?But I should write the final implement class in my code.

@sbrannen
Copy link
Member

sbrannen commented Dec 3, 2023

Is this OK?

Yes, I was suggesting something like that.

Though, I don't think you need to register all MemberCategory values to get it to work.

In any case, can you please confirm that ServiceRegistryRuntimeHints allows your aspect to work properly in a native image?

But I should write the final implement class in my code.

I don't understand what you mean by that. Can you please expound?

@sbrannen sbrannen added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Dec 3, 2023
@imgoby
Copy link
Author

imgoby commented Dec 3, 2023

Is this OK?

Yes, I was suggesting something like that.

Though, I don't think you need to register all MemberCategory values to get it to work.

In any case, can you please confirm that ServiceRegistryRuntimeHints allows your aspect to work properly in a native image?

But I should write the final implement class in my code.

I don't understand what you mean by that. Can you please expound?

Previously, it was just an interface called org. springframework. cloud. client. serviceregistry.ServiceRegistry,and there are several implementation classes,such as org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.class,
org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry

Is it written here as follow?
hints.reflection().registerType(org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry.class,
MemberCategory.values());
hints.reflection().registerType(org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.class,
MemberCategory.values());

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Dec 3, 2023
@imgoby
Copy link
Author

imgoby commented Dec 3, 2023

@imgoby
Copy link
Author

imgoby commented Dec 4, 2023

@ImportRuntimeHints is not working in my project and the issue cannot be resolved. Therefore, I divided the original classes into four. The project is now working normally.

https://github.com/imgoby/spring-cloud-alibaba-graalvm/blob/main/spring-cloud-alibaba-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java

@imgoby imgoby closed this as completed Dec 4, 2023
@snicoll snicoll removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Dec 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants