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

Generic constructor argument (e.g. ObjectProvider) fails to resolve for inner class [SPR-16734] #21275

Closed
spring-projects-issues opened this issue Apr 17, 2018 · 8 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Apr 17, 2018

David Kensche opened SPR-16734 and commented

I have a class containing an inner class configuration that inherits from JpaBaseConfiguration. It therefore overrides the protected super constructor. Upon application startup I get a misleading error message stating that there is no ObjectProvider<JtaTransactionManager>. However, the root cause for this is that the inner class itself is listed as first argument in the list of constructor arguments, leading to an off-by-1 error, therefore not satisfying the condition to create the ObjectProvider automatically.

This again resulted for me in hours of searching for dependency conflicts as the internet suggests this is a dependency conflict.

Here is the code example:

@SpringBootApplication
@EnableJms
public class ShowcaseManager {
    ...

    @Configuration
    @EnableTransactionManagement
    public static class JpaConfiguration extends JpaBaseConfiguration {

        protected JpaConfiguration(DataSource dataSource, JpaProperties properties,
                ObjectProvider<JtaTransactionManager> jtaTransactionManager,
                ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
            super(dataSource, properties, jtaTransactionManager, transactionManagerCustomizers);
        }
       ...
    }
}

Affects: 4.3.16, 5.0.5

Reference URL: https://bugs.java.com/view_bug.do?bug_id=5087240

Issue Links:

Backported to: 4.3.17

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I suppose this only happens when you forget to declare the nested class as static? At least I can only reproduce it in such a scenario.

Even there we need to fix it, of course, but we highly recommend to declare nested classes as static unless they have an actual need to access an instance of the containing class.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 17, 2018

Juergen Hoeller commented

It turns out that this is a variant of the javac bug in #21193, showing through the JDK's core reflection libraries: Constructor.getGenericParameterTypes() is off by one for an inner class since it doesn't expose the enclosing instance, just like Constructor.getParameterAnnotations. I'll use a similar workaround within our MethodParameter implementation.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Sam Brannen, you'll love this: Constructor.getGenericParameterTypes() is off by one... but only if generic type information is actually included since it'll fall back to a regular getParameterTypes() call otherwise. As mentioned above, I've worked around it along the lines of our fix for getParameterAnnotations on inner classes. FWIW, this is the same on JDK 8 and 9+, so hasn't been addressed at JDK level recently either, in contrast to the parameter annotation case.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

The corresponding test unexpectedly fails on the CI server (on Linux? on a different JDK 8 patch level?), still mismatching the parameter between getParameterTypes and getGenericParameterTypes... We'll have to revisit why the new check doesn't kick in there.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Turns out I only committed the test, not the actual fix... Pushing to the CI server once again :-)

@spring-projects-issues
Copy link
Collaborator Author

Andrei Ivanov commented

Btw, I've noticed on the jdk8u-dev mailing lists that fixed bugs get back ported from newer versions, so maybe someone can ask for the related ones too?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 17, 2018

Juergen Hoeller commented

This one hasn't even been addressed in JDK 11 yet, so we'll rather have to push for an actual fix first...

At least the workaround seems as safe as the one we introduced for #21193. No information lost, just having to adapt the index assumptions in the returned array.

@spring-projects-issues
Copy link
Collaborator Author

Sam Brannen commented

Sam Brannen, you'll love this: Constructor.getGenericParameterTypes() is off by one... but only if generic type information is actually included since it'll fall back to a regular getParameterTypes() call otherwise.

That is indeed quite amusing! :-o
 

As mentioned above, I've worked around it along the lines of our fix for getParameterAnnotations on inner classes.

Nice!
 

FWIW, this is the same on JDK 8 and 9+, so hasn't been addressed at JDK level recently either, in contrast to the parameter annotation case.

Hmmm.... that's a pity.

 

@spring-projects-issues spring-projects-issues added type: bug A general bug status: backported An issue that has been backported to maintenance branches in: core Issues in core modules (aop, beans, core, context, expression) labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.0.6 milestone Jan 11, 2019
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) status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants