redhat-developer / vscode-java

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

Mapstruct implementation class not generated after upgrading to 1.36.0 #3836

Closed raulvaldoleiros closed 1 week ago

raulvaldoleiros commented 3 weeks ago

After the upgrade to the version 1.36.0 the Mapstruct classes stopped from being generated, I suspect it's related with lombok upgrade. I reverted to the previous version and it worked as expected, the shown error was:

Please let me know if I can help somehow.

rgrunber commented 3 weeks ago

We just updated to latest edge release, so maybe one of their commits is causing this ? https://github.com/projectlombok/lombok/commits/master/?since=2024-09-29&until=2024-10-31 . Maybe related to https://github.com/projectlombok/lombok/issues/3116 ?

iwangbowen commented 3 weeks ago

It happened to me. At first I thought something's wrong with my code😒 Image

ashe98 commented 3 weeks ago

Facing the same issue. Any updates on this?

mvannux commented 3 weeks ago

The same for me in VSCode, but using "mvn clean compile package" all works as expected

laurocesar commented 3 weeks ago

Rolling back to 1.35.1 version for now... Uncheck "Auto Update"

Image

gbrandalise commented 3 weeks ago

same issue here. reverting version to 1.35.1 solve the problem. apparently the annotationProcessorPaths does not resolving properly in correct order

rgrunber commented 3 weeks ago

Does anyone have a sample project they're able to share that easily reproduces this ? I tried just importing some basic ones from https://github.com/mapstruct/mapstruct-examples/ but I didn't see any with the error mentioned here.

When you install the latest vscode-java release (1.36.0), it will install Lombok under a path like $HOME/.vscode/extensions/redhat.java-1.36.0-linux-x64/lombok/lombok-1.18.36.jar (on Linux), or %USERPROFILE%\.vscode\extensions\redhat.java-1.36.0-win32-x64\lombok\lombok-1.18.35.jar (on Windows). That Lombok jar is the latest development version towards 1.18.35 that was available on October 31st. If you replace that jar with https://projectlombok.org/downloads/lombok.jar (currently 1.18.34), and try again, does the problem go away ? This would at least determine whether the problem is with Lombok.

gbrandalise commented 3 weeks ago

@rgrunber it's possible that the problem is related with conflicted versions of lombok? I have vscjava.vscode-lombok extension installed and my pom.xml have following annotationProcessorPaths :

<annotationProcessorPaths>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
    </path>
    <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-mapstruct-binding</artifactId>
        <version>${lombok.mapstruct.binding.version}</version>
    </path>
    <!-- Mapstruct should follow the lombok path(s) -->
    <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${mapstruct.version}</version>
    </path>
</annotationProcessorPaths>
shygnome commented 2 weeks ago

facing the same issue. reverting to version 1.35.1 does solve the problem. I also have vscode-lombok extension installed.

valtrig commented 2 weeks ago

Does anyone have a sample project they're able to share that easily reproduces this ? I tried just importing some basic ones from https://github.com/mapstruct/mapstruct-examples/ but I didn't see any with the error mentioned here.

When you install the latest vscode-java release (1.36.0), it will install Lombok under a path like $HOME/.vscode/extensions/redhat.java-1.36.0-linux-x64/lombok/lombok-1.18.36.jar (on Linux), or %USERPROFILE%\.vscode\extensions\redhat.java-1.36.0-win32-x64\lombok\lombok-1.18.35.jar (on Windows). That Lombok jar is the latest development version towards 1.18.35 that was available on October 31st. If you replace that jar with https://projectlombok.org/downloads/lombok.jar (currently 1.18.34), and try again, does the problem go away ? This would at least determine whether the problem is with Lombok.

Hi, I'm also currently facing the same issue and can confirm that by simply replacing Lombok's jar in the extensions-directory with current stable version 1.18.34 does indeed make it go away.

fbricon commented 2 weeks ago

Anyone using mapstruct but not lombok can try disabling lombok support in the preferences:

Image

gbrandalise commented 2 weeks ago

@rgrunber I tested desabling vscjava.vscode-lombok extension but the issue persist. Only reverting to version 1.35.1 solve the problem. Maybe this issue is more related with the lombok.jar's version than the extension version itself, as @valtrig mentioned. My project uses 1.18.20 lombok version by the way.

rgrunber commented 2 weeks ago

Does anyone have a full project they can share or some smaller project they can reproduce the issue on ?

dxaraujo commented 2 weeks ago

@rgrunber, you can use this repository: https://github.com/dxaraujo/vscode-java/

heyarny commented 2 weeks ago

we're facing the same problem. +1

fp024 commented 2 weeks ago

I think it's because "MapStruct" and "Lombok 1.18.35" are not compatible.

I have modified the pom.xml from "https://github.com/dxaraujo/vscode-java/" to use the version of lombok1.18.35 (2024-10-17 23:16:18 UTC) as follows.

  <properties>
    ...
    <lombok.version>edge-SNAPSHOT</lombok.version>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
  </properties>

  <repositories>
    <repository>
      <id>projectlombok.org</id>
      <url>https://projectlombok.org/edge-releases</url>
    </repository>
  </repositories>

An error occurred when performing "mvn clean package" on the CMD in this state.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile) on project vscode-java: Compilation failure
[ERROR] /C:/git-other/vscode-java/src/main/java/com/vscode/java/mapper/UserMapper.java:[9,8] No implementation was created for UserMapper due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument.
[ERROR]
...

I think it's better to downgrade the version of Lombok provided by VSCode java extension to 1.18.34,

or if that doesn't work, turn off the Lombok support for VSCode java in User Settings.json and manually configure it to use Lombok 1.18.34.

{
  "java.jdt.ls.lombokSupport.enabled": false,
  "java.jdt.ls.vmargs": "-javaagent:\"{custom_lombok_path}\\lombok-1.18.34.jar\" {jvm options...} ... ",
}
fp024 commented 2 weeks ago

There was something unique about it.

If I didn't set up the "lombok-mapstruct-binding" library, there was no error when I ran the example in the lombok 1.18.35 environment.

Of course, the Mapper implementation class was also generated well.

davidnussio commented 2 weeks ago

I fixed this issue by selecting 'Use Project Version.'

Image

Image

gbrandalise commented 2 weeks ago

@davidnussio in my case this not work because lombok's version is old (1.18.20) and incompatible with extension. But this is a valid alternative

rgrunber commented 2 weeks ago

I think it's because "MapStruct" and "Lombok 1.18.35" are not compatible.

I think you're right. I just tried that and can see the same error. I think that's enough to take to take upstream to either Lombok or Mapstruct. I can go ahead and mention it.

I was having a lot of difficulty reproducing with VS Code Java, but I think I've figured it out. I needed to clear out the target folder and manually issue "Java: Force Java Compilation" (Full) in order to update the error marker correctly. Otherwise, it would continue to show the previous state.

rgrunber commented 2 weeks ago

I've been able to narrow down the issue to the exact commit in Lombok. It appears to be https://github.com/projectlombok/lombok/pull/3744 (which I suspected in https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2450369932 but was having a lot of trouble even showing Lombok was to blame because of the issues mentioned above with consistently reproducing).

Update: Informed on https://github.com/projectlombok/lombok/pull/3744#issuecomment-2462409609.

Update 2: So the workaround mentioned at https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2461695785 is totally valid. You can tell vscode-java to use your project's Lombok version (make it 1.18.34) instead of what we ship (1.18.35 edge). If there aren't major issues with 1.18.34, we could downgrade to that and have something in pre-releases.

@testforstephen @fbricon , let me know your thoughts here.

Radenixlol commented 2 weeks ago

I have an issue with the extension, and well, since it is within the same topic I put it here, I am using Spring Boot 3.3.5, and OpenJDK 17.0.13, and my project uses Lombok 1.18.34 (version given by Spring), and I added MapStruct 1.6.2, and the extension marks me a possible error in my interface marked with the @Mapper of MapStruct, and well, I compile my project, and it generates the classes without any problem, so there really is no such error as the extension marks.

Image

Image

Image

Image

Could you please review this? It's strange to see an error in your project, and you know there is no error.

rgrunber commented 2 weeks ago

@Radenixlol are you using the extension's Lombok version by any chance ? If you have a Java source file or build file (eg. pom.xml) open, you should be able to check as described in https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2461695785 . You should avoid version 1.18.35 for now, which is what the latest version uses. Alternatively, you can try downgrading to vscode-java 1.35.1 as that also works around the issue (ships a lower version of Lombok).

testforstephen commented 2 weeks ago

Update 2: So the workaround mentioned at https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2461695785 is totally valid. You can tell vscode-java to use your project's Lombok version (make it 1.18.34) instead of what we ship (1.18.35 edge). If there aren't major issues with 1.18.34, we could downgrade to that and have something in pre-releases.

@rgrunber Agreed. If Lombok 1.18.34 works well, let's downgrade to it until the upstream Lombok version resolves the issue.

AntonioSeleda commented 2 weeks ago

https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2461695785

Could someone better explain how to access these settings? I've searched a lot but couldn't find them in the interface.

Thanks

fp024 commented 2 weeks ago

@AntonioSeleda

The "{ }" menu appears in the bottom status bar when a Java or XML file is opened in the Editor window.

Radenixlol commented 2 weeks ago

@Radenixlol are you using the extension's Lombok version by any chance ? If you have a Java source file or build file (eg. pom.xml) open, you should be able to check as described in #3836 (comment) . You should avoid version 1.18.35 for now, which is what the latest version uses. Alternatively, you can try downgrading to vscode-java 1.35.1 as that also works around the issue (ships a lower version of Lombok).

Yeah, I'm sure that I'm using Lombok 1.18.34, but I'm not using the Lombok's extension, my dependency tree say Lombok 1.18.34, and well, for now, I downgrade the version of Java by red hat, how can I do that? I don't know

rgrunber commented 2 weeks ago

Select the "Extensions" tab from the left panel. Find "Language Support for Java(TM) by Red Hat" (redhat.java) from from the "Installed" extensions. Once selected, you should see an "Uninstall" button, which has a dropdown beside it. Selecting the dropdown should reveal "Install Specific Version". Select "1.35.1" from the quick-pick menu the comes up.

https://github.com/user-attachments/assets/dd92c69b-59fb-4074-9359-e40afbbeea6f

Also, if you "Switch To Pre-Release Version", it should use Lombok 1.18.34 as of today.

Note: (as mentioned by @testforstephen on another comment, Lombok 1.18.34 doesn't support Java 23) so we really should update as soon as this issue is fixed upstream.

Radenixlol commented 2 weeks ago

Well, I switch the version to the pre-realease and the old version and the extension mark the same error in both cases, so, I'll leave the stable version and ignore the bug for now

Update:

The error was solved, just, I don't know what happened, I left vscode open without doing anything for like half an hour, suddenly it did a resource reading I don't know where, and now it shows that everything is correct

rgrunber commented 2 weeks ago

@Radenixlol I was going to retry the case you mentioned just to be sure, but one thing I would have suggested is, even after updating to Lombok 1.18.34, I needed to manually trigger Java: Force Java Compilation -> (Full) from the command palette. My guess is that updating Lombok didn't re-trigger the full build. I briefly explained it at https://github.com/redhat-developer/vscode-java/issues/3836#issuecomment-2462252671 . Good to know that everyone with the error can use the same workaround.

filiphr commented 2 weeks ago

@rgrunber reading from the comments here is it correct that the VSCode Java Extension is using Lombok 1.18.35? From what I could see this looks like an edge release of Lombok and maybe the accompanying lombok-mapstruct-binding is not released yet.

tle130475c commented 2 weeks ago

My project (multi-module Maven) use mapstruct + lombok together, even before this issue every time open my project, I need to rebuild all project to get rid of error "implementation class not generated". Now the error persist, rebuild all not solve the problem. I have tried workaround in comments, it's work, but like before I need to rebuild all every time I open my project.

rgrunber commented 1 week ago

For the past few days, our pre-releases have contained Lombok 1.18.34, which appears to fix the issue. That will likely be part of our 1.37.0 release at the end of the month.

Looking at https://github.com/projectlombok/lombok/issues/3777#issuecomment-2466122068 , it seems lombok-mapstruct-binding just needs to update to properly support what will become Lombok 1.18.35.

I'll close this issue soon as it appears the workaround (and fix) would work for everyone.

@tle130475c , are you able to share your project ? Seems like maybe you're running it in some cases against a version of Lombok that might be causing issues ?

tle130475c commented 1 week ago

Hi @rgrunber , the project is basically like this: https://github.com/tle130475c/multi-module-project When open it with vscode you will see the error: No implementation was created for CarMapper due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument. If not, please close vscode and open the project again (With a very small percentage, it will not report any errors). "Rebuild All" make the error disappear: Image VScode information:

Version: 1.96.0-insider
Commit: 9b365cafae763d229e999f353831458761aff1cd
Date: 2024-11-11T05:05:11.976Z
Electron: 32.2.1
ElectronBuildId: 10427718
Chromium: 128.0.6613.186
Node.js: 20.18.0
V8: 12.8.374.38-electron.0
OS: Linux x64 6.11.7-arch1-1

Extension information:

Identifier: redhat.java
Version: 1.37.2024111408
Last Updated: 2024-11-14, 16:44:02

It's build no problem with maven Thanks.

rgrunber commented 1 week ago

Yeah, I think I see the same thing even with the other test project. If the project is freshly imported, the error shows up, but if you rebuild the project, or if you reload it and see the error marker, a simple save resolves it. It definitely seems to be related to whether we actually generate the implementation in the folder for generates sources. We don't seem to do it from a fresh import.

@snjeza , might be something worth looking at later, unless this is something known about annotation processing.

snjeza commented 1 week ago

, the project is basically like this: https://github.com/tle130475c/multi-module-project When open it with vscode you will see the error: No implementation was created for CarMapper due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument. If not, please close vscode and open the project again (With a very small percentage, it will not report any errors

@rgrunber @tle130475c Could you try the following patch

diff --git a/module-1/pom.xml b/module-1/pom.xml
index a9cbefe..4aa342c 100644
--- a/module-1/pom.xml
+++ b/module-1/pom.xml
@@ -53,16 +53,16 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.mapstruct</groupId>
-                            <artifactId>mapstruct-processor</artifactId>
-                            <version>${mapstruct.version}</version>
-                        </path>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                             <version>${lombok.version}</version>
                         </path>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${mapstruct.version}</version>
+                        </path>
                         <dependency>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok-mapstruct-binding</artifactId>
diff --git a/module-2/pom.xml b/module-2/pom.xml
index 2bc2a76..d977c74 100644
--- a/module-2/pom.xml
+++ b/module-2/pom.xml
@@ -60,16 +60,16 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.mapstruct</groupId>
-                            <artifactId>mapstruct-processor</artifactId>
-                            <version>${mapstruct.version}</version>
-                        </path>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                             <version>${lombok.version}</version>
                         </path>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${mapstruct.version}</version>
+                        </path>
                         <dependency>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok-mapstruct-binding</artifactId>

The lombok processor should be executed before the mapstruct processor.

rgrunber commented 1 week ago

Yup, I think that was the other problem! @snjeza where did you see this ordering is required ? When I look at https://github.com/mapstruct/mapstruct-examples/blob/main/mapstruct-lombok/pom.xml , it's not even followed there.

Update: https://github.com/mapstruct/mapstruct/issues/1581 seems to imply order did matter at some point.

snjeza commented 1 week ago

@snjeza where did you see this ordering is required ?

https://github.com/mapstruct/mapstruct/issues/510#issuecomment-164172815

tle130475c commented 1 week ago

, the project is basically like this: https://github.com/tle130475c/multi-module-project When open it with vscode you will see the error: No implementation was created for CarMapper due to having a problem in the erroneous element java.util.ArrayList. Hint: this often means that some other annotation processor was supposed to process the erroneous element. You can also enable MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument. If not, please close vscode and open the project again (With a very small percentage, it will not report any errors

@rgrunber @tle130475c Could you try the following patch

diff --git a/module-1/pom.xml b/module-1/pom.xml
index a9cbefe..4aa342c 100644
--- a/module-1/pom.xml
+++ b/module-1/pom.xml
@@ -53,16 +53,16 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.mapstruct</groupId>
-                            <artifactId>mapstruct-processor</artifactId>
-                            <version>${mapstruct.version}</version>
-                        </path>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                             <version>${lombok.version}</version>
                         </path>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${mapstruct.version}</version>
+                        </path>
                         <dependency>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok-mapstruct-binding</artifactId>
diff --git a/module-2/pom.xml b/module-2/pom.xml
index 2bc2a76..d977c74 100644
--- a/module-2/pom.xml
+++ b/module-2/pom.xml
@@ -60,16 +60,16 @@
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
-                        <path>
-                            <groupId>org.mapstruct</groupId>
-                            <artifactId>mapstruct-processor</artifactId>
-                            <version>${mapstruct.version}</version>
-                        </path>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                             <version>${lombok.version}</version>
                         </path>
+                        <path>
+                            <groupId>org.mapstruct</groupId>
+                            <artifactId>mapstruct-processor</artifactId>
+                            <version>${mapstruct.version}</version>
+                        </path>
                         <dependency>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok-mapstruct-binding</artifactId>

The lombok processor should be executed before the mapstruct processor.

This patch fixes the issue when open the project with vscode. Thank you.

rgrunber commented 1 week ago

Based on the discussion upstream, the fix that introduced this issue will be reverted from the development stream (towards 1.18.35). Looks like that fix was incomplete. It's very likely that we'll stick to 1.18.34 for our upcoming release by the end of November. Closing this for now as the issue itself will be resolved (already in our pre-release builds) and the one related issue has a workaround (order of annotation processors).

Thanks to everyone who provided examples, and helped to verify them !

filiphr commented 1 week ago

Thanks @rgrunber for working with the community on making sure that the MapStruct experience with Lombok in VSCode keeps working.

Just to give some insight for some comments I read about the order

Yup, I think that was the other problem! @snjeza where did you see this ordering is required ? When I look at https://github.com/mapstruct/mapstruct-examples/blob/main/mapstruct-lombok/pom.xml , it's not even followed there.

Update: https://github.com/mapstruct/mapstruct/issues/1581 seems to imply order did matter at some point.

For some reason people keep saying that the order is important, with the work we did with the Lombok team and the lombok-mapstruct-binding present the order of the annotation processor in the annotationProcessorPaths does not matter. That's what I am saying in https://github.com/mapstruct/mapstruct/issues/1581 as well.

https://github.com/mapstruct/mapstruct/issues/510#issuecomment-164172815

The linked comment is from 2015, which is long before we worked with the Lombok team to make the two processors work seamlessly together.

rgrunber commented 1 week ago

@filiphr , you're right! And I think I have an example that proves where the issue is.

What I forgot was that as far as command line execution is concerned, the order doesn't matter, and that's what really counts. The build succeeds every time. However, in vscode-java, the error shows up when the project is imported under Maven, but not under Gradle . @snjeza I think that shows it could be an issue in m2e.

Take https://github.com/mapstruct/mapstruct-examples/blob/main/mapstruct-lombok/ , which can be imported as either Maven, or Gradle. Every time you import it as Maven (m2e), you'll get the error until you adjust the order (placing the Lombok annotation processor above the mapstruct one). However, it works just fine with Gradle even though the mapstruct processor is listed before the Lombok one.

filiphr commented 1 week ago

That's interesting information @rgrunber. The fact that it does not work with Maven (m2e) it might be related to the fact that the Eclipse Compiler Java is used and that one might be invoking the processors differently. It might also be related to how the lombok-mapstruct-binding is implemented. Whereas with Gradle the javac compiler is being used (which should be similar to how it is from the command line).

I might be completely wrong though, maybe the ECJ is not used in VSCode.

snjeza commented 1 week ago

I might be completely wrong though, maybe the ECJ is not used in VSCode.

VS Code uses ECJ per default. I can't reproduce the issue with javac

"java.jdt.ls.javac.enabled": "on",