Movatterモバイル変換


[0]ホーム

URL:


Sitemap
Open in app

Why Lombok and MapStruct Dependency Order is Important

Gradle helps manage your project’s dependencies. However, the order in which you declare these dependencies can impact how they work together, especially for tools likeLombok andMapStruct.

During the build process, Gradle runs special tools calledannotation processors that help generate extra code based on your annotations.

Compilation Stages

  1. Source Code Scanning:
    The compiler scans your project’s source files to understand the structure of your code, preparing it for further processing.
  2. Annotation Processing:
    Gradle runs annotation processors, which analyze your annotations (like@Getter from Lombok or@Mapper fromMapStruct) and generate additional code.
  3. Compiling Generated Code:
    The compiler combines your original code and the newly generated code, converting them into bytecode, which can run on the Java Virtual Machine (JVM).

Why the Order of annotationProcessor Matters

Gradle runs annotation processors in the same order they appear in yourbuild.gradle file.

Consider this example:

dependencies {
annotationProcessor("org.mapstruct:mapstruct-processor:1.5.5.Final")
annotationProcessor("org.projectlombok:lombok:1.18.34")
}

What Happens When MapStruct Runs First?

  1. MapStruct runs first: It tries to generate mappers by accessing methods likegetId() andgetUserName(), but these methods are not yet available because Lombok hasn’t generated them.
  2. Compilation Error: When MapStruct tries to create the mapper, it looks for methods likegetId() andgetUserName(). But since Lombok hasn’t generated them yet, MapStruct gets confused and can’t do its job.

When MapStruct runs before Lombok, you might encounter an error like this during compilation:

warning: Unmapped target properties: "id, userName".
UserDTO mapToUserDto(User user);

and generated class as:

public class UserMapperImpl implements UserMapper {

@Override
public UserDTO mapToUserDto(User user) {
if ( user == null ) {
return null;
}

// only initialization with null values
Long id = null;
String userName = null;

UserDTO userDTO = new UserDTO( id, userName );

return userDTO;
}
}

Lombok must finish building its parts (likegetters andsetters) before MapStruct can build the final product. If MapStruct starts too early, it won't have all the necessary pieces.

The Correct Order

To avoid this issue, you should declare your dependencies in the following order:

dependencies {
annotationProcessor("org.projectlombok:lombok:1.18.34")
annotationProcessor("org.mapstruct:mapstruct-processor:1.5.5.Final")
}

In this case:

  1. Lombok runs first, generating the necessary methods.
  2. MapStruct then uses the generated code to create mappers successfully.

And generated implementation is correct:

public class UserMapperImpl implements UserMapper {

@Override
public UserDTO mapToUserDto(User user) {
if ( user == null ) {
return null;
}

Long id = null;
String userName = null;

// Lombok-generated getters will be used here
id = user.getId();
userName = user.getUserName();

UserDTO userDTO = new UserDTO( id, userName );

return userDTO;
}
}

How to Verify annotationProcessor Order

You can check the order of annotation processors using the following command:

gradle dependencies --configuration annotationProcessor

This command will list all annotation processors in the order they are passed to the compiler:

annotationProcessor - Annotation processors and their dependencies for source set 'main'.
+--- org.projectlombok:lombok:1.18.34
\--- org.mapstruct:mapstruct-processor:1.5.5.Final

This shows that Lombok runs before MapStruct, ensuring everything works correctly.

Conclusion

Remember, the right dependency order isn’t just a best practice — it’s the secret sauce that keeps your build process running smoothly, especially when using libraries like Lombok and MapStruct together.

DeclareLombok first, then MapStruct and your code will work as expected.

Have you faced similar issues with annotation processors? Share your experience in the comments!

--

--

Responses (1)


[8]ページ先頭

©2009-2025 Movatter.jp