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.