Вопрос или проблема
Среда:
- Версия Micronaut: 4.6.3
- JDK: 17
У меня есть REST API, разработанный с помощью Micronaut. Теперь я хочу добавить функциональность клиента gRPC в этот REST API для вызова gRPC сервера по адресу http://localhost:50051
.
Я прочитал https://micronaut-projects.github.io/micronaut-grpc/latest/guide/index.html, но все еще есть информация, которая не описана четко.
Следуя предложению chatgpt, я добавил несколько строк и блоков в свой текущий build.gradle
build.gradle
plugins {
id("groovy")
id("com.github.johnrengelman.shadow") version "8.1.1"
id("io.micronaut.application") version "4.4.2"
id("io.micronaut.aot") version "4.4.2"
id("com.google.protobuf") version "0.9.2" // Я добавил эту строку
}
version = "0.1"
group = "com.example"
repositories {
mavenCentral()
}
dependencies {
annotationProcessor("org.projectlombok:lombok")
annotationProcessor("io.micronaut:micronaut-http-validation")
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("jakarta.annotation:jakarta.annotation-api") // Я добавил эту строку
compileOnly("org.projectlombok:lombok")
runtimeOnly("ch.qos.logback:logback-classic")
runtimeOnly("org.yaml:snakeyaml")
// Я добавил эти 2 строки
implementation("io.micronaut.grpc:micronaut-grpc-runtime")
implementation("io.micronaut.grpc:micronaut-grpc-client-runtime")
}
application {
mainClass = "com.example.Application"
}
java {
sourceCompatibility = JavaVersion.toVersion("17")
targetCompatibility = JavaVersion.toVersion("17")
}
graalvmNative.toolchainDetection = false
micronaut {
runtime("netty")
testRuntime("spock2")
processing {
incremental(true)
annotations("com.example.*")
}
aot {
// Пожалуйста, внимательно проверьте оптимизации, включенные ниже
// Посмотрите https://micronaut-projects.github.io/micronaut-aot/latest/guide/ для получения дополнительных сведений
optimizeServiceLoading = false
convertYamlToJava = false
precomputeOperations = true
cacheEnvironment = true
optimizeClassLoading = true
deduceEnvironment = true
optimizeNetty = true
replaceLogbackXml = true
}
}
// Я добавил нижний блок protobuf
protobuf {
protoc { artifact = "com.google.protobuf:protoc:3.25.5" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.66.0" }
}
generateProtoTasks {
all()*.plugins {grpc {}}
}
}
// Я добавил нижний блок sourceSets
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
application.yml
micronaut:
application:
name: grpc-http-client-example
server:
port: 8080
## Я добавил нижний блок grpc
grpc:
channels:
greeter:
address: 'http://localhost:50051'
plaintext: true
Также я добавил файл .proto, предоставленный gRPC-сервером, ниже в src/main/proto
grpc-server-example.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.example";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// Определение сервиса приветствий.
service Greeter {
// Отправляет приветствие
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// Сообщение запроса, содержащее имя пользователя.
message HelloRequest {
string name = 1;
}
// Сообщение ответа, содержащее приветствия
message HelloReply {
string message = 1;
}
Теперь я выполняю следующую команду:
./gradlew clean generateProto
./gradlew run
Затем возникает следующая ошибка:
9:23:57 a.m.: Выполнение ':classes'...
> Задача :extractIncludeProto UP-TO-DATE
> Задача :extractProto UP-TO-DATE
> Задача :generateProto UP-TO-DATE
> Задача :compileJava FAILED
В этом сборке использовались устаревшие функции Gradle, что делает его несовместимым с Gradle 9.0.
Вы можете использовать '--warning-mode all', чтобы показать отдельные предупреждения об устаревании и определить, приходят ли они из ваших собственных скриптов или плагинов.
Для получения дополнительной информации смотрите https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings в документации Gradle.
4 задачи, которые требуют выполнения: 1 выполнена, 3 актуальны
E:\Project-Space\microservices\grpc-http-client2-example\build\generated\source\proto\main\grpc\com\example\GreeterGrpc.java:10: ошибка: не может найти символ
@javax.annotation.Generated(
^
символ: класс Generated
расположение: пакет javax.annotation
1 ошибка
НЕУДАЧА: Сборка завершилась с ошибкой.
* Что пошло не так:
Не удалось выполнить задачу ':compileJava'.
> Компиляция не удалась; см. вывод ошибок компилятора для деталей.
Ниже приведена структура каталогов проекта REST API
Как исправить ошибку?
Ответ или решение
Для внедрения функции gRPC клиент в существующий REST API, разработанный с использованием Micronaut, необходимо выполнить несколько шагов. Ваша текущая конфигурация build.gradle выглядит почти правильно, но вы сталкиваетесь с ошибкой компиляции из-за отсутствия класса @Generated
. Давайте разберем, как это исправить и как правильно интегрировать gRPC в ваш проект.
Шаги для исправления ошибок и интеграции gRPC клиента
1. Настройка зависимостей
Как правильно указано в вашем build.gradle, вы добавили все необходимые зависимости для работы с gRPC. Однако убедитесь, что вы добавили следующие зависимости:
dependencies {
// ... другие зависимости
implementation("javax.annotation:javax.annotation-api:1.3.2") // Добавьте эту строку
}
Добавление этой зависимости должно решить вашу проблему, связанную с отсутствием класса Generated
.
2. Проверка плагинов и версий
Убедитесь, что все используемые плагины и версии соответствуют друг другу:
- Плагин для Protobuf и gRPC имеет версии, совместимые с Micronaut 4.6.3.
- Используйте версию
com.google.protobuf:protoc
иio.grpc:protoc-gen-grpc-java
, чтобы избежать конфликтов.
Пример корректных строк в build.gradle:
protobuf {
protoc { artifact = "com.google.protobuf:protoc:3.25.5" }
plugins {
grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.66.0" }
}
generateProtoTasks {
all().each { task ->
task.plugins {
grpc {}
}
}
}
}
3. Конфигурация application.yml
Ваш файл application.yml
выглядит корректно. Убедитесь, что указанные вами значения соответствуют настройкам вашего gRPC сервера:
grpc:
channels:
greeter:
address: 'http://localhost:50051'
plaintext: true
4. Генерация .proto файлов
Теперь выполните команды для очистки, генерации файлов Protobuf и запуска приложения:
./gradlew clean generateProto
./gradlew run
При этом убедитесь, что ваш локальный gRPC сервер работает на порту 50051 и доступен по указанному адресу.
5. Реализация клиента gRPC
После успешной генерации файлов, вы можете создать gRPC клиента в вашем приложении. Вот пример реализации, который можно поместить в контроллер вашего REST API:
import io.micronaut.grpc.annotation.GrpcClient;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import helloworld.GreeterGrpc;
import helloworld.HelloRequest;
import helloworld.HelloReply;
@Controller("/greet")
public class GreetingController {
@GrpcClient("greeter") // Используйте имя, указанное в application.yml
GreeterGrpc.GreeterBlockingStub greeter;
@Get("/{name}")
public String greet(String name) {
HelloRequest request = HelloRequest.newBuilder()
.setName(name)
.build();
HelloReply response = greeter.sayHello(request);
return response.getMessage();
}
}
Заключение
Теперь, когда вы выполнили все указанные шаги, ваше приложение должно успешно интегрировать клиента gRPC и вызывать удаленные процедуры на gRPC сервере. Если после внесения всех поправок у вас все еще возникают ошибки, внимательно проверьте логи компиляции и убедитесь, что нет конфликтующих зависимостей или плагинов.
Следуя инструкциям, вы сможете добавить функциональность gRPC клиента к вашему существующему микросервису, обеспечив более гибкий и производительный способ взаимодействия с другими сервисами.