lombokjava-17intellij-lombok-plugin

Using Lombok 1.18.24 and jdk 17 class complilation fails on import lombok.var


I am running through some examples for lombok and I am attempting to use the lombok.var. I am using jdk 17 and lombok 1.18.24 with spring boot. I am aware that the JEP 286 made available var type in Jdk 10 but the lombok documentation seems to say this should work. At first i was trying to build this via IntelliJ and all my other lombok tutorials worked fine except when I came to lombok.var. So I switched to building form terminal with ./gradlew clean build and still got the same error:

.../src/main/java/com/example/service/EmployeeImageService.java:6:error: illegal reference to restricted type 'var'
import lombok.var;
             ^

Here is my gradle file:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.1'
    id 'io.spring.dependency-management' version '1.1.0'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok:1.18.24'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

I included the lombok.config in the root of my project. It has the following settings:

lombok.nonNull.exceptionType=IllegalArgumentException
lombok.var.flagUsage=ALLOW

My sample class that includes the lombok import:

package com.example.service;

import com.example.dao.Employee;
import com.example.repository.EmployeeRepository;
import lombok.RequiredArgsConstructor;
import lombok.var;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@RequiredArgsConstructor
@Service
public class EmployeeImageService {
    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeImageService.class);
    private final EmployeeRepository employeeRepository;

    public byte[] findEmployeeImageById(final Long id){
        LOGGER.info("EmployeeImageService.findEmployeeImageById() - retrieving employee image");
        var message = "Hello";
        message = message + " World!";

        var employee = employeeRepository.findById(id);
        return employee.map(Employee::getImage).orElse(null);
    }
...
}

Like I said, I know that JEP 286 in Jdk 10 released the var reference type but I don't understand what could be causing this import lombok.var throw the compile time error:

.../src/main/java/com/example/service/EmployeeImageService.java:6:error: illegal reference to restricted type 'var'
import lombok.var;
             ^

Solution

  • Because, as the error says, java10 is slightly backwards incompatible in the sense that trying to name a type var is now no longer allowed at all and that error message pops up. Team OpenJDK introduced this incompatibility in fairness, because who names their type var?

    As the var docs state, lombok introduced var because java10 introduced var as a keyword - it exists solely for java6/7/8/9 developers to be able to use it without having to update their JDK. At the time of writing (early 2023), the only users of lombok.var should be those still on java 8. Which you should probably really start planning on getting away from soon, it's in the 'support at this point requires a commercial license, it is that old' phase of life.

    Lombok does not drop support for out-of-support java versions (Lombok still supports java 6!), unless there is a pressing need to do so. There's a bit of baggage wrapped up in j6/7/8 support we may at some point actually want to ditch, but until java8 usage worldwide shrinks down to a tiny set, we wouldn't. But, if we ever drop that support, lombok.var would be completely deleted. It cannot be used in JDK10 and up.

    val remains a feature we will continue to support, and val works fine in JDK6-19. It's essentially just final var. Unlike var, val is not a contextual keyword.

    The solution

    If you have a codebase that uses lombok's var and you upgrade it to a JDK edition 10 or higher, simply... delete the import statements, and leave the actual usages of var untouched. Except in vanishingly rare cases (primarily, doubling up: var x = 5, y = "Hello"; is legal lombok-var, not legal java-var, that's about it) - your code will do the same thing.

    SOURCE: I'm one of the main lombok maintainers.