Repository navigation
Description
Hi. I'm using Protocol Buffers in my Java application. I'm using Gradle, and the protobuf-gradle-plugin to generate Java classes from the .proto files. The generated proto Java files are added to my sourceSet in build.gradle.
build.gradle
plugins {
id 'java'
id 'application'
id "com.google.protobuf" version "0.8.12"
}
repositories {
jcenter()
}
dependencies {
implementation 'com.google.guava:guava:28.2-jre'
testImplementation 'junit:junit:4.12'
}
application {
mainClassName = 'test.gradle.project.proto.App'
}
sourceSets {
main {
java {
srcDirs 'src/main/java'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
compileJava.dependsOn 'generateProto'Whenever I make a change to the proto files, and re-generate the proto Java classes via ./gradlew generateProto, the language server does not update the references, and I get errors in the editor. AFAIK there's two ways to update the class references:
- Restart vscode, or
- Run "Update project configuration" from the grade build file
Neither options are ideal, and option 2 can sometimes take a long time to complete on large projects. I would think updating class references should be a quick process. No compilation is necessary, the language server just needs to update it's reference cache (or something along those lines).
Would it be possible to
- Provide a new command to update class references?
- Watch the build directory/sourceSets and automatically update references when generated files change?
I'm also developing a gradle vscode extension, and from my extension i would potentially be able to provide a list of generated class files to the vscode-java extension via an API call, so that could also be a potential option.
Looking for any ideas/suggestions/changes to make this process more user friendly and fast.
Environment
- Operating System: MacOS catalina
- JDK version: openjdk 11.0.2
- Visual Studio Code version: 1.45.1
- Java extension version: 0.62.0
Steps To Reproduce
- Clone this repo: https://github.com/badsyntax/test-gradle-project-proto
- Open
test-gradle-project-protoin vscode - Open
src/main/java/test/gradle/project/proto/App.java - Note classes for
Greetingdon't exist - In the vscode terminal, run
./gradlew generateProto - Note references for
Greetingstill don't exist - Either restart vscode, or run "Update project configuration" from
build.gradle - Note references for
Greetingnow exist and there's no errors in the editor
Keep in mind this is a very small project and you won't see the performance issues I mentioned above, but does demonstrate the extension not updating references when files on disk change.
Activity
testforstephen commentedon Jun 5, 2020
"Update project configuration" is exactly used to update classpath. Its performance issue is covered at another issue #1362.
badsyntax commentedon Jun 5, 2020
I don't know the internals of how this extension works, but it seems that "Update project configuration" does more than just update classpath (eg I don't know what "project configuration" means):
But ignoring the performance and focusing in the UX, running this command is not an ideal step. I need to either focus on the
build.gradlefile before running it, or right click thebuild.gradlefile in the explorer and select "Update project configuration".Working with others, I've also noticed that this is not an obvious step and causes confusion & frustration for users (it was also confusing behaviour for me when I first used the extension).
My expectation is the extension should update the references when the classes change on disk.
If this extension already knows which files are in the classpath (eg as defined in the
sourceSetsblock in mybuild.gradle), why can't it automatically compile the classes and update the references in the editor when those files change?For the test repo I linked above, the
.classpathfile has this entry (as defined insourceSets):..so it seems like the extension should be able to watch those files and update references when the classes change. This would be a huge UX improvement.
testforstephen commentedon Jun 5, 2020
The extension will auto watch on those files under the folder which is marked as
srckind in .classpath.When i tried your sample project at first time, actually the .classpath file didn't contain the sourceSets you pasted above. Only when i run
./gradlew generateProtoand "Update project configuratoin", then the sourceSets entry above is added to .classpath. So looks like the .classpath cannot contain not existing folder.Once your new sourceSets is included in .classpath, you are supposed not need to update project configuration manually. Because the extension will auto watch on the files listed by .classpath, and sync up them.
Regarding UX, i'm open to new idea to make it better.
badsyntax commentedon Jun 5, 2020
Thanks for testing this. You're totally right, it does indeed watch those files and update references. This is great. Apologies for not spotting this behaviour. I remember it didn't always do this, perhaps this is a recent change in the extension? Either way, this is exactly what I was looking for haha 🤦
About the
.classpathnot containing references to paths that don't exist, do you happen to know why? As i've defined a classpath via sourceSet, i would expect the extension to add this path to the.classpath, regardless if the path exists or not. Is this something that can be changed, to support classes being added to the classpath at a later time?badsyntax commentedon Jun 15, 2020
hi @testforstephen have you had a chance to look into this? Am wondering why the extension doesn't add paths from the sourceSets (that don't exist) into the
.classpath? This would help with the UX of this extension.testforstephen commentedon Jun 16, 2020
We're leveraging buildship to support gradle project, don't get time to look into the upstream buildship tool yet.
lfarkas commentedon Feb 1, 2023
is there any progress with this? for me it's still not working...
Mr-EmPee commentedon Jul 17, 2026
This problem still seems to exists, I found out that after running a compileJava (that also compile the protos) and then Java: reload projects it works.
Is there any chance of this being fixed?