跳过正文
  1. Posts/

java-grpc 踩坑记录

·1789 字·4 分钟

最近的项目需要java和python之间的进程通信,想到了之前使用过的 grpc。

参考官方quickstart

  • JDK: version 7 or higher

看起来只依赖jdk,美滋滋

然后按照文档执行

./gradlew installDist

报错:

 1Task :grpc-compiler:compileJava_pluginExecutableJava_pluginCpp FAILED
 2
 3FAILURE: Build failed with an exception.
 4
 5* What went wrong:
 6Execution failed for task ':grpc-compiler:compileJava_pluginExecutableJava_pluginCpp'.
 7> No tool chain is available to build for platform 'x86_64':
 8    - Tool chain 'visualCpp' (Visual Studio): Visual Studio is not available on this operating system.
 9    - Tool chain 'gcc' (GNU GCC): Could not determine GCC metadata: could not find vendor in output of /usr/local/gcc-4.9.4/bin/gcc.
10    - Tool chain 'clang' (Clang): Could not find C compiler 'clang' in system path.
11
12* Try:
13Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
14
15* Get more help at https://help.gradle.org
16
17BUILD FAILED in 3m 47s
18
19~

看起来是 gcc 或者 clang 的问题… 先装个 clang 再说,可能 clang 太常用了,所以文档没有提到,这下一定可以了。

然而又报错:

 1> Task :grpc-compiler:linkJava_pluginExecutable FAILED
 2/usr/bin/ld: cannot find -lstdc++
 3clang: error: linker command failed with exit code 1 (use -v to see invocation)
 4
 5
 6
 7
 8FAILURE: Build failed with an exception.
 9
10
11* What went wrong:
12Execution failed for task ':grpc-compiler:linkJava_pluginExecutable'.
13> A build operation failed.
14      Linker failed while linking protoc-gen-grpc-java.
15  See the complete log at: file:///home/renkuanze/github/grpc-java/compiler/build/tmp/linkJava_pluginExecutable/output.txt
16
17
18* Try:
19Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
20
21
22* Get more help at https://help.gradle.org
23~
24~
25~
26~

??????

看起来是 stdc++ 的 lib 没有找到。

在 CentOS 上安装了:

1libstdc++.x86_64 4.8.5-28.el7_5.1 @updates
2libstdc++-devel.x86_64 4.8.5-28.el7_5.1 @updates
3libstdc++-static.x86_64

这回一定没问题了吧?

然而继续报错,变成了 javadoc 找不到。

 1*** Skipping the build of codegen and compilation of proto files because skipCodegen=true
 2> Task :grpc-all:javadoc FAILED
 3
 4FAILURE: Build failed with an exception.
 5
 6* What went wrong:
 7Execution failed for task ':grpc-all:javadoc'.
 8> Javadoc generation failed. Generated Javadoc options file (useful for troubleshooting): '/home/renkuanze/github/grpc-java/all/build/tmp/javadoc/javadoc.options'
 9
10* Try:
11Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
12
13* Get more help at https://help.gradle.org
14
15BUILD FAILED in 1s
1630 actionable tasks: 1 executed, 29 up-to-date

简直了…grpc的文档还是一如既往的辣鸡…目前还在坑里面,先把前面踩的坑记录一下。

然后继续报错:

 1*** Skipping the build of codegen and compilation of proto files because skipCodegen=true
 2> Task :grpc-all:javadoc FAILED
 3
 4FAILURE: Build failed with an exception.
 5
 6* What went wrong:
 7Execution failed for task ':grpc-all:javadoc'.
 8> Javadoc generation failed. Generated Javadoc options file (useful for troubleshooting): '/home/renkuanze/github/grpc-java/all/build/tmp/javadoc/javadoc.options'
 9
10* Try:
11Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
12
13* Get more help at https://help.gradle.org
14
15BUILD FAILED in 3s
1630 actionable tasks: 6 executed, 24 up-to-date

好像不是很对啊…

文档固然辣鸡,但是会不会有其他打开方式?

于是跑到工程院那边请教了同事…发现果然打开方式不正确…

正确的方式是直接在依赖管理工具如maven中添加,并不需要手动编译安装…

参考这个搞它一发先

同时按照 maven-in-five-minutes 了解一下 maven 的使用。

Although hardly a comprehensive list, these are the most common default lifecycle phases executed.

  • validate: validate the project is correct and all necessary information is available
  • compile: compile the source code of the project
  • test: test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • package: take the compiled code and package it in its distributable format, such as a JAR.
  • integration-test: process and deploy the package if necessary into an environment where integration tests can be run
  • verify: run any checks to verify the package is valid and meets quality criteria
  • install: install the package into the local repository, for use as a dependency in other projects locally
  • deploy: done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

There are two other Maven lifecycles of note beyond the default list above. They are

  • clean: cleans up artifacts created by prior builds
  • site: generates site documentation for this project

发现 mvn package 的时候会报几百行的错误。

于是先执行 mvn validate 验证一下情况,最上面的错误如下:

 1[INFO] Scanning for projects...
 2[INFO] ------------------------------------------------------------------------
 3[INFO] Detecting the operating system and CPU architecture
 4[INFO] ------------------------------------------------------------------------
 5[INFO] os.detected.name: osx
 6[INFO] os.detected.arch: x86_64
 7[INFO] os.detected.classifier: osx-x86_64
 8[WARNING] Failed to inject repository session properties.
 9java.lang.NoSuchMethodError: org.apache.maven.execution.MavenSession.getRepositorySession()Lorg/eclipse/aether/RepositorySystemSession;
10    at kr.motd.maven.os.RepositorySessionInjector.injectRepositorySession(RepositorySessionInjector.java:22)
11    at kr.motd.maven.os.DetectExtension.injectSession(DetectExtension.java:148)
12    at kr.motd.maven.os.DetectExtension.afterProjectsRead(DetectExtension.java:107)
13    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:274)
14    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
15    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
16    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
17    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
18    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
19    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
20    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
21    at java.lang.reflect.Method.invoke(Method.java:483)
22    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
23    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
24    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
25    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
26    at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
27    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
28    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
29    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
30    at java.lang.reflect.Method.invoke(Method.java:483)
31    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
32[INFO]

参考An exception occurred when I use maven plugin, Why? 发现可能是maven版本不行,去官网下载了目前的最新版本 3.5.4,ok 了

下一步该进行mvn compile,也ok

然后是mvn test,又是几百行错误…核心的信息是java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument

参考java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument

添加了两个依赖(再次吐槽 grpc-java 官方文档&demo 的不靠谱)

Please add following dependencies in your project.

 1<dependency>
 2    <groupId>com.google.guava</groupId>
 3    <artifactId>guava</artifactId>
 4    <version>23.6-jre</version>
 5</dependency>
 6<dependency>
 7    <groupId>org.apache.httpcomponents</groupId>
 8    <artifactId>httpcore</artifactId>
 9    <version>4.4.8</version>
10</dependency>

似乎是 ok 了。

然后执行mvn package,继续报错,好在只有几十行…

1[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage (default) on project grpc-demo: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:2.0.3.RELEASE:repackage failed: Unable to find a single main class from the following candidates [io.grpc.examples.advanced.HelloJsonClient, io.grpc.examples.advanced.HelloJsonServer, io.grpc.examples.alts.HelloWorldAltsClient, io.grpc.examples.alts.HelloWorldAltsServer, io.grpc.examples.errorhandling.DetailErrorSample, io.grpc.examples.errorhandling.ErrorHandlingClient, io.grpc.examples.experimental.CompressingHelloWorldClient, io.grpc.examples.header.CustomHeaderClient, io.grpc.examples.header.CustomHeaderServer, io.grpc.examples.helloworld.HelloWorldClient, io.grpc.examples.helloworld.HelloWorldServer, io.grpc.examples.helloworldtls.HelloWorldClientTls, io.grpc.examples.helloworldtls.HelloWorldServerTls, io.grpc.examples.manualflowcontrol.ManualFlowControlClient, io.grpc.examples.manualflowcontrol.ManualFlowControlServer, io.grpc.examples.routeguide.RouteGuideClient, io.grpc.examples.routeguide.RouteGuideServer] -> [Help 1]
2[ERROR]
3[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
4[ERROR] Re-run Maven using the -X switch to enable full debug logging.
5[ERROR]
6[ERROR] For more information about the errors and possible solutions, please read the following articles:
7[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

摘重点: Unable to find a single main class from the following candidates

看样子是找不到程序入口在哪里了…好像很合理,毕竟grpc-java的example里每个文件都带了main函数

参考SpringBoot: Unable to find a single main class from the following candidates,在 pom.xml 中添加如下的属性就行了。

 1<profiles>
 2    <profile>
 3        <id>profile1</id>
 4        <properties>
 5          <spring.boot.mainclass>com.SomeClass</spring.boot.mainclass>
 6        </properties>
 7    </profile>
 8    <profile>
 9        <id>profile2</id>
10        <properties>
11          <spring.boot.mainclass>com.SomeOtherClass</spring.boot.mainclass>
12        </properties>
13    </profile>
14</profiles>
15
16
17
18
19<plugin>
20    <groupId>org.springframework.boot</groupId>
21    <artifactId>spring-boot-maven-plugin</artifactId>
22    <version>1.5.2.RELEASE</version>
23    <executions>
24      <execution>
25        <goals>
26          <goal>repackage</goal>
27        </goals>
28        <configuration>
29          <mainClass>${spring.boot.mainclass}</mainClass>
30        </configuration>
31      </execution>
32    </executions>
33    ...
34</plugin>

然后另一边,将python的server启动起来

注意 ip 和端口号要保持一致,ok 了。

1java -jar  /data/downloads/grpc-demo/target/grpc-demo-0.0.1-SNAPSHOT-exec.jar
2十月 18, 2018 11:48:06 上午 io.grpc.examples.helloworld.HelloWorldClient greet
3信息: Will try to greet sensetime autobots java backend ...
4十月 18, 2018 11:48:06 上午 io.grpc.examples.helloworld.HelloWorldClient greet
5信息: Greeting: Hello, sensetime autobots java backend  from python server

最后的代码请参考grpc-java-maven-exmaple

相关文章

spring 学习笔记

·496 字·1 分钟
迫于生计,又要从零开始学习spring. 在这篇文章之前,对java的基础是2015年写过一个java大作业,对spring是一无所知。

gRPC学习笔记

·628 字·2 分钟
gRPC 是 google 最新发布的开源 RPC 框架, 声称是"一个高性能,开源,将移动和HTTP/2放在首位的通用的RPC框架.". 技术栈非常的新, 基于HTTP/2, netty4.1, proto3, 拥有非常丰富而实用的特性, 堪称新一代RPC框架的典范.