Open linux-china opened 3 years ago
@linux-china , do you experience any issue when running your app as spring-native
?
@jvmlet I did some testing, and I found the problem is io.grpc:grpc-netty-shaded which is not supported by spring native, but grpc-netty is ok with spring native.
@jvmlet with #203 support, I upgraded my demo and the link is https://github.com/linux-china/grpc-native-demo
Spring Native and grpc-spring-boot-starter almost work well, but a problem is Spel with Spring Native, and issue link is https://github.com/spring-projects-experimental/spring-native/issues/768
I just find one place to use Spel in grpc-spring-boot-starter, could you use @ConditionalOnProperty(name = "grpc.inProcessServerName", havingValue = "")
to replace @ConditionalOnExpression()
?
@Bean
@ConditionalOnExpression("#{environment.getProperty('grpc.inProcessServerName','')!=''}")
public GRpcServerRunner grpcInprocessServerRunner(@Qualifier("grpcInternalConfigurator") Consumer<ServerBuilder<?>> configurator) {
return new GRpcServerRunner(configurator, InProcessServerBuilder.forName(grpcServerProperties.getInProcessServerName()));
}
removeSpelSupport
can make compiling faster and native binary file smaller.
@linux-china , can you please try with 4.4.8-SNAPSHOT
?
BTW, replacing @ConditionalOnExpression("#{environment.getProperty('grpc.inProcessServerName','')!=''}")
with @ConditionalOnProperty(name = "grpc.inProcessServerName", havingValue = "")
will brake backward compatibility for users who choose to call the in-process-server as literal false
;-)
Anyway, users also ask to support @PreAuthorize
and @PostAuthorize
spring security annotations (#175), need to be careful with these as well...
@jvmlet yes, it works with 4.4.8-SNAPSHOT. 👍
Now I use native-image-agent to get reflect and resource config for grpc-spring-boot-starter, if possible, could you add src/main/resources/META-INF/native-image/io.github.lognet/grpc-spring-boot-starter/reflect-config.json and src/main/resources/META-INF/native-image/io.github.lognet/grpc-spring-boot-starter/resource-config.json files for native-image support, you can refer json files on https://github.com/linux-china/grpc-native-demo/tree/master/src/main/resources/META-INF/native-image
I'm not sure that it's necessary to add reflect-config.json for grpc-client-spring-boot-starter module.
Sure, I'll add them. But I wonder how all original spring boot starters, like web and jpa, work with native app without these files? This is what I asked in https://github.com/spring-projects-experimental/spring-native/issues/710 but didn't get the clear answer.... Do you have a clue?
From https://www.graalvm.org/reference-manual/native-image/BuildConfiguration/ you don't need to import org.springframework.experimental:spring-native
and add native-image support, and it's good choice to add json config file because it works well with normal Java Apps and Spring native apps. grpc-spring-boot-starter is very not complicated to work with native image, and my suggestion is to add configuration files.
Yes, I will add it, just want to know how standard spring boot starters support spring native... They don't have such files in META-INF directory...
Yes probably better to just provide JSON configuration, I will update the guidelines in Spring Native to make that more clear.
Thanks @sdeleuze, Can you please point me to json files in standard jpa/web spring boot starters? Or any other sources in these repositories that make jpa and web starters supported by spring native.
I can't because those files are generated dynamically by Spring Native. JPA and web starters are supported out of the box by Spring Native. Do no need some sample reflect-config.json
or something else?
So as far as I understand, they are generated and packaged in distributable jar, can you please confirm it @sdeleuze? I also don't see spring native dependencies in these projects (jpa/web starters)....
@linux-china , I've created branch here The build fails with
Execution failed for task ':grpc-spring-boot-starter-native-demo:generateAot'.
> Unable to find class file for com/ecwid/consul/v1/agent/model/NewService$Check
Can you please have a look ?
@linux-china , please try with io.github.lognet:grpc-spring-boot-starter:4.5.4-SNAPSHOT
, I've also added demo here
@linux-china , does it work for you ?
@linux-china , does it work for you ?
It works for me. But I should still add some reflect config for gRPC, and reflect config example is
If I remove reflect config for gRPC and I will get following exception:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'grpcServerRunner' defined in class path resource [org/lognet/springboot/grpc/autoconfigure/GRpcAutoConfiguration.class]: Unsatisfied dependency expressed through method 'grpcServerRunner' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.grpc.ServerBuilder<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[na:na]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[na:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[na:na]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[na:na]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[na:na]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[na:na]
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:63) ~[na:na]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) ~[grpc-native-demo:2.4.5]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) ~[grpc-native-demo:2.4.5]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[grpc-native-demo:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) ~[grpc-native-demo:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[grpc-native-demo:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[grpc-native-demo:2.4.5]
at com.example.SpringBootApp.main(SpringBootApp.java:9) ~[grpc-native-demo:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.grpc.ServerBuilder<?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[na:na]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[na:na]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[na:na]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[na:na]
... 20 common frames omitted
Maybe reflect config for gRPC should be included in reflection-config.json.
@jvmlet regarding spring boot way of doing native things: They implements NativeConfiguration and add NativeHint's for AoT. After that they use service locator to find all classes implemented this interface, e.g.: https://github.com/spring-projects-experimental/spring-native/blob/main/spring-native-configuration/src/main/java/LoggingInitHints.java
As for a 3rd party components, according to their documentation, we need to put NativeHints on library configuration classes. If Spring AoT decides that this configuration is active, these hints will be applied.
Thanks, @ArtyomGabeev ,I'm generating the reflect-config.yml
by running test app in findepi/graalvm:java11-native
container (with native-image-agent
enabled) and then filtering out all starter-own classes to be included in final reflection-config.json
which is bundled in starter's jar (4.5.4-SNAPSHOT already has it)
The problem I'm experiencing now is that grpc related classes (io.grpc.netty.NettyServerBuilder
)are not generated by AOT if grpc dependencies come from maven-hosted jar, but if switched to project
dependencies, everything works as expected (see demo here).
Waiting for spring-aot-gradle-plugin:0.10.0
release to complain about it to @sdeleuze ;-)
We have released it ;-)
Thanks @sdeleuze, complaining ;-)
As I already said, if I use project dependency in grpc-native demo application, the class io.grpc.netty.NettyServerBuilder
appears in generated reflect-config.json
, but if I switch to maven-hosted dependency jar, this class is missing from generated reflect-config.json
.
I'm attaching the generated resources zip for both cases for your reference
That could be something we need to fine tune in the Spring AOT Gradle plugin, if it still happens with 0.10.1 please create a related issue on https://github.com/spring-projects-experimental/spring-native with, if possible, a minimal reproducer for this "project versus Maven repo" dependency native configuration generation issue.
@sdeleuze , unfortunately even with 0.10.3
the issue is still reproducible.
I've uploaded zip with generated aot resources for both cases : project
vs maven
dependency. io.grpc.netty.NettyServerBuilder
is missing from reflect-config.json
when referenced with maven hosted jar.
To reproduce - switch to io.github.lognet:grpc-spring-boot-starter:4.5.4
dependency here , enable test
task and run ./gradlew :grpc-spring-boot-starter-native-demo:test
Back reference
gRPC was already supported by Spring native on https://github.com/spring-projects-experimental/spring-native/tree/main/samples/grpc . Andy plan to add Spring Native support smoothly?