0

I am using Spring Boot 3.0.3, Spring Core 6.0.5 with Spring Data MongoDB 4.0.2. I see many warning messages of the form

ocalVariableTableParameterNameDiscoverer : Using deprecated '-debug' fallback for parameter name resolution. Compile the affected code with '-parameters' instead or avoid its introspection: <your mongo entity here>

Inserting a breakpoint at source of the message, I get this stack trace:

apply:-1, LocalVariableTableParameterNameDiscoverer$$Lambda$1162/0x00000008013cfa98 (org.springframework.core)
computeIfAbsent:1708, ConcurrentHashMap (java.util.concurrent)
doGetParameterNames:96, LocalVariableTableParameterNameDiscoverer (org.springframework.core)
getParameterNames:90, LocalVariableTableParameterNameDiscoverer (org.springframework.core)
getParameterNames:67, PrioritizedParameterNameDiscoverer (org.springframework.core)
buildPreferredConstructor:236, PreferredConstructorDiscoverer$Discoverers (org.springframework.data.mapping.model)
discover:118, PreferredConstructorDiscoverer$Discoverers$1 (org.springframework.data.mapping.model)
discover:82, PreferredConstructorDiscoverer (org.springframework.data.mapping.model)
discover:81, InstanceCreatorMetadataDiscoverer (org.springframework.data.mapping.model)
<init>:113, BasicPersistentEntity (org.springframework.data.mapping.model)
<init>:84, BasicMongoPersistentEntity (org.springframework.data.mongodb.core.mapping)
createPersistentEntity:88, MongoMappingContext (org.springframework.data.mongodb.core.mapping)
createPersistentEntity:41, MongoMappingContext (org.springframework.data.mongodb.core.mapping)
doAddPersistentEntity:403, AbstractMappingContext (org.springframework.data.mapping.context)
addPersistentEntity:379, AbstractMappingContext (org.springframework.data.mapping.context)
addPersistentEntity:339, AbstractMappingContext (org.springframework.data.mapping.context)
accept:-1, AbstractMappingContext$$Lambda$1098/0x00000008013bded0 (org.springframework.data.mapping.context)
forEach:75, Iterable (java.lang)
forEach:-1, ManagedTypes$$Lambda$1093/0x00000008013b90f0 (org.springframework.data.domain)
forEach:79, MongoManagedTypes (org.springframework.data.mongodb)
initialize:484, AbstractMappingContext (org.springframework.data.mapping.context)
afterPropertiesSet:476, AbstractMappingContext (org.springframework.data.mapping.context)
invokeInitMethods:1798, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1748, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:600, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:522, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:326, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, AbstractBeanFactory$$Lambda$414/0x0000000800e45ff0 (org.springframework.beans.factory.support)
getSingleton:234, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:324, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:200, AbstractBeanFactory (org.springframework.beans.factory.support)
resolveCandidate:254, DependencyDescriptor (org.springframework.beans.factory.config)
doResolveDependency:1405, DefaultListableBeanFactory (org.springframework.beans.factory.support)
resolveDependency:1325, DefaultListableBeanFactory (org.springframework.beans.factory.support)
resolveAutowiredArgument:885, ConstructorResolver (org.springframework.beans.factory.support)
createArgumentArray:789, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:548, ConstructorResolver (org.springframework.beans.factory.support)
... truncated

I am aware of this issue but I understand that I am using code that should contain the fix explained there. Is this evidence that we're not following current recommended practices for initializing our Mongo entities somehow? We did not see this warning prior to upgrading our app to Spring Boot 3.0.x.

Chad Showalter
  • 211
  • 1
  • 12
  • Have you compiled your Mongo entities with `-parameters`? – Andy Wilkinson Mar 03 '23 at 09:42
  • @Andy Wilkinson No, we have not. In looking closer at [the docs](https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/) I see that this is mentioned under Customized Object Construction. We do frequently have entities with multiple constructors and use @PersistenceConstructor/Creator to indicate the one to be used by the framework. Until the upgrade to Spring Boot 3, this "just worked." Is compiling with `-parameters` a reasonable pattern for this scenario? It does indeed eliminate the errors in our case when I do so. – Chad Showalter Mar 03 '23 at 12:31
  • Yes, it's both reasonable and recommended. The change in behavior in Spring Boot 3.0 is due to [this change in Spring Framework 6.0](https://github.com/spring-projects/spring-framework/pull/29531). – Andy Wilkinson Mar 03 '23 at 12:36
  • Okay, and thanks. Regarding the compiler flag, is it reasonable/recommended to compile our entire java codebase with `-parameters` or would it be better to somehow segment compilation between parts of our codebase that need it and those that do not? E.g. compile the entities as their own artifact. Or some other way. – Chad Showalter Mar 03 '23 at 13:03
  • If it were me, I'd turn it on everywhere. It may increase class sizes a little but I would not expect the effect to be too dramatic. I'd only split things into separate artifacts if really necessary. – Andy Wilkinson Mar 03 '23 at 13:35

1 Answers1

3

Due to these changes in Spring Framework 6.0, the use of the -parameters compiler option is now strongly encouraged. It allows the names of constructor and methods parameters to be discovered without having to resort to extracting them from debug information in .class files.

Spring Framework 6's upgrade guide has the following to say on this topic:

LocalVariableTableParameterNameDiscoverer is deprecated now and logs a warning for each successful resolution attempt (it only kicks in when StandardReflectionParameterNameDiscoverer has not found names). Compile your Java sources with the common Java 8+ -parameters flag for parameter name retention (instead of relying on the -debug compiler flag) in order to avoid that warning, or report it to the maintainers of the affected code. With the Kotlin compiler, we recommend the -java-parameters flag for completeness.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242