spring-projects / spring-projects/spring-framework
Fail explicitly if a final method is invoked on a CGLIB proxy
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 60.2k
- Forks
- 38.8k
- Avg merge
- 5d 2h
- Merged PRs (30d)
- 27
Description
Started from https://github.com/spring-projects/spring-retry/issues/238
In org.springframework.cglib.proxy.Enhancer.getMethods():
CollectionUtils.filter(methods, new RejectModifierPredicate(Constants.ACC_FINAL));
If the method is final it is SILENTLY rejected from being proxied.
Shouldn't we warn someone who is implementing a proxy on top of a final class ?
I believe it is a contract break of making the proxy and should throw a NotProxiableElementException("The method or field is final.").
This issue is particularly severe in Kotlin where final is the default.
This example is using Spring-Retry to generate the Proxy and demonstrate the issue.
import org.junit.Assert
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.retry.annotation.EnableRetry
import org.springframework.retry.annotation.Retryable
import org.springframework.stereotype.Component
private const val COUNT=1000
@SpringBootTest
@EnableRetry
class SpringOpenIssueTest {
@Autowired
private lateinit var bean: ChildBean
@Test
fun `proxies should work in kotlin with all-open plugin`(){
bean.assertOkayFromTheInside()
Assert.assertEquals(COUNT, bean.openCount)
Assert.assertEquals(COUNT, bean.closedCount) //java.lang.AssertionError: expected:<1000> but was:<0>
}
}
@Component //This class is automatically opened by all-open plugin
class ChildBean : AbstractBean(){
@Retryable
fun assertOkayFromTheInside(){
Assert.assertEquals(COUNT, openCount)
Assert.assertEquals(COUNT, closedCount)
}
}
//This class is open because abstract
abstract class AbstractBean{
var closedCount = COUNT //This field is not automatically opened
open var openCount = COUNT
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in org.springframework.cglib.proxy.Enhancer.getMethods(), where final methods are filtered with RejectModifierPredicate(Constants.ACC_FINAL). Review the Kotlin example and existing proxy tests, then verify that attempting to proxy a final method or field reports the proposed NotProxiableElementException instead of silently omitting it.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, kotlin
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100