如何配置 VS Code 和 Gradle 以通过 Gradle Protobuf 插件使用生成的 Java 代码?

问题描述 投票:0回答:2

我正在尝试在一个小型 Java 应用程序中将 Protobuf 与 Google 官方 Gradle 插件、Gradle 一起使用,在 VS Code 中测试工作流程。

我无法让 VS Code 识别生成的 Java 源代码,并且在终端中,当我尝试使用 Gradle 构建应用程序时,我也无法让 Gradle 识别代码。

当我尝试引用生成的代码时,VS Code 显示此信息:

VS Code, editing a Java file called App.java, where the text

当我尝试构建时,Gradle 显示以下错误:

> Task :app:compileJava FAILED
/home/mattgbi/vscode-gradle-protobuf-repro/app/src/main/java/vscode/gradle/protobuf/repro/App.java:14: error: cannot find symbol
        System.out.println(Person.class);
                           ^
  symbol:   class Person
  location: class App
1 error

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileJava'.
> Compilation failed; see the compiler error output for details.

* Try:
> Run 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.

* Get more help at https://help.gradle.org

BUILD FAILED in 405ms
4 actionable tasks: 1 executed, 3 up-to-date

我知道我需要在

App.java
中添加导入才能使用
Person
类。但是,当我尝试调用 VS Code 代码补全工具来执行此操作时,如上所述,代码补全无法帮助我执行此操作。

但是,如果我手动输入 import 语句,VS Code 会说找不到它。:

VS Code error saying it can't find the package

但是,此时,Gradle 能够使用 import 语句(即使 VS Code 渲染错误)并且能够完成构建:

> ./gradlew build

> Task :app:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

BUILD SUCCESSFUL in 1s
13 actionable tasks: 10 executed, 3 up-to-date

这里是一个 GitHub 存储库,完整重现了该问题:https://github.com/mattwelke/repros/tree/main/vscode-gradle-protobuf-repro

以下是我遇到此问题时完成的步骤:

  1. 使用
    gradle init
    创建项目。选择“应用程序”并将所有设置保留为默认值。
  2. 按照 https://github.com/google/protobuf-gradle-plugin 的说明将插件添加到我的项目中。将“buildscript”部分添加到
    build.gradle
    文件的顶部,位于文件的
    plugins
    部分之上。在
    plugins
    部分内添加带有
    id "com.google.protobuf" version "0.8.18"
    的线,位于该部分中
    id 'application'
    线下方。将以
    protobuf {
    开头的块添加到文件底部,以便我可以让 Gradle 下载并使用它自己的
    protoc
    二进制文件。
  3. 按照 Protobuf 的 Java 教程 (https://developers.google.com/protocol-buffers/docs/javatutorial),将页面顶部附近有
    message Person {
    的代码添加到我的新文件中的应用程序
     app/src/main/proto/message.proto
  4. 在 VS Code 终端中使用
    ./gradlew build
    进行构建。
  5. 观察生成到
    app/build/generated/source
    中的源代码,即使控制台中出现错误,提示
    package com.google.protobuf does not exist
  6. 将依赖项
    protobuf-java
    (来自https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java)添加到文件的
    build.gradle
    部分下的
    dependencies
    文件,以便我的应用程序生成Java源代码将能够引用 Protobuf 库。选择版本 3.21.1,因为它是目前的最新版本。使用
    implementation
    语法添加。
  7. 在 VS Code 终端中使用
    ./gradlew build
    再次构建应用程序。这次在终端中没有观察到错误。
  8. 尝试在
    App.java
    (在
    src
    下)中编写引用生成的
    Person
    类的源代码。 VS Code 找不到它。
  9. 尝试在 VS Code 终端中使用
    ./gradlew build
    再次构建应用程序。 Gradle也找不到源代码。
  10. 手动添加导入语句到
    App.java
    。观察 VS Code 显示有关仍然无法找到包的错误。
  11. 尝试在 VS Code 终端中使用
    ./gradlew build
    再次构建应用程序。 Gradle也找不到源代码。这次 Gradle 成功了。剩下的唯一问题是 IDE 如何识别所有代码(期望的是所有代码,包括生成的代码,都能被识别)。
java gradle visual-studio-code protocol-buffers gradle-plugin
2个回答
5
投票

我的问题是我没有配置 Gradle(通过

build.gradle
)来包含生成代码所在位置的新源集。 VS Code 在检测到 Gradle 时读取 Gradle 配置以设置类路径,并在检测到它时禁用手动调整类路径,因此配置 Gradle 是唯一的选择。

将源集添加到 Gradle 配置之前:

accessing classpath settings before adding source set to Gradle config 1

accessing classpath settings before adding source set to Gradle config 2

accessing classpath settings before adding source set to Gradle config 2 3

将其添加到底部的

build.gradle
后:

sourceSets {
  main {
    java {
      srcDir 'build/generated/source/proto/main/java'
    }
  }
}

after adding to classpath via Gradle settings 1

after adding to classpath via Gradle settings 2

此外,删除

app/build
目录并再次运行
./gradlew build
后,我发现我必须从 Java 扩展运行“删除工作区”命令才能使我的工作区恢复到健康状态,其中生成的代码已被 VS Code 识别。

在阅读插件的自述文件(https://github.com/google/protobuf-gradle-plugin)并阅读他们关于覆盖源集的说明后,我意识到这是问题所在。由于对 Gradle 有点陌生,我忘记了源集的重要性。自述文件描述了插件如何动态地为生成的代码目录设置源集。

我想,因为 VS Code 没有调用任何 Gradle 任务来完成 Java 代码完成等(我认为它使用 Eclipse 工具),但因为它显然使用 Gradle 配置来配置它与 Java 的行为方式,所以解决我的问题的关键问题是通过在我的

build.gradle
文件中显式指定来手动告诉 VS Code 有关新源集的信息。


0
投票

我对 Maven 项目和 VS Code 也有完全相同的问题。 我能够使用项目设置来解决

Java 项目 > (***) 配置类路径 > 添加如下 enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.