On Spring Petclinic during a native build or a JVM one with the AOT plugin enabled, if I change the pom.xml to use tomcat-jdbc as following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
I get the following exception while building the application:
Exception in thread "main" org.springframework.boot.context.properties.bind.MissingParametersCompilerArgumentException: Constructor binding in a native image requires compilation with -parameters but the following classes were compiled without it:
org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorProperty
at org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrar.registerHints(BindableRuntimeHintsRegistrar.java:100)
at org.springframework.boot.context.properties.ConfigurationPropertiesBeanFactoryInitializationAotProcessor$ConfigurationPropertiesReflectionHintsContribution.applyTo(ConfigurationPropertiesBeanFactoryInitializationAotProcessor.java:74)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78)
Would be nice if the registrar would ignore failures due to a lack of parameter information. Notice the application works fine without AOT involved.
Comment From: wilkinsona
Test that reproduces the problem:
@Test
void registerHintsDoesNotThrowWhenParameterInformationForConstructorBindingIsNotAvailable()
throws NoSuchMethodException, SecurityException {
Constructor<?> constructor = PoolProperties.InterceptorProperty.class.getConstructor(String.class, String.class);
String[] parameterNames = new StandardReflectionParameterNameDiscoverer().getParameterNames(constructor);
assertThat(parameterNames).isNull();
assertThatNoException().isThrownBy(() -> registerHints(PoolProperties.class));
}
Comment From: jukekxm
I checked the commit that added MissingParametersCompilerArgumentException.
I think you should attach '-parameters' to build.gradle unconditionally when building with native image.
https://github.com/spring-projects/spring-boot/commit/421f2fac6769be39aa443b764cad54d433a40aa6
Also, if you check the issue below, it seems that another error will occur if you do not throw MissingParametersComputerArgumentException.
https://github.com/spring-projects/spring-boot/issues/33182
Comment From: mhalbritter
The line which throws the exception has been added in https://github.com/spring-projects/spring-boot/issues/33182.
If we remove the exception, the build works, but the application still doesn't work on native, because without -parameters the LocalVariableTableParameterNameDiscoverer fallback is used (which doesn't work in a native image).
Comment From: wilkinsona
@mhalbritter Can you share the failure? I'm not sure why we're trying to bind org.apache.tomcat.jdbc.pool.PoolProperties$InterceptorProperty at runtime. Hopefully the stack trace might shed some light on it.
Comment From: mhalbritter
Oh sorry, that was not clearly phrased. I haven't tested it, just read through the history of #33182.
Now that I've tested it, indeed the native image application works fine, even when using the spring.datasource.tomcat properties.
So this looks like a false positive of the early failure detection introduced in #33182.
Comment From: wilkinsona
Great, thank you. That's what I expected. I think this issue shows that the early failure detection is a bit too much as it may generate false positives. I think we should remove it.
Comment From: mhalbritter
The chain it follows is: PoolProperties -> InterceptorDefinition[] getJdbcInterceptorsAsArray() -> InterceptorDefinition -> Map<String, InterceptorProperty> getProperties() -> InterceptorProperty -> constructor InterceptorProperty(String name, String value). Because it has decided for InterceptorProperty to use constructor binding, it checks if it has been compiled with -parameters, which it hasn't, and then it fails.
Comment From: mhalbritter
I have removed the exception.