Enable preview feature in Java

Solve preview feature disabled by default. use --enable-preview to enable in Intellij gradle

I upgraded to JDK 21, tried to use the String templates feature which is a preview feature and got hit with the error in IntelliJ: preview feature disabled by default

Meanwhile, I had set the Project language level to 21 (preview) as shown here

Resolution Steps

To resolve this, let's first confirm that this file can be compiled outside of the Integrated Developer Environment.

The complete code.

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.UUID;

import static java.lang.StringTemplate.STR;

public class RequestHashGenerator {
    private static final String secret = "fake-secret";
    private static final String xWebHookHeader = "x-webhook-hmac";

    private static final Mac mac;

    static {
        String algorithm = "HmacSHA512";
        try {
            mac = Mac.getInstance(algorithm);
            mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), algorithm));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException(e);
        }
    }

    private static String generateHash(String payload) {
        return Base64.getEncoder().encodeToString(mac.doFinal(payload.getBytes(StandardCharsets.UTF_8)));
    }

    public static void main(String[] args) {
        var customer = new Customer("John Okafor", UUID.fromString("e1221b65-6027-446e-a4ef-cf8cda75b399"), "+233898232942", "50.50", "2023-11-20T09:23:23Z");
        String payload = STR.
                """
                {
                    "customerName": "\{customer.customerName}",
                    "customerId": "\{customer.customerId}",
                    "customerPhone": "\{customer.customerPhone}",
                    "amount": "\{customer.amount}",
                    "paidAt": "\{customer.paidAt}"
                """;
        var hash = generateHash(payload);
        System.out.println(hash);
    }

    record Customer(String customerName, UUID customerId, String customerPhone, String amount, String paidAt){}

}

Compile command

javac --enable-preview --release 21 RequestHashGenerator.java

output

Run command

java --enable-preview RequestHashGenerator

output

It works! we confirmed that we can compile and execute String templates preview feature, we proceed to attempt a fix in the IDE.

The same compile and execute steps need to be run even in the IDE

As gradle doesn't support preview features explicitly, we'll have to add it manually. Add the following to your build.gradle file to pass the argument to the compile task

compileJava {
	options.compilerArgs += ['--enable-preview']
}

To enable preview in test task, add the following

test {
	jvmArgs '--enable-preview'
}

Does it work?

Gradle is fine.

we run ./gradlew clean build and it succeeds

Add VM Option to Intellij

Select the modify option

Add the VM Option

And that's it !!! Project compiles starts up fine and runs.

You can drop suggestions if you find other ways.