Why is this an issue?

The common pattern of taking a class-file entity, obtaining a corresponding builder, examining each element of the entity and possibly replacing it with other elements can be expressed by transforms. Using the transformClass method in that case instead of build removes all that boilerplate and makes the intent clearer.

How to fix it

Use the ClassFile.transformClass method instead of ClassFile.build.

Code examples

Noncompliant code example

public static void transformClassFile(Path path) throws IOException {
  ClassFile classFile = ClassFile.of();
  ClassModel classModel = classFile.parse(path);
  byte[] newBytes = classFile.build( // Noncompliant
    classModel.thisClass().asSymbol(), classBuilder -> {
        for (ClassElement classElement : classModel) {
          if (!(classElement instanceof MethodModel methodModel &&
              methodModel.methodName().stringValue().startsWith("debug"))) {
            classBuilder.with(classElement);

          }
        }
    });
  Files.write(path, newBytes);
}

Compliant solution

public static void transformClassFile(Path path) throws IOException {
  ClassFile classFile = ClassFile.of();
  ClassModel classModel = classFile.parse(path);
  byte[] newBytes = classFile.transformClass(
    classModel, (classBuilder, classElement) -> {
      if (!(classElement instanceof MethodModel methodModel &&
            methodModel.methodName().stringValue().startsWith("debug"))) {
          classBuilder.with(classElement);
        }
      });
  Files.write(path, newBytes);
}

Resources