Skip to content
This repository was archived by the owner on Feb 23, 2023. It is now read-only.

Add more Spring Integration native hints #894

Closed

Conversation

artembilan
Copy link
Contributor

  • The IntegrationFlow interface can be proxied at runtime
  • The resource pattern for JDBC schemas should really be a regex pattern
  • The HTTP and WebFlux request mappings need a reflection access to
    method of their handlers to map
  • Process interfaces with a @MessagingGateway and register their
    proxy hints
  • Improve IntegrationApplication in the sample to cover the mentioned
    above cases about an IntegrationFlow proxy and @MessagingGateway

@artembilan
Copy link
Contributor Author

This PR depends on: spring-projects/spring-integration#3586.

A couple observation:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:315)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder$1.provider(DnsServerAddressStreamProviders.java:140)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder$1.<init>(DnsServerAddressStreamProviders.java:120)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder.<clinit>(DnsServerAddressStreamProviders.java:118)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders.unixDefault(DnsServerAddressStreamProviders.java:107)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders.platformDefault(DnsServerAddressStreamProviders.java:103)
        at io.netty.resolver.dns.DnsNameResolverBuilder.<init>(DnsNameResolverBuilder.java:60)
        at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:432)
        at reactor.netty.tcp.TcpResources.getOrCreateDefaultResolver(TcpResources.java:306)
        at reactor.netty.http.HttpResources.getOrCreateDefaultResolver(HttpResources.java:140)
        at reactor.netty.http.client.HttpClientConfig.defaultAddressResolverGroup(HttpClientConfig.java:383)
        at reactor.netty.transport.ClientTransportConfig.resolverInternal(ClientTransportConfig.java:219)
        at reactor.netty.http.client.HttpClientConfig.resolverInternal(HttpClientConfig.java:437)
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:265)
        at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
        at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:76)
        at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:272)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4150)
        at reactor.core.publisher.Mono.block(Mono.java:1726)
        at com.example.integration.IntegrationApplication.main(IntegrationApplication.java:46)
Caused by: java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:199)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:221)
        at sun.net.dns.ResolverConfigurationImpl.stringToList(ResolverConfigurationImpl.java:69)
        at sun.net.dns.ResolverConfigurationImpl.loadConfig(ResolverConfigurationImpl.java:104)
        at sun.net.dns.ResolverConfigurationImpl.nameservers(ResolverConfigurationImpl.java:127)
        at com.sun.jndi.dns.DnsContextFactory.serversForUrls(DnsContextFactory.java:149)
        at com.sun.jndi.dns.DnsContextFactory.getContext(DnsContextFactory.java:81)
        at com.sun.jndi.dns.DnsContextFactory.urlToContext(DnsContextFactory.java:120)
        at com.sun.jndi.dns.DnsContextFactory.getInitialContext(DnsContextFactory.java:64)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
        at javax.naming.InitialContext.init(InitialContext.java:236)
        at javax.naming.InitialContext.<init>(InitialContext.java:208)
        at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at io.netty.resolver.dns.DirContextUtils.addNameServers(DirContextUtils.java:49)
        at io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.<clinit>(DefaultDnsServerAddressStreamProvider.java:53)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        ... 25 more

This might be a Graal VM problem with DNS resolution. Or netty. Or we need to configure WebClient some way to avoid such a DNS resolution. It happens only once: seems on a first request. Application works well after that anyway. Or I miss something...

The interface with my @MessagingAnnotation has to be in a top-level file: it is not visible by type system when I place it as an inner class in the main one what is typically done in the target applications though.

@artembilan
Copy link
Contributor Author

OK. Turns out it doesn't work well.
Tried to follow webclient sample in the project and reworked my code to rely on the WebClient.Builder bean from the application context.
Here is an exception:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webClientBuilder' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/WebClientAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.reactive.function.client.WebClient$Builder]: Factory method 'webClientBuilder' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clientConnectorCustomizer' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'clientConnectorCustomizer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactorClientHttpConnector' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration$ReactorNetty.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.client.reactive.ReactorClientHttpConnector]: Factory method 'reactorClientHttpConnector' threw exception; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1273)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1234)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1172)
        at com.example.integration.IntegrationApplication.main(IntegrationApplication.java:43)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.reactive.function.client.WebClient$Builder]: Factory method 'webClientBuilder' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clientConnectorCustomizer' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'clientConnectorCustomizer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactorClientHttpConnector' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration$ReactorNetty.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.client.reactive.ReactorClientHttpConnector]: Factory method 'reactorClientHttpConnector' threw exception; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
        ... 14 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clientConnectorCustomizer' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'clientConnectorCustomizer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactorClientHttpConnector' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration$ReactorNetty.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.client.reactive.ReactorClientHttpConnector]: Factory method 'reactorClientHttpConnector' threw exception; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1605)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1562)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1406)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1338)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2108)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2102)
        at org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration.webClientBuilder(WebClientAutoConfiguration.java:57)
        at java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
        ... 15 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactorClientHttpConnector' defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration$ReactorNetty.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.client.reactive.ReactorClientHttpConnector]: Factory method 'reactorClientHttpConnector' threw exception; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
        ... 34 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.client.reactive.ReactorClientHttpConnector]: Factory method 'reactorClientHttpConnector' threw exception; nested exception is java.lang.ExceptionInInitializerError
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
        ... 48 more
Caused by: java.lang.ExceptionInInitializerError
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:315)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder$1.provider(DnsServerAddressStreamProviders.java:140)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder$1.<init>(DnsServerAddressStreamProviders.java:120)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder.<clinit>(DnsServerAddressStreamProviders.java:118)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders.unixDefault(DnsServerAddressStreamProviders.java:107)
        at io.netty.resolver.dns.DnsServerAddressStreamProviders.platformDefault(DnsServerAddressStreamProviders.java:103)
        at io.netty.resolver.dns.DnsNameResolverBuilder.<init>(DnsNameResolverBuilder.java:60)
        at reactor.netty.transport.NameResolverProvider.newNameResolverGroup(NameResolverProvider.java:432)
        at reactor.netty.transport.ClientTransport.runOn(ClientTransport.java:354)
        at reactor.netty.transport.ClientTransport.runOn(ClientTransport.java:42)
        at reactor.netty.transport.Transport.runOn(Transport.java:247)
        at reactor.netty.http.client.HttpClientTcpConfig.runOn(HttpClientTcpConfig.java:189)
        at org.springframework.http.client.reactive.ReactorClientHttpConnector.lambda$initHttpClient$1(ReactorClientHttpConnector.java:85)
        at reactor.netty.http.client.HttpClient.tcpConfiguration(HttpClient.java:1494)
        at org.springframework.http.client.reactive.ReactorClientHttpConnector.initHttpClient(ReactorClientHttpConnector.java:85)
        at org.springframework.http.client.reactive.ReactorClientHttpConnector.<init>(ReactorClientHttpConnector.java:76)
        at org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorConfiguration$ReactorNetty.reactorClientHttpConnector(ClientHttpConnectorConfiguration.java:66)
        at java.lang.reflect.Method.invoke(Method.java:566)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
        ... 49 more
Caused by: java.lang.NullPointerException
        at java.util.StringTokenizer.<init>(StringTokenizer.java:199)
        at java.util.StringTokenizer.<init>(StringTokenizer.java:221)
        at sun.net.dns.ResolverConfigurationImpl.stringToList(ResolverConfigurationImpl.java:69)
        at sun.net.dns.ResolverConfigurationImpl.loadConfig(ResolverConfigurationImpl.java:104)
        at sun.net.dns.ResolverConfigurationImpl.nameservers(ResolverConfigurationImpl.java:127)
        at com.sun.jndi.dns.DnsContextFactory.serversForUrls(DnsContextFactory.java:149)
        at com.sun.jndi.dns.DnsContextFactory.getContext(DnsContextFactory.java:81)
        at com.sun.jndi.dns.DnsContextFactory.urlToContext(DnsContextFactory.java:120)
        at com.sun.jndi.dns.DnsContextFactory.getInitialContext(DnsContextFactory.java:64)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
        at javax.naming.InitialContext.init(InitialContext.java:236)
        at javax.naming.InitialContext.<init>(InitialContext.java:208)
        at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
        at io.netty.resolver.dns.DirContextUtils.addNameServers(DirContextUtils.java:49)
        at io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.<clinit>(DefaultDnsServerAddressStreamProvider.java:53)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:375)
        at com.oracle.svm.core.classinitialization.ClassInitializationInfo.initialize(ClassInitializationInfo.java:295)
        ... 69 more

Fails with the same DNS resolution problem.

Thanks

@artembilan
Copy link
Contributor Author

To be more precise: it fails with that error as a native .exe on my Windows.
When I run it in Docker, the WebClient works well. So, probably that DNS problem is indeed up to Graal VM by itself...

@artembilan
Copy link
Contributor Author

Found more reflection usage when it comes to Control Bus and its SpEL-based functionality...
Do not merge: stay tuned. 😄

@artembilan
Copy link
Contributor Author

NOTE: tried to add reflection for org.springframework.messaging.Message impls to meet SpEL requirements, but it fails with something like this:

[INFO] [ERROR] org.springframework.nativex.type.MissingTypeException: Unable to find class file for org/springframework/web/server/WebFilter
[INFO] [ERROR] [org.springframework.nativex.type.TypeSystem.resolveSlashed(TypeSystem.java:185), org.springframework.nativex.type.TypeSystem.resolveSlashed(TypeSystem.java:176), org.springframework.nativex.type.Type.getInterfaces(Type.java:235), org.springframework.nativex.type.Type.implementsInterface(Type.jav
a:351), org.springframework.integration.IntegrationHints.lambda$computeMessageHints$4(IntegrationHints.java:210), org.springframework.nativex.type.TypeProcessor.lambda$filter$13(TypeProcessor.java:314), java.base/java.util.function.BiPredicate.lambda$and$0(BiPredicate.java:73), org.springframework.nativex.type.
TypeProcessor.process(TypeProcessor.java:506), org.springframework.nativex.type.TypeProcessor.access$000(TypeProcessor.java:74), org.springframework.nativex.type.TypeProcessor$2.lambda$toProcessTypes$0(TypeProcessor.java:467), java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183), ja
va.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177), java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195), java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195), java.base/java.util.ArrayList$ArrayListSpliterator.forEachR
emaining(ArrayList.java:1655), java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658), java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274), java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655), java.base/java.util
.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484), java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474), java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150), java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(
ForEachOps.java:173), java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234), java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497), org.springframework.nativex.type.TypeProcessor$2.toProcessTypes(TypeProcessor.java:467), org.springframework.nativex.type.TypeP
rocessor$TypeHintCreatingProcessor.toProcessTypesMatching(TypeProcessor.java:744), org.springframework.nativex.type.TypeProcessor$TypeHintCreatingProcessor.processTypes(TypeProcessor.java:715), org.springframework.integration.IntegrationHints.computeMessageHints(IntegrationHints.java:215), org.springframework.i
ntegration.IntegrationHints.computeHints(IntegrationHints.java:168), org.springframework.nativex.type.SpringConfiguration.<init>(SpringConfiguration.java:60), org.springframework.nativex.type.TypeSystem.ensureSpringConfigurationDiscovered(TypeSystem.java:681), org.springframework.nativex.type.TypeSystem.getSpri
ngFactoryProcessors(TypeSystem.java:1071), org.springframework.nativex.support.ResourcesHandler.processSpringFactory(ResourcesHandler.java:755), org.springframework.nativex.support.ResourcesHandler.processSpringFactories(ResourcesHandler.java:697), org.springframework.nativex.support.ResourcesHandler.register(R
esourcesHandler.java:114), org.springframework.nativex.support.SpringAnalyzer.analyze(SpringAnalyzer.java:87), org.springframework.aot.nativex.ConfigurationContributor.contribute(ConfigurationContributor.java:70), org.springframework.aot.BootstrapCodeGenerator.generate(BootstrapCodeGenerator.java:75), org.sprin
gframework.aot.maven.TestGenerateMojo.execute(TestGenerateMojo.java:65), org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137), org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210), org.apache.maven.lifecycle.internal.MojoExecutor.execute(Mo
joExecutor.java:156), org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148), org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117), org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
, org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56), org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128), org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305), org.apache.maven.DefaultMaven.doExecut
e(DefaultMaven.java:192), org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105), org.apache.maven.cli.MavenCli.execute(MavenCli.java:957), org.apache.maven.cli.MavenCli.doMain(MavenCli.java:289), org.apache.maven.cli.MavenCli.main(MavenCli.java:193), java.base/jdk.internal.reflect.NativeMethodAccessorImp
l.invoke0(Native Method), java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.base/java.lang.reflect.Method.invoke(Method.java:566), org.codehaus.plexus.cl
assworlds.launcher.Launcher.launchEnhanced(Launcher.java:282), org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:225), org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:406), org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:347)]

Not sure why does it talk about WebFilter from that commented code:

	private static List<HintDeclaration> computeMessageHints(TypeSystem typeSystem) {
		return TypeProcessor.namedProcessor("IntegrationHints - Message")
				.skipAnnotationInspection()
				.skipMethodInspection()
				.skipFieldInspection()
				.skipConstructorInspection()
				.filter(type -> type.implementsInterface(MESSAGE_TYPE))
				.onTypeDiscovered((type, context) ->
						context.addReflectiveAccess(type,
								new AccessDescriptor(AccessBits.CLASS | AccessBits.PUBLIC_METHODS)))
				.use(typeSystem)
				.processTypes();
	}

on the filter() line.
What am I missing? Can anyone help me to understand what is going on?

Thanks

P.S. At the moment the PR is ready for merge: the Message concern does not appear in the test application, but can be addresses separately.

@christophstrobl
Copy link
Contributor

The filter method operates upon the resolved Type and it seems there's at least one that is extending/implementing WebFilter. Now Type.getInterfaces(), which is used in the filter predicate via implementsInterface, tries to resolve
WebFilter which is not available. This throws an error cause it's using typeSystem.resolveSlashed(...) which in turn does not allow missing types.

So there's a couple of things we could do here:

  • guard the filter with a try catch block
  • see if moving the filter to TypeProcessor.toProcessTypesMatching(...) helps (which I doubt)
  • make sure Type.getInterfaces() ignores the ones not available by calling typeSystem.resolveSlashed(..., true) (to be discussed since it's changing the behaviour).

@artembilan
Copy link
Contributor Author

Hi Christoph!
Thank you for feedback and suggestions!

Well, it really doesn't work with the toProcessTypesMatching() which I had in the beginning.
It fails when it build an AOP plugin if that gives any clue...
That's really a surprise this issues hasn't popped before with this implementsInterface().

@aclement
Copy link
Contributor

aclement commented Jul 8, 2021

@artembilan have you tried running your thing with the agent to collect missing config - does it fix the DNS resolution problem?

@artembilan
Copy link
Contributor Author

@aclement ,

thank you for suggestion, but I'm not sure how to proceed with that.
I added this into my POM:

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<argLine>-DspringAot=true -agentlib:native-image-agent=access-filter-file=src/main/resources/access-filter.json,config-merge-dir=target/classes/META-INF/native-image</argLine>
				</configuration>
			</plugin>

according Docs: https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#tracing-agent-testing.
The .exe is built fine, but I don't see any difference in the output in that target/classes/META-INF/native-image dir.

Not relevant to this problem, but I see that CI has failed for my PR and looks like the change in the core project is not installed to Maven local before running samples to verify.
Locally I build core project and install it then I build the sample to be sure that latest changes are pulled.
So, my assumption that pipeline for the PR does not rely on the core change in the end.
Am I missing anything?
Thanks

@artembilan artembilan force-pushed the more_integration_hints branch from 0c3716f to 0e875a4 Compare July 15, 2021 20:47
@artembilan
Copy link
Contributor Author

The latest commit depends on: spring-projects/spring-integration#3590.
That Spring Integration version version is due next week.

@sdeleuze
Copy link
Contributor

Should I merge it now that we use Spring Boot 2.5.3-SNAPSHOT?

@artembilan
Copy link
Contributor Author

Let me release Spring Integration 5.5.2 right now and then I update the sample to rely on Spring Boot dependency management and then you can merge it.
Thanks

* The `IntegrationFlow` interface can be proxied at runtime
* The resource pattern for JDBC schemas should really be a regex pattern
* The HTTP and WebFlux request mappings need a reflection access to
method of their handlers to map
* Process interfaces with a `@MessagingGateway` and register their
proxy hints
* Improve `IntegrationApplication` in the sample to cover the mentioned
above cases about an `IntegrationFlow` proxy and `@MessagingGateway`
* Use `WebClient.Builder` bean from the ctx for application logic
…equirements

* Add some common types to satisfy common SpEL expressions
Spring AOT plugin fails with no `WebFilter` class on `type.implementsInterface()`
* Add more Spring Integration types specific to `MessageStore` serialization functionality
* Add programmatic scan for `IntegrationNode` impls instead of huge number of
explicit types in `@TypeHint`
* Add `JdbcChannelMessageStore` logic into the sample to cover its serialization functionality
* Add programmatic scan for `IntegrationNode` impls instead of huge number of
explicit types in `@TypeHint`
* Add `JdbcChannelMessageStore` logic into the sample to cover its serialization functionality
* Add `RedisChannelMessageStore` logic into the sample to cover JSON (un)marshaling feature
@artembilan artembilan force-pushed the more_integration_hints branch from 0e875a4 to 3fd97ab Compare July 20, 2021 18:27
@artembilan
Copy link
Contributor Author

Rebased to the latest main and removed an explicit Spring Integration version from the sample.
Now it is ready for merge.
Thanks

@sdeleuze sdeleuze added type: compatibility Native image compatibility issue and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jul 22, 2021
@sdeleuze sdeleuze added this to the 0.10.2 milestone Jul 22, 2021
@sdeleuze sdeleuze self-requested a review July 22, 2021 11:16
Copy link
Contributor

@sdeleuze sdeleuze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me, I just noticed a pretty high memory footprint, so maybe something to fine tune after our 0.11 improvements.

@sdeleuze sdeleuze closed this in bdb85a0 Jul 23, 2021
@artembilan
Copy link
Contributor Author

Thanks, @sdeleuze, for taking care about this!

I wonder if you can share with me some guidance how you measure that memory, so perhaps I can investigate that myself from Spring Integration perspective.
Although it is already not a surprise since Spring Integration really loads enough classes and creates many beans for its infrastructure and end-user configuration support.
See more info in this JIRA: https://jira.spring.io/browse/INT-4483

@sdeleuze
Copy link
Contributor

Sure, you can measure it with ps -o rss ${PID} after startup. See also this related comment.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: compatibility Native image compatibility issue
Development

Successfully merging this pull request may close these issues.

5 participants