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

ValueExpressionResolver should be annotated with @Nullable #4094

Closed
asinbow opened this issue Sep 22, 2023 · 0 comments
Closed

ValueExpressionResolver should be annotated with @Nullable #4094

asinbow opened this issue Sep 22, 2023 · 0 comments
Labels
type: task A general task
Milestone

Comments

@asinbow
Copy link

asinbow commented Sep 22, 2023

Describe the bug
As @NonNullApi used in the package, ValueExpressionResolver is annotated with both input and output @nonnull. But this is not true at runtime, which makes it not friendly to Kotlin.

image

Environment
v1.11.4

To Reproduce

@Component
class MyComponent {
  @Timed
  void myMethod(@MeterTag("slug", expression = "#this" String slug) { }
}

@Autowired private myComponent: MyComponent;

myComponent.myMethod(null);
// Then a null parameter will be sent to the implementation ValueExpressionResolver.
java.lang.NullPointerException: Parameter specified as non-null is null: method SpelValueExpressionResolver.resolve, parameter parameter
	at com.flexport.bookings.config.MetricsConfig$SpelValueExpressionResolver.resolve(MetricsConfig.kt)
	at io.micrometer.core.aop.MeterTagAnnotationHandler.resolveTagValue(MeterTagAnnotationHandler.java:70)
	at io.micrometer.core.aop.MeterTagAnnotationHandler.lambda$new$1(MeterTagAnnotationHandler.java:52)
	at io.micrometer.common.annotation.AnnotationHandler.addAnnotatedArguments(AnnotationHandler.java:141)
	at io.micrometer.common.annotation.AnnotationHandler.addAnnotatedParameters(AnnotationHandler.java:96)
	at io.micrometer.core.aop.TimedAspect.recordBuilder(TimedAspect.java:258)
	at io.micrometer.core.aop.TimedAspect.record(TimedAspect.java:241)
	at io.micrometer.core.aop.TimedAspect.processWithTimer(TimedAspect.java:234)
	at io.micrometer.core.aop.TimedAspect.perform(TimedAspect.java:202)
	at io.micrometer.core.aop.TimedAspect.timedMethod(TimedAspect.java:194)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:702)

Expected behavior
ValueExpressionResolver should defined like this:

public interface ValueExpressionResolver {
  @Nullable String resolve(String expression, @Nullable Object parameter);
}

Another option is to ensure micrometer doesn't pass in null to the parameter, because it doesn't make much sense..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task A general task
Projects
None yet
Development

No branches or pull requests

3 participants