Skip to content

Make Kotlin functions accessible in CoroutinesUtils #23840

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

Conversation

mgmeiner
Copy link

After updating to spring-webflux 5.2 i noticed that @ExceptionHandler's in private Kotlin-Classes stopped working.
After debbuging I found that this regression was introduced with kotlin-coroutines support for reactive Webflux and reactive Messaging handlers.

The Problem is that when converting Java methods to Kotlin functions the information if a method is accessible or not will not be copied and the Kotlin function has to be made accessible again via its isAccessible setter.

For this I introduced a new very simple KotlinReflectionUtils class which both InvocableHandlerMethod's use when Kotlin is available. I'm not 100% sure if this is the best solution and if its worth to introduce a new utils class for this.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Oct 21, 2019
@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Nov 10, 2021
@rstoyanchev rstoyanchev added this to the Triage Queue milestone Dec 3, 2021
}
else {
ReflectionUtils.makeAccessible(method);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code for this has moved to the constructor of HandlerMethod so this needs to be removed from here.

}
else {
ReflectionUtils.makeAccessible(method);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, the code for this has moved to the constructor of HandlerMethod so this needs to be removed from here.

@rstoyanchev
Copy link
Contributor

I'm wondering if these classes need to remain private, i.e. is this something we want to work?

@sdeleuze
Copy link
Contributor

I'm wondering if these classes need to remain private, i.e. is this something we want to work?

@rstoyanchev If you mean classe like CoroutinesController in the PR and if that works on Java, I would say yes.

That said, we can't modify org.springframework.core.CoroutinesUtils#invokeSuspendingFunction signature to use KFunction instead of Method, and CoroutinesUtils is now a Java class. So I think I would suggest to modify:

public static Publisher<?> invokeSuspendingFunction(Method method, Object target, Object... args) {
	KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
	// ...
}

To

public static Publisher<?> invokeSuspendingFunction(Method method, Object target, Object... args) {
	KFunction<?> function = Objects.requireNonNull(ReflectJvmMapping.getKotlinFunction(method));
	if (method.isAccessible() && !kotlin.reflect.jvm.KCallablesJvm.isAccessible(function)) {
		kotlin.reflect.jvm.KCallablesJvm.setAccessible(function, true);
	}
	// ...
}

This will impact other invokeSuspendingFunction invocations as well (not just those from InvocableHandlerMethod), but implemented like that I tend to think that's ok.

@rstoyanchev Do you agree? Is it ok to target 5.3.x for that fix?

@sdeleuze
Copy link
Contributor

We probably need to do the same thing on BeanUtils#instantiateClass and try to detect similar other patterns by a search on ReflectionUtils#makeAccessible usage where kotlin-reflect is involved.

@sdeleuze sdeleuze changed the title Fixes invoke of InvocableHandlerMethod on functions in private Kotlin classes Make Kotlin functions accessible where done on Java methods Dec 17, 2021
@rstoyanchev
Copy link
Contributor

@sdeleuze I agree, as far as the changes to CoroutinesUtils#invokeSuspendingFunction.

@sdeleuze sdeleuze modified the milestones: Triage Queue, 5.3.15 Dec 21, 2021
@sdeleuze sdeleuze removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Dec 21, 2021
@sdeleuze sdeleuze modified the milestones: 5.3.15, 5.3.16 Jan 12, 2022
@sdeleuze sdeleuze changed the title Make Kotlin functions accessible where done on Java methods Make Kotlin functions accessible in CoroutinesUtils Feb 14, 2022
@sdeleuze sdeleuze closed this in 8eb618b Feb 14, 2022
@sdeleuze
Copy link
Contributor

I applied the discussed changes via 8eb618b on 5.3.x and merged them to main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants