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

Properties not resolved on FactoryBean initialization for beans defined in XML #1195

Open
krysz-clgx opened this issue Jan 17, 2023 · 0 comments

Comments

@krysz-clgx
Copy link

Describe the bug
Spring Cloud Commons: 4.0.0
Spring Boot: 3.0.1

This issue is strictly related to: #439 and spring-cloud/spring-cloud-config#1167

I've been using the Spring Cloud to connect to a config server on PCF, unfortunately it is some legacy code with beans declared in old-XML fashion way. We have theorg.springframework.transaction.interceptor.TransactionProxyFactoryBean as an abstract bean (defined in beans.xml file) which is parent to couple of specific bean instances. One of them does not contain the class attribute in definition. All of these instances contains transactionManager which has the sessionFactory which has our OracleDataSource class as property. The last one needs username/password/url to be properly initialized. They should be resolved from application.yml file.
Everything was working correctly until we migrated to the PCF. For some reason the SpringBoot started to throw the BeanCreationException:

Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is java.sql.SQLException: Invalid Oracle URL specified: OracleDataSource.makeURL

This URL is indeed null.

It is caused by calling this instruction:

it starts the cascade of bean creation if it cannot predict type or the type is assignable to FactoryBean.
It turned out the the DefaultListableBeanFactory used here does not have properly initialized properties (or PostProcessors?)

To wrap it up: it can happen only if:

  • we have the spring-cloud enabled
  • the bean is defined in XML without the class attribute
  • the bean implements org.springframework.beans.factory.FactoryBean<> interface

The simplest workaround is just defining the missing attribute but since it is not required by default I consider it as a bug.

Sample
The complete application to recreate this issue:
https://github.com/krysz/spring-cloud-commons-xml-bug

It contains BaseBean which is the instance of FactoryBean, the ChildBean defined in XML without class attribute and the DataSource bean with injected property. If you disable spring-cloud or add the class attribute the whole application runs fine and prints 42 as property value but with my provided configuration it fails with error: Caused by: java.lang.InstantiationException: Could not initialize dataSource with someProperty!

I think @D0rmouse correctly identified the root cause of it:

They fixed a initialization cascade, but the log from the demo project shows that the properties are loaded and should be resolvable when the FactoryBean is initialized.

And he also proposed the solution:

I would say you first load the properties and then instantiate any FactoryBeans that require properties, or not even load any FactoryBeans before loading the properties. The latter is probably not possible, because FactoryBeans are involved in loading properties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants