redhat-developer / vscode-java

Java Language Support for Visual Studio Code
Eclipse Public License 2.0
2.08k stars 434 forks source link

'Cannot be resolved' errors in projects with module-info.java #881

Open JesseRacine opened 5 years ago

JesseRacine commented 5 years ago

I am not able to get projects that use a module-info.java file to work with VS Code and Java. I've tried both Gradle and Maven.

VS Code p shows me a bunch of "cannot be resolved" errors for any classes called out in the module-info.java file. What I have found is that if I put a module attribute in the classpath, then it will work. However, because I am modifying the classpath file manually, I find that Gradle and Maven will automatically refresh the classpath file and remove my modifications to it, which will bring back the errors.

Is there a proper way to use modules with VS Code and Java? It seems that the problem is due to the fact that there needs to be module path information set in the classpath file in order for Eclipse to be happy, but there is no good way to do with that from Gradle or Maven.

fbricon commented 5 years ago

Can you share a sample project?

brunoborges commented 5 years ago

@fbricon a sample project that can demonstrate this is this one: https://github.com/brunoborges/fx2048

I am facing the same issue.

fbricon commented 5 years ago

@brunoborges I haven't checked but given this is a Gradle project, I'm not too surprised there might be some issues, as AFAIK, buildship doesn't support java module configuration (I maybe be wrong and that's another issue though).

@snjeza can you please take a look?

brunoborges commented 5 years ago

The Java Dependency Viewer extension correctly loads the classpath:

image

fbricon commented 5 years ago

those are regular classpath entries. If there's a module-info.java, Eclipse JDT requires those required modules to be flagged as modules in their respective classpath entries. I don't know that the Java dependency extension provides some kind of support for Java Modules (i.e. displays the module infos). cc @testforstephen @jdneo @akaroml

snjeza commented 5 years ago

@brunoborges could you try the following patch:

diff --git a/build.gradle b/build.gradle
index 7d7113c..b9893b5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,7 @@
+
 plugins {
     id 'java'
+    id 'eclipse'
     id 'application'
     id 'org.openjfx.javafxplugin'      version '0.0.7'
     id 'org.jonnyzzz.java9c'           version '0.2.3'
@@ -29,3 +31,20 @@ jlink {

     imageZip = project.file("${buildDir}/distributions/game2048-${javafx.platform.classifier}.zip")
 }
+
+eclipse {
+    classpath {
+        containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
+        file {
+            whenMerged {
+                entries.findAll { it.properties.kind.equals('lib') && !it.properties.path.contains("junit") }.each {
+                    it.entryAttributes['module'] = 'true'
+                }
+                entries.findAll { it.properties.path.startsWith('org.eclipse.jdt.launching.JRE_CONTAINER') }.each {
+                    it.entryAttributes['module'] = 'true'
+                }
+
+            }
+        }
+    }
+}
brunoborges commented 5 years ago

@fbricon I don't think they are regular classpath entries. See the module-info.java

@snjeza I tried the patch and it didn't work: I edited the file, closed the folder and reopened the entire project. No success.

fbricon commented 5 years ago

Related upstream buildship issue: https://github.com/eclipse/buildship/issues/658. TL;DR: don't hold your breath for a fix

snjeza commented 5 years ago

javafx

@brunoborges could you try the following build.gradle:


plugins {
    id 'java'
    id 'eclipse'
    id 'application'
    id 'org.openjfx.javafxplugin'      version '0.0.7'
    id 'org.jonnyzzz.java9c'           version '0.2.3'
    id 'org.beryx.jlink'               version '2.6.4'
    id 'com.github.ben-manes.versions' version '0.20.0'
}

repositories {
    mavenCentral()
}

mainClassName = 'fxgame/game2048.Game2048'

javafx {
    modules = [
       'javafx.base',
       'javafx.graphics',
       'javafx.controls'
    ]
}

jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'game2048'
    }

    imageZip = project.file("${buildDir}/distributions/game2048-${javafx.platform.classifier}.zip")
}

eclipse {
    classpath {
        containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
        file {
            whenMerged {
                entries.findAll { it.properties.kind.equals('lib') && !it.properties.path.contains("junit") }.each {
                    it.entryAttributes['module'] = 'true'
                }
                entries.findAll { it.properties.path.startsWith('org.eclipse.jdt.launching.JRE_CONTAINER') }.each {
                    it.entryAttributes['module'] = 'true'
                }

            }
        }
    }
}
brunoborges commented 5 years ago

@snjeza do I need to run some command to update the eclipse settings after modifying the build.gradle file ?

snjeza commented 5 years ago

@brunoborges you can call the "Java: Clean the Java Language Server workspace" command.

brunoborges commented 5 years ago

This solved the issue with the imports, but now IntelliSense (or whatever should do the job) is not working and I don't have auto-complete in the imports section for any package (javafx. as well as any of the java. or javax.*):

image

Auto-complete at method/field level works:

image

snjeza commented 5 years ago

This solved the issue with the imports, but now IntelliSense (or whatever should do the job) is not working and I don't have auto-complete in the imports section for any package (javafx. as well as any of the java. or javax.*)

The issue can be reproduced in Eclipse.

snjeza commented 5 years ago

@brunoborges you can try the following workaround:

diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 2ac9521..05d99fe 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -2,9 +2,9 @@ module fxgame {
     requires java.base;
     requires java.logging;

-    requires transitive javafx.base;
-    requires transitive javafx.controls;
-    requires transitive javafx.graphics;
+    requires javafx.base;
+    requires javafx.controls;
+    requires javafx.graphics;

     exports game2048;
 }
brunoborges commented 5 years ago

Thanks @snjeza. This worked. The environment is now 100% functional as one would expect.

But it is weird though since I'd expect the transitive config to actually avoid this problem.

snjeza commented 5 years ago

That is an Eclipse bug. Checking...

snjeza commented 5 years ago

Related issue - https://bugs.eclipse.org/bugs/show_bug.cgi?id=550619

lingocoder commented 4 years ago

Hey @brunoborges Thanks for posting your issue. And especially thanks for sharing your sample project. It's a super useful functional test for the upcoming release of my JPMS plugin: mrJar.

mr jar brunoborges fx2048 0 a

„...But it is weird though since I'd expect the transitive config to actually avoid this problem...“

Notice there are zero error messages in the Problems tab. That's because of mrJar's correct expected handling of the transitive config.

Also notice the contents of the build.gradle is a lot simpler, more concise and much prettier with mrJar. That's because there are way fewer lines of boilerplate than what you need with the original plugins you used.

Please, feel free to try it out. Let me know if it works for you. TIA :+1:

brunoborges commented 4 years ago

Any chance to incorporate your plugin's functionality into vscode-java extension?

lingocoder commented 4 years ago

Thanks for coming back to me @brunoborges.

I have thought about doing exactly what you're asking about before. I won't rule it out for some point in the future. But I can't commit to exactly when.

Excellent suggestion, though! Thanks :+1:

dsyer commented 2 years ago

FWIW I have the same or similar issues with a Maven project. Should I open a new issue, or just watch this one?

dsyer commented 1 year ago

No response? If anyone wants to reproduce the problem with Maven, just download a project from start.spring.io and add a module-info.java. You might need to tweak the one that VSCode generates for you. This worked for me in a vanilla Boot/Webflux app with Actuators:

module demo {
    exports com.example.demo;

    requires spring.beans;
    requires spring.boot;
    requires spring.boot.autoconfigure;
    requires spring.boot.actuator;
    requires spring.boot.actuator.autoconfigure;
    requires spring.context;
    requires spring.core;
    requires spring.web;

    opens com.example.demo to //
            spring.core, spring.web, spring.beans, spring.context, spring.boot, com.fasterxml.jackson.databind;
}

YMMV. I had to delete the tests because VSCode is confused about test dependencies and the module path. And the app was runnable from the command line, but not in the IDE (same incomprehensible error as above).

brunoborges commented 1 year ago

This issue will become a larger problem with Spring 3.0

snjeza commented 1 year ago

... And the app was runnable from the command line, but not in the IDE (same incomprehensible error as above).

@dsyer could you try to add

requires java.instrument;

to your module-info.java

snjeza commented 1 year ago

I had to delete the tests because VSCode is confused about test dependencies and the module path

@dsyer Could you try to add

 <properties>
...
  <m2e.disableTestClasspathFlag>true</m2e.disableTestClasspathFlag>
...
</properties>

to pom.xml

dsyer commented 1 year ago

requires java.instrument; works to run the app in the IDE. But it doesn't, does it, require that? So is it still a bug?

I can't reproduce the problem with the tests, but I think I might have updated VSCode Java Extension Pack to a "pre-release" version, so that might be fixed there.

snjeza commented 1 year ago

requires java.instrument; works to run the app in the IDE. But it doesn't, does it, require that? So is it still a bug?

It works in the same way in Eclipse.

dsyer commented 1 year ago

So what? I should raise an issue in Eclipse? Do you happen to have a link?