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

Fail early FactoryBean instantiation for LinkageError #26425

Conversation

liudongmiao
Copy link

In 0288878 to resolve gh-22409, a little bug was introduced:
if there is LinkageError in FactoryBean instantiation, no first exception.

In JVM, if a class cannot be initialized, it acts like this:

  • at the first time, it will show the real reason and stack
  • then, only show "NoClassDefFoundError: Could not initialize class xxx"

In 0288878 to resolve gh-22409, a little bug was introduced:
if there is LinkageError in FactoryBean instantiation, no first exception.

In JVM, if a class cannot be initialized, it acts like this:
- at the first time, it will show the real reason and stack
- then, only show "NoClassDefFoundError: Could not initialize class xxx"
@pivotal-issuemaster
Copy link

@liudongmiao Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-issuemaster
Copy link

@liudongmiao Thank you for signing the Contributor License Agreement!

@jhoeller jhoeller self-assigned this Jan 21, 2021
@jhoeller jhoeller added in: core Issues in core modules (aop, beans, core, context, expression) type: enhancement A general enhancement labels Jan 21, 2021
@jhoeller jhoeller added this to the 5.3.4 milestone Jan 21, 2021
@jhoeller jhoeller added the for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x label Jan 21, 2021
@spring-projects-issues spring-projects-issues added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-5.2.x Marks an issue as a candidate for backport to 5.2.x labels Jan 21, 2021
@liudongmiao
Copy link
Author

@jhoeller

Even the exception is recorded by onSuppressedException, however, the suppressedExceptions can be cleard without be added into relatedCause.

boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}

Sometimes recordSuppressedExceptions is false, and suppressedExceptions is not Empty, then it's been cleared without call addRelatedCause.

Even if I call addRelatedCause or don't clear suppressedExceptions, the log is confused.
Then I try every version from spring 4.2 to latest, find the affected version, and finally the commit 0288878.

If there is exception in class initializer, jvm acts like this:
- for the first time, show the real reason and stack
- then, mark the class in error state, throws only NoClassDefFoundError

This commit don't suppress any LinkageError during bean creation.
If there is exception in class initializer, jvm acts like this:
- for the first time, show the real reason and stack
- then, mark the class in error state, throws only NoClassDefFoundError

This commit don't suppress any LinkageError when set property
@jhoeller jhoeller closed this in defc246 Feb 14, 2021
jhoeller added a commit that referenced this pull request Feb 14, 2021
@jhoeller
Copy link
Contributor

I went with a custom ex.contains(LinkageError.class) check for the FactoryBean part, reusing some of your test code (with an author attribution). I left the PropertyAccessor part as-is since the initial exception does not really disappear there, it's rather the log output being somewhat complex there... due to the property batch update mechanism which should not get bypassed. Also, such XML-driven scenarios with linkage errors in setter methods seem rather rare, not worth making compromises for.

Thanks for the pull request in any case!

This was referenced Mar 13, 2021
@liudongmiao liudongmiao deleted the patch-factorybean-linkageerror branch November 8, 2021 09:16
lxbzmy pushed a commit to lxbzmy/spring-framework that referenced this pull request Mar 26, 2022
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: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Directly registered FactoryBeans are instantiated more aggressively than those defined via @Bean methods
4 participants