-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Using TransactionManagementConfigurer causes StackOverflowError that results in NoClassDefFoundError for FatalBeanException [SPR-10787] #15413
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
Comments
Nick Williams commented Test project attached. |
Juergen Hoeller commented I'll do a deep dive with this ASAP but just for the moment: You could define a JpaTransactionManager bean without an EntityManagerFactory bean reference, letting it find the EntityManagerFactory by default - or you could specify the "persistenceUnitName" property instead. Both of those options avoid early initialization problems with the EntityManagerFactory. Juergen |
Nick Williams commented Juergen Hoeller, are you not going to be able to get this fixed for 4.0.0? That's disappointing. This is a pretty major bug; there's no way to have more than one |
Juergen Hoeller commented I assumed the workaround above (using "persistenceUnitName" values instead of direct EntityManagerFactory references) would work? That's why I didn't consider it critical... That aside, admittedly, we're running out of time in terms of bug fix work towards 4.0 GA. Design decisions (of which we have a few left, e.g. new module interdependencies) are more important at this point, so we can only research very few bugs for RC2 and GA now. Note that bug reports with a clearly pointed-out cause/solution fall into the "low-hanging fruit" category and are still likely to make it. We just can't spend a lot of time reproducing bugs and researching them at this point. We're going to pick up bugs again as of January, for delivering a whole bunch of user-requested fixes in 4.0.1 and 3.2.6 (scheduled for late January / early February). Juergen |
Nick Williams commented If I understand the workaround correctly, which I may not, it still wouldn't work if you had two |
Juergen Hoeller commented The "persistenceUnitName" property is available quite consistently, so can be specified on the EntityManagerFactoryBeans as well as on JpaTransactionManager beans and other JPA accessors. Basically, there is no need to ever link to an EntityManagerFactory directly; relationships between JPA-accessing components can always be expressed through the persistence unit name. This is very much in the spirit of the JPA specification: see persistence.xml, As for this report, it just never reached the top of the list. Like everybody else, we have limited resources, and every day we're getting new stuff pushed onto our plate. In all fairness, four months is not a lot of time; check the bug tracker of a few other open source projects (hint: OpenJDK, Hibernate) and you'll find bugs that have been open for many years. We're not perfect there either, but at least we're trying to catch up with unaddressed reports in the issue tracker every year - typically after each major release. Juergen |
Nick Williams commented Juergen, I may be missing something, but I don't think this statement is accurate:
The Thus, if you create two |
Michael Wyraz commented This bug is still pressent in 4.0.6. It seems to be a regression to #14894 |
Juergen Hoeller commented Michael, what kind of stack trace do you get? Any specific indication for the cause of the stack overflow? Juergen |
sateesh kumar kapu commented Juergen, Recently when we upgraded to 4.1.2.Release from 3.0.6, I was facing similar StackOverflowError issue while initializing one of our bean. Find the stack trace below. When I pulled spring-beans source and debugged, I found while checking for isDependent, it is going through transitive dependencies recursively. In my product's application context we do have circular dependencies and while parsing through transitive dependencies list, it was resulting into StackOverflowError. I gone ahead and fix the method "DefaultSingletonBeanRegistry()" by adding extra argument "parents" (refer to code snippet below) to ignore if the same bean reappears in the dependency path. /**
The above fixed just worked for me. I am not sure whether this is a good fix and this won't break something else. However when I saw similar method in the 3.0.6, I found we never had code that goes into recursion and that is the reason it was working for us earlier.: Can you let me know if this is the right fix ? or if not can you suggest what needs to be done. |
Juergen Hoeller commented I've fixed that potential Juergen |
Nick Williams opened SPR-10787 and commented
This one was a doozy and took me three hours just to figure it out...
This may affect earlier versions as well, I don't know. I've only been working with 4.0 lately. I don't see why it would just now be happening, because I don't see any major changes in this area.
I've been using Java configuration in a project just fine. I added
@EnableTransactionManagement
, aDataSource
, aLocalContainerEntityManagerFactoryBean
, and aJpaTransactionManager
to the configuration (I didn't add anything else), implementedTransactionManagementConfigurer
, and suddenly started getting the followingNoClassDefFoundError
on startup.As you can plainly see, I have spring-beans.jar on the classpath, so the
NoClassDefFoundError
is clearly a symptom and not the actual error. I put a breakpoint atinstantiateUsingFactoryMethod
line 584 and saw this actual error being caught:I spent considerable time debugging, but there's a LOT of code to step through. Here's essentially what's happening, as far as I can tell:
entityManagerFactoryBean()
to create that beanentityManagerFactoryBean()
callsspringJpaDataSource()
to look up theDataSource
springJpaDataSource()
(my code, at least) returns, but before the CGLib'd wrapperspringJpaDataSource()
can return control toentityManagerFactoryBean()
, Spring for some reason decides it needs to callannotationDrivenTransactionManager()
specified byTransactionManagementConfigurer
. THIS IS WHERE THE PROBLEM STARTSannotationDrivenTransactionManager()
callsjpaTransactionManager()
, which creates the actualJpaTransactionManager
bean.jpaTransactionManager()
callsentityManagerFactoryBean()
to get theEntityManagerFactory
to pass to theJpaTransactionManager
constructor.entityManagerFactoryBean()
callsspringJpaDataSource()
to look up theDataSource
StackOverflowError
.If I comment out
implements TransactionManagementConfigurer
and theannotationDrivenTransactionManager()
error, everything works great.Have fun. This one's craaazy. Marked it "blocker" because it doesn't appear to be possible to use
TransactionManagementConfigurer
, meaning you can't have more than onePlatformTransactionManager
.I'll attach a replication project shortly. It requires Java 8.
Affects: 4.0 M2
Attachments:
Backported to: 4.0.9
1 votes, 7 watchers
The text was updated successfully, but these errors were encountered: