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

In a native image, configuration property binding fails when the target has package-private getters and setters #35397

Closed
wilkinsona opened this issue May 11, 2023 · 0 comments
Labels
type: bug A general bug
Milestone

Comments

@wilkinsona
Copy link
Member

wilkinsona commented May 11, 2023

BindableRuntimeHintsRegistrar does not generate reflection hints to allow package-private getters and setters to be invoked. Previously, this resulted in such methods being silently ignored. It has now started failing due to Framework adding a query all methods hint for every bean. This allows the binder to find the package-private methods but a failure then occurs when it tries to invoke them.

One example of this failing can be found in Spring Cloud:

Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: Runtime reflection is not supported for java.util.Map org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryProperties.getInstances()
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) ~[na:na]
	at java.base@17.0.5/java.lang.reflect.Method.acquireMethodAccessor(Method.java:71) ~[cloud-gateway:na]
	at java.base@17.0.5/java.lang.reflect.Method.invoke(Method.java:566) ~[cloud-gateway:na]
	at org.springframework.boot.context.properties.bind.JavaBeanBinder$BeanProperty.lambda$getValue$0(JavaBeanBinder.java:357) ~[na:na]
	at org.springframework.boot.context.properties.bind.MapBinder.getExistingIfPossible(MapBinder.java:110) ~[na:na]

The getters and setters on SimpleReactiveDiscoveryProperties look like this:

	public Flux<ServiceInstance> getInstances(String service) {
		return Flux.fromIterable(instances.getOrDefault(service, emptyList()));
	}

	Map<String, List<DefaultServiceInstance>> getInstances() {
		return instances;
	}

	public void setInstances(Map<String, List<DefaultServiceInstance>> instances) {
		this.instances = instances;
	}

	public DefaultServiceInstance getLocal() {
		return this.local;
	}

	public int getOrder() {
		return this.order;
	}

	public void setOrder(int order) {
		this.order = order;
	}

The map binder tries to call getInstances() so that it can merge any existing values with those being bound. This call now fails. Previously, the getInstances() method would not have been found so any existing values would have been overwritten.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

1 participant