GoogleCloudPlatform / GoogleCloudPlatform/spring-cloud-gcp

Address native image runtime failure for spring-cloud-gcp-data-spanner-repository-sample

Open
#2,343 2 comments 0 reactions 0 assignees View on GitHub
priority: p2 spanner type: enhancement
Dominant language
Java
Stars
551
Forks
349
Avg merge
1d 13h
Merged PRs (30d)
14

Description

Command: `mvn clean test --activate-profiles native-sample-config,nativeTest --define notAllModules=true -Dmaven.javadoc.skip=true -Dcheckstyle.skip -Dtests=com.example.SpannerRepositoryIntegrationTests#testRestEndpointPut`

Results in:
```
JUnit Jupiter:SpannerRepositoryIntegrationTests:testRestEndpoint()
MethodSource [className = 'com.example.SpannerRepositoryIntegrationTests', methodName = 'testRestEndpoint', methodParameterTypes = '']
=> java.lang.IllegalStateException: Failed to load ApplicationContext for [AotMergedContextConfiguration@4cc91e70 testClass = com.example.SpannerRepositoryIntegrationTests,
...
[...]
Caused by: org.graalvm.nativeimage.MissingReflectionRegistrationError: The program tried to reflectively invoke method public synchronized int org.apache.coyote.AbstractProtocol.getNameIndex() without it being registered for runtime reflection. Add it to the reflection metadata to solve this problem. See https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection for help.
org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.forQueriedOnlyExecutable(MissingReflectionRegistrationUtils.java:97)
java.base@17.0.7/java.lang.reflect.Method.acquireMethodAccessor(Method.java:77)
java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:566)
org.apache.tomcat.util.IntrospectionUtils.getProperty(IntrospectionUtils.java:250)
org.apache.catalina.connector.Connector.getProperty(Connector.java:298)
[...]
```
Adding the following reflection configs as suggested resolves the previous error but results in an NPE at https://github.com/GoogleCloudPlatform/spring-cloud-gcp/blob/28ab0c29e5763df42e986e8c31a9fe5a22fa0416/spring-cloud-gcp-samples/spring-cloud-gcp-data-spanner-repository-sample/src/test/java/com/example/SpannerRepositoryIntegrationTests.java#L87
```
[
{
"name":"org.apache.coyote.AbstractProtocol",
"queryAllPublicMethods":true,
"queryAllDeclaredMethods":true,
"methods":[{"name": "getName", "parameterTypes":[]},{"name": "getNameIndex", "parameterTypes":[]},{"name":"getAddress","parameterTypes":[] }, {"name":"getLocalPort","parameterTypes":[] }, {"name":"setPort","parameterTypes":["int"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }]
}
]
```

Stacktrace:
```
com.example.SpannerRepositoryIntegrationTests > testRestEndpoint() FAILED

com.example.SpannerRepositoryIntegrationTests > testLoadsCorrectData() SUCCESSFUL

com.example.SpannerRepositoryIntegrationTests > testRestEndpointPut() FAILED

com.example.SpannerRepositoryIntegrationTests > testJsonAndArrayJsonFieldReadWrite() SUCCESSFUL

com.example.SpannerRepositoryMultiDatabaseIntegrationTests > testLoadsCorrectData() SUCCESSFUL

Failures (2):
JUnit Jupiter:SpannerRepositoryIntegrationTests:testRestEndpoint()
MethodSource [className = 'com.example.SpannerRepositoryIntegrationTests', methodName = 'testRestEndpoint', methodParameterTypes = '']
=> java.lang.NullPointerException
com.example.SpannerRepositoryIntegrationTests.testRestEndpoint(SpannerRepositoryIntegrationTests.java:87)
java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568)
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
[...]
JUnit Jupiter:SpannerRepositoryIntegrationTests:testRestEndpointPut()
MethodSource [className = 'com.example.SpannerRepositoryIntegrationTests', methodName = 'testRestEndpointPut', methodParameterTypes = '']
=> java.lang.AssertionError:
expected: Trader{traderId='t123', firstName='John', lastName='Smith', createdOn=2000-01-02 03:04:05.0, modifiedOn=[2000-01-02 03:04:05.0]}
but was: null
com.example.SpannerRepositoryIntegrationTests.testRestEndpointPut(SpannerRepositoryIntegrationTests.java:117)
java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568)
org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
[...]

```

Contributor guide

Open the contributing guide

Research direction

Start by rerunning the native test command against spring-cloud-gcp-data-spanner-repository-sample and inspect SpannerRepositoryIntegrationTests at lines 87 and 117 alongside the MissingReflectionRegistrationError. Investigate the reflection metadata involved in the native runtime failure and verify that testRestEndpoint and testRestEndpointPut pass without the reported NPE or null result.

Written by the indexing model from the issue text.

Assessment

Tech stack
google-cloud, java, spring
Domain
database, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.