Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

annotation processor of mapstruct can not generate Impl class in vscode. #1660

Closed
yousetme opened this issue Oct 16, 2020 · 31 comments · Fixed by eclipse-jdtls/eclipse.jdt.ls#2319

Comments

@yousetme
Copy link

Mapstruct has supported IDEA and eclipse to generate copier class automatically,but VSCODE doesn't work.
https://mapstruct.org/documentation/ide-support/

Steps To Reproduce

1.define java class
@Mapper(componentModel = "spring")
public interface AccountingFlowDtoCopier extends ObjectCopier<AccountingFlow, AccountingFlowDto> {
}

2.gradle build works and generate AccountingFlowDtoCopierImpl.class to {projectRootDir}/build dir.

2.VSCODE compile file to {projectRootDir}/bin dir and AccountingFlowDtoCopierImpl.class can not generate.

is there some magic? thank!

@fbricon
Copy link
Collaborator

fbricon commented Oct 16, 2020

Please attach a sample project reproducing the issue

@fbricon
Copy link
Collaborator

fbricon commented Oct 19, 2020

I tested with a Maven project and it worked fine. Since you're using gradle, you might want to follow the instructions in http://dplatz.de/blog/2018/gradle-apt.html so that annotation processing configuration files can be generated by gradle

@yousetme
Copy link
Author

Please attach a sample project reproducing the issue

It's my demo project. bin/ dir is generated by VSCODE and build/ dir is generated by "gradle build". bin/ dir does't generate DemoCopierImpl.class but build dir does.
https://github.com/yousetme/mapstruct-gradle-demo

@yousetme
Copy link
Author

I tested with a Maven project and it worked fine. Since you're using gradle, you might want to follow the instructions in http://dplatz.de/blog/2018/gradle-apt.html so that annotation processing configuration files can be generated by gradle

I have try in VSCODE,but it does't work, perhaps it works with Eclipse.

@fbricon
Copy link
Collaborator

fbricon commented Oct 20, 2020

your example doesn't even build from CLI:

./gradlew build                                ✔  11:12:33 

Welcome to Gradle 5.6.2!

Here are the highlights of this release:
 - Incremental Groovy compilation
 - Groovy compile avoidance
 - Test fixtures for Java projects
 - Manage plugin versions via settings script

For more details see https://docs.gradle.org/5.6.2/release-notes.html

Starting a Gradle Daemon, 6 busy and 1 incompatible Daemons could not be reused, use --status for details

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/fbricon/Dev/souk/mapstruct-gradle-demo/build.gradle' line: 2

* What went wrong:
A problem occurred evaluating root project 'halo'.
> Could not get resource 'http://saos-publish-test.chj.cloud/gradle/version.gradle'.
   > Could not GET 'http://saos-publish-test.chj.cloud/gradle/version.gradle'.
      > saos-publish-test.chj.cloud: nodename nor servname provided, or not known

* 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 6s

@yousetme
Copy link
Author

your example doesn't even build from CLI:

./gradlew build                                ✔  11:12:33 

Welcome to Gradle 5.6.2!

Here are the highlights of this release:
 - Incremental Groovy compilation
 - Groovy compile avoidance
 - Test fixtures for Java projects
 - Manage plugin versions via settings script

For more details see https://docs.gradle.org/5.6.2/release-notes.html

Starting a Gradle Daemon, 6 busy and 1 incompatible Daemons could not be reused, use --status for details

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/fbricon/Dev/souk/mapstruct-gradle-demo/build.gradle' line: 2

* What went wrong:
A problem occurred evaluating root project 'halo'.
> Could not get resource 'http://saos-publish-test.chj.cloud/gradle/version.gradle'.
   > Could not GET 'http://saos-publish-test.chj.cloud/gradle/version.gradle'.
      > saos-publish-test.chj.cloud: nodename nor servname provided, or not known

* 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 6s

https://github.com/yousetme/mapstruct-gradle-demo
So sorry to waste your time, it's my negligence to import some no use code. I have clear it, have a try please. thanks.

@yousetme
Copy link
Author

this problem is resolved, gradle demo https://github.com/yousetme/mapstruct-gradle-demo is work in VSCODE with http://dplatz.de/blog/2018/gradle-apt.html .
our project is not work in VSCODE, i think it's gradle version or it's dependence version problem.
Thanks!
image

@chiragai
Copy link

chiragai commented Nov 11, 2020

I have the same problem but I am using maven for the build.
This are the dependency which I am using

<dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>

Here is a build plugin

<plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>xxx</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <release>${java.version}</release>
          <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>
          </annotationProcessorPaths>
          <compilerArgs>-Amapstruct.defaultComponentModel=spring</compilerArgs>
        </configuration>
      </plugin>
    </plugins>

No Impl class is generated.
@fbricon any help or suggestion on this. Thank you

@mainmethod0126
Copy link

Still not available in VSCODE?

@pumano
Copy link

pumano commented Mar 10, 2021

got the same problem

@PandaGeek1024
Copy link

Getting the same problem, any updates?

@PandaGeek1024
Copy link

works fine when building with gradle command, looks like mainly a vscode thing.

@snjeza
Copy link
Contributor

snjeza commented Mar 28, 2021

@PandaGeek1024 @pumano @chiragai could you attach a project example?

@pumano
Copy link

pumano commented Apr 10, 2021

@snjeza yes, I prepare repo for it: https://github.com/pumano/vscode-mapstruct-tests
just check via gradle clean test and then try to run via vscode.

You got java.lang.ExceptionInInitializerError which Caused by: java.lang.ClassNotFoundException: Cannot find implementation for com.example.vscode.mapstructdemo.mappers.ExampleMapper

looks like path to generated code by annotation processor not included to tests.

@snjeza
Copy link
Contributor

snjeza commented Apr 12, 2021

@pumano could you try the following patch:

diff --git a/build.gradle b/build.gradle
index 18beeb8..965f6de 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@ plugins {
        id 'org.springframework.boot' version '2.4.4'
        id 'io.spring.dependency-management' version '1.0.11.RELEASE'
        id 'java'
+       id 'eclipse'
 }
 
 group = 'com.example.vscode'
@@ -26,3 +27,14 @@ dependencies {
 test {
        useJUnitPlatform()
 }
+
+eclipse {
+    classpath {
+        containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
+        file.whenMerged { cp ->
+            def entries = cp.entries;
+            def src = new org.gradle.plugins.ide.eclipse.model.SourceFolder('build/generated/sources/annotationProcessor/java/main/', null)
+            entries.add(src)
+        } 
+    }
+}

@pumano
Copy link

pumano commented Apr 12, 2021

@snjeza wow! Works like a charm! Would be good to have it out of the box if possible.

Ok for this simple project problem solved, but for multimodule gradle project - same problem.

@snjeza
Copy link
Contributor

snjeza commented Apr 13, 2021

Ok for this simple project problem solved, but for multimodule gradle project - same problem.

@pumano could you attach a multimodule project?

@pumano
Copy link

pumano commented Apr 13, 2021

Ok for this simple project problem solved, but for multimodule gradle project - same problem.

@pumano could you attach a multimodule project?

Ok I will prepare it soon

@AriseIGitHub
Copy link

I have the same problem. When can you fix it?

@ad798
Copy link

ad798 commented Jun 4, 2021

Hello everyone! I am happy to say I found a way to solve this. I got it working with Spring Boot + Lombok + Mapstruct with Maven Wrapper. The key is to put the mapstuct and mapstruct-processor as dependencies. Here is how the result pom.xml looks like.

<properties>
	<java.version>11</java.version>
	<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
</properties>
<dependencies>
        <!--Spring Boot dependencies omitted for brevity-->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>org.mapstruct</groupId>
		<artifactId>mapstruct</artifactId>
		<version>${org.mapstruct.version}</version>
		<optional>true</optional>
	</dependency>
	<dependency>
		<groupId>org.mapstruct</groupId>
		<artifactId>mapstruct-processor</artifactId>
		<version>${org.mapstruct.version}</version>
		<optional>true</optional>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
			<configuration>
				<excludes>
					<exclude>
						<groupId>org.projectlombok</groupId>
						<artifactId>lombok</artifactId>
					</exclude>
					<exclude>
						<groupId>org.mapstruct</groupId>
						<artifactId>mapstruct</artifactId>
					</exclude>
					<exclude>
						<groupId>org.mapstruct</groupId>
						<artifactId>mapstruct-processor</artifactId>
					</exclude>
				</excludes>
			</configuration>
		</plugin>
	</plugins>
</build>

@pumano
Copy link

pumano commented Jun 4, 2021

@ad798 It's good, but how to solve this via gradle...

@Yanxinwei
Copy link

I have the same problem but I am using maven for the build.
This are the dependency which I am using

<dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>

Here is a build plugin

<plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>xxx</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <release>${java.version}</release>
          <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>
          </annotationProcessorPaths>
          <compilerArgs>-Amapstruct.defaultComponentModel=spring</compilerArgs>
        </configuration>
      </plugin>
    </plugins>

No Impl class is generated.
@fbricon any help or suggestion on this. Thank you

Was this problem solved? I just got the same one. @chiragai Thanks

@activedgetechnologies
Copy link

@snjeza wow! Works like a charm! Would be good to have it out of the box if possible.

Ok for this simple project problem solved, but for multimodule gradle project - same problem.

yeah!

@Yanxinwei
Copy link

Yanxinwei commented Aug 9, 2021

I have the same problem but I am using maven for the build.
This are the dependency which I am using

<dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>
    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <version>${mapstruct.version}</version>
    </dependency>

Here is a build plugin

<plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <mainClass>xxx</mainClass>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.0</version>
        <configuration>
          <release>${java.version}</release>
          <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>
          </annotationProcessorPaths>
          <compilerArgs>-Amapstruct.defaultComponentModel=spring</compilerArgs>
        </configuration>
      </plugin>
    </plugins>

No Impl class is generated.
@fbricon any help or suggestion on this. Thank you

Was this problem solved? I just got the same one. @chiragai Thanks

I solved this problem by adding this dependency in my project module, while my project compiled succeessfully but didn't generate implementation classes.

`

   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct-processor</artifactId>
   <scope>compile</scope>
`

@ivadoncheva
Copy link

ivadoncheva commented Feb 7, 2022

Hello, I am getting the same error when mapstruct generates impl class for my Mapper, one of the classes is not listed as import. Then if I open the impl class I'm able import the package, but mapstruct doesn't not import it during generation of the class and therefore the class could not be used. I'm using gradle and Intelij. Is there any updates or work done on this?

@javohircomunity
Copy link

I have the same problem but I am using gradle for the build.
When I run project then mapper impl class couldn't generate.
How can i solve the problem.

@ivadoncheva
Copy link

@javohircomunity I have managed to find a way to get this running by using in my interface the following annotation:

@Mapper(componentModel = "spring", imports = <YourClass>.class)
public interface SomeClassMapper {
// the SomeClassMapperImpl which is generated by mapstruct now imports YourClass
}

@javohircomunity
Copy link

@javohircomunity I have managed to find a way to get this running by using in my interface the following annotation:

@Mapper(componentModel = "spring", imports = <YourClass>.class)
public interface SomeClassMapper {
// the SomeClassMapperImpl which is generated by mapstruct now imports YourClass
}

I haven't any import class, There are many String fields.

@mishi321
Copy link

mishi321 commented Apr 4, 2022

*Impl.class didn't generate by vscode run , but it work well by gradle bootRun. So everytime I copy *Impl.class from build(gradle compile folder) to bin(vscode compile folder) by hand let vscode to run.

@laDanz
Copy link

laDanz commented Jul 7, 2022

@ad798 It's good, but how to solve this via gradle...

@snjeza 's patch is fixing it: #1660 (comment)

@appleseedexm
Copy link

There also seems a specific setup where mapstruct doesnt build *Impl of abstract classes extending other classes. We have in our project one specific abstract class which doesnt get an *Impl class, but in IntelliJ it does. As soon as I remove the "extends from", the *Impl is created. I've not come around to investigate this and create a sample project, but I'll update here as soon as I have a better bug report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.