-
-
Notifications
You must be signed in to change notification settings - Fork 734
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
'object is not an instance of declaring class' when runnig on SpringBoot2/HikariCP #742
Comments
➕ Added dependecies.txt file with all the versions of all the libraries/frameworks used in the app. |
I do not reproduce the exception using spring boot 2.0.1. Note that calling So can you give the source of a simple project to reproduce the issue? |
@evernat,
In our case it is setBeanFactory method that triggered initialization of the proxy. 💡 As a proof-of-concept I created a sample project that reliably reproduces the issue. To switch between successful and failure scenarios just [un]comment line 39 in build.gradle. Actually I don't see any simple solution now. But I'm going to try to apply a workaround with the methods I found during debugging. Please let me know if you have any ideas. |
Thanks for finding the cause and for the sample project. javamelody.excluded-datasources=scopedTarget.dataSource That said I don't know why Spring Cloud is messing up with the Spring Boot dataSource and with the Spring Boot proxies (as a reminder, the HikariDataSource does not have a RefreshScope annotation). |
The suggested workaround does allow the application to start but it hardly pretends to be a solution because one of the main goals of using JavaMelody in the project is monitoring of JDBC connections and SQL queries. Other workarounds I've mentioned early also passed by as Spring Cloud forces the use of public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config); // HERE is the 'wrong' decision
}
else {
return new JdkDynamicAopProxy(config);
}
}
// ...
} Perhaps there is a way to alternate value of |
I've eventually found relatively admissible workaround - I've switched Spring Boot back to Tomcat JDBC pool (the one it used until 2.x generation). Thanks to full conformation to You can find the fix in the second commit to sample project. |
yes, that's a a better workaround |
P.S. @evernat, I've updated sample project with a commit to easily reproduce new exception. |
@evernat , @Toparvion , I think the issue is due to Spring re-lookups datasource bean, and Spring assumes the bean is always springcglib-based: https://github.com/spring-projects/spring-framework/blob/c037e75f26ac5ef69e4d5fc3045e101ca674dcaf/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java#L672 However, JavaMelody post-processor wraps the bean, which defeats the thing. Apparently Spring allows to wrap beans into proxies in post processors, so I think the issue is to be resolved at the Spring side. |
@evernat, to clarify @vlsi's comment, the implementation behind aforementioned @Override
public Object getTarget() throws Exception {
return getBeanFactory().getBean(getTargetBeanName());
} i.e. searches Spring context for the bean again instead of just 'directly getting' the target from some field. Since the search is performed on behalf of I agree with @vlsi that the issue should be resolved in Spring: SPR-17381. |
Here is a solution - https://github.com/Toparvion/joker-2018-samples/tree/master/hikari-javamelody - use google translate to translate from Russian.
|
@Toparvion @fedotxxl |
Wrapping Hikari is another workaround that worked for me:
|
I'm trying to use JavaMelody Spring Boot Starter (1.72.0) in application built upon Spring Boot 2.0.1.RELEASE which in turn uses HikariCP 2.7.8 connection pool. But the application fails to start due to the following exception:
If I comment out the dependency from JavaMelody starter, application starts fine.
ℹ️ During debugging I've found out that the exception occur when initializing logic tries to call method
public java.lang.String com.zaxxer.hikari.HikariConfig.getConnectionTestQuery()
on the following classes instances:The problem is that method
HikariDataSourcePoolMetadata#getValidationQuery
relies on methodcom.zaxxer.hikari.HikariConfig#getConnectionTestQuery
which is not part ofjavax.sql.DataSource
interface. But JavaMelody wrapper conforms to that interface only and thus cannot correctly handle the invocation ofgetConnectionTestQuery
method.While it seems not a bug of JavaMelody (but HikariCP config in SpringBoot2) I'd like you to check my groundwork and may be propose a workaround.
Additional info on reproducing the issue can be provided.
The text was updated successfully, but these errors were encountered: