Docker构建billing-service时protoc-gen-grpc-java平台适配错误解决
问题
在billing-service目录下执行docker compose up时出现以下错误:
Please specify a program using absolute path or make sure the program is available in your PATH system variable --grpc-java_out: protoc-gen-grpc-java: Plugin failed with status code 1. [ERROR] Failed to execute goal org.xolstice.maven.plugins:protobuf-maven-plugin:0.6.1:compile-custom (default) on project billing-service: protoc did not exit cleanly. Review output for more information. -> [Help 1]
原因是本地Windows环境编译时,gRPC在/target/protoc-plugins/生成的是Windows版本的protoc-gen-grpc-java-1.68.1-windows-x86_64可执行文件,但Docker构建环境是Linux,导致平台适配失败。
相关配置文件如下:
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.caiohportella</groupId> <artifactId>billing-service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>billing-service</name> <description>billing-service</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>21</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--GRPC --> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty-shaded</artifactId> <version>1.69.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.69.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.69.0</version> </dependency> <dependency> <!-- necessary for Java 9+ --> <groupId>org.apache.tomcat</groupId> <artifactId>annotations-api</artifactId> <version>6.0.53</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>4.29.1</version> </dependency> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-spring-boot-starter</artifactId> <version>3.1.0.RELEASE</version> </dependency> </dependencies> <build> <extensions> <!-- Ensure OS compatibility for protoc --> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.7.0</version> </extension> </extensions> <plugins> <!-- Spring boot / maven --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- PROTO --> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.6.1</version> <configuration> <protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.68.1:exe:${os.detected.classifier}</pluginArtifact> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Dockerfile
FROM maven:3.9.9-eclipse-temurin-24-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src RUN mvn clean package FROM openjdk:25-jdk-slim AS runner WORKDIR /app COPY --from=builder ./app/target/billing-service-0.0.1-SNAPSHOT.jar ./app.jar EXPOSE 4001 9001 ENTRYPOINT ["java", "-jar", "app.jar"]
docker-compose.yml
services: billing-service: image: billing-service:latest build: . container_name: billing-service environment: SPRING_DATASOURCE_URL: jdbc:postgresql://billing-service-db:5432/db SPRING_DATASOURCE_USERNAME: admin_user SPRING_DATASOURCE_PASSWORD: password SPRING_JPA_HIBERNATE_DDL_AUTO: update SPRING_SQL_INIT_MODE: always ports: - "4001:4001" - "9001:9001" networks: - internal networks: internal: driver: bridge
解决方案
问题核心是本地Windows生成的protoc插件文件被复制到Docker构建环境中,导致Linux无法执行,可通过以下方式解决:
方案一:构建前清理本地target目录
执行docker compose up前,先在本地运行:
mvn clean
删除本地target目录下的Windows版本插件文件,确保Docker构建时在Linux环境重新下载对应版本的插件。
方案二:修改Dockerfile,强制清理编译
在Dockerfile的编译步骤中添加清理命令,确保构建环境无残留文件:
修改后的Dockerfile:
FROM maven:3.9.9-eclipse-temurin-24-alpine AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src # 先清理再打包,避免本地文件干扰 RUN mvn clean package -DskipTests FROM openjdk:25-jdk-slim AS runner WORKDIR /app COPY --from=builder ./app/target/billing-service-0.0.1-SNAPSHOT.jar ./app.jar EXPOSE 4001 9001 ENTRYPOINT ["java", "-jar", "app.jar"]
-DskipTests用于加快构建速度,需要测试可移除该参数。
方案三:配置.dockerignore忽略target目录(推荐)
在项目根目录创建.dockerignore文件,添加内容:
target/
这样Docker构建时会跳过本地target目录,避免跨平台文件被复制到容器内,确保容器编译完全基于Linux环境。
额外优化:统一gRPC版本
pom.xml中grpc依赖版本为1.69.0,但protoc-gen-grpc-java版本是1.68.1,版本不一致可能引发潜在问题,建议统一:
修改protobuf-maven-plugin中的pluginArtifact版本:
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.69.0:exe:${os.detected.classifier}</pluginArtifact>
内容的提问来源于stack exchange,提问作者Caio
相关产品推荐
相关产品推荐

