У меня есть проект Gradle с модулями. moduleA
содержит только файлы protobuf и создает файл jar с классами, сгенерированными из файлов .proto
. moduleB
зависит от moduleA
(implementation project(':moduleA')
).
moduleA
│ build.gradle
│ src
│ └───main
│ └───proto <-- proto file defining gRPC services
moduleB
│ build.gradle
│ src <-- code dependent on classes generated from moduleA
build.gradle
Проект работает хорошо, если я создаю/запускаю его из Gradle.
Проблема: IntelliJ IDEA не видит классы, сгенерированные из moduleA
в источниках moduleB
(импорт выделен красным).
Вопрос: Как заставить IntelliJ IDEA правильно распознавать классы, созданные из .proto
файлов?
Я использую IntelliJ IDEA 2020.2.4 (Ultimate Edition).
Это то же самое, что и использование прототипа сгенерированного кода в том же модуле, он должен быть там первым, прежде чем его сможет подобрать IDE.
Такие зависимости не могут быть разрешены статически. Сгенерированные прототипы классов доступны только после сборки moduleA
. Вам нужно будет собрать moduleA
хотя бы один раз (и при необходимости обновить импорт IDE), чтобы сделать сгенерированный код доступным для moduleB
.
В какое место модуль А генерирует исходные файлы? Этот каталог определяется IDE как тип исходного каталога? Можете ли вы поделиться примером проекта?
- модуль A строится автоматически каждый раз, когда строится модуль B. Не в этом дело. Компиляция всегда может найти сгенерированный код во время сборки. Но вы хотите, чтобы IDE забрала сгенерированный код перед сборкой moduleB
. Тогда у вас должен быть сгенерированный код в moduleA
available. - Этот каталог определяется IDE как тип исходного каталога? Protobuf-gradle-plugin имеет интеграцию с IDEA, каталог для сгенерированного кода будет автоматически помечен как модуль srcDirs.
Обязательно обновите импорт IDE (на панели инструментов Intellij Gradle нажмите «Повторно импортировать все проекты Gradle») после создания кода в moduleA
.
@voidzcy Я создам пример проекта и поделюсь им с вами. Обновление проекта, его пересборка, пометка каталога сборки как исходного каталога - все это не помогло. Мне пришлось вручную добавить каталог в Grade, как это было предложено в другом ответе
Конечно, вы можете открыть проблему на github, если у вас есть минимальный воспроизводимый проект.
Чтобы среда IDE разрешала классы и импортировала их из зависимого модуля, эти классы должны существовать и располагаться в исходном каталоге зависимого модуля. Похоже, что классы создаются в каталоге, который IDE не распознает как исходный каталог. Попробуйте добавить этот сгенерированный каталог в качестве исходного набора Gradle. В файл сборки Gradel модуля A добавьте:
sourceSets {
main {
java {
srcDirs = ['build/generated/source/proto/main/java']
}
}
}
где 'build/generated/source/proto/main/java'
- каталог, в котором генерируются исходники.
Для IntelliJ IDEA есть связанная проблема: IDEA-209418.
Плагин protobuf-gradle-plugin добавляет сгенерированный код в модель IDEA: github.com/google/protobuf-gradle-plugin/blob/… Это должно работать из коробки (и я пробовал это сам). Единственное, сгенерированный код уже должен быть там.
@voidzcy Я использую Quarkus. Он генерирует код в другой каталог. Может быть, поэтому Идея не выбирает его.
Мы можем сделать что-то подобное для нескольких исходных папок — sourceSets.main.java.srcDir new File(buildDir, 'build/generated/source/proto/main/java')
Расположение классов, сгенерированных из файлов .proto
, изначально не известно Intellij.
Подключаемый модуль Gradle com.google.protobuf регистрирует исходные каталоги с помощью сгенерированного кода, чтобы Intellij мог видеть, когда подключаемый модуль Gradle idea
применяется в файле build.gradle модуля A.
См. советы IntelliJ IDEA для плагина com.google.protobuf gradle документацию по плагину protobuf gradle.
Эта настройка работает для меня с Intellij IDEA 2021.1.
Краткий ответ: примените плагин idea
gradle к модулю A.
moduleA
строится автоматически каждый раз, когда строитсяmoduleB
. Но я также пробовал собиратьmoduleA
вручную - не помогает.