Debugging JavaPoet exceptions

Originally posted on 2020-11-30

JavaPoet is an incredible system for generating code. Debugging JavaPoet leaves a lot to be desired in my opinion though. I'll give the JavaPoet team credit though. It's impossible to anticipate what people are going to do with it and that makes coming up with clever error messages really challenging. Below are a few things that I've run into that will hopefully save you some time if you run into them.

Exception during compilation Caused by: java.lang.IllegalArgumentException: cannot unindent 1 from 0

When I ran into this it was on a piece of code that was creating a new method that looked like this:

ClassName arrayList = ClassName.get("java.util", "ArrayList");

ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(List.class, MyClass.class);

return typeSpecBuilder.addMethod(
    MethodSpec.methodBuilder("returnEmpty")
              .addStatement("return new T$<>()", arrayList)
              .build());
🚨Can you spot what is wrong?🚨

Can you spot what's wrong? In this case I've transposed the T and the $ character. When the compilation step reports an error though it doesn't actually point to the correct line that contains this mistake. Instead it points to the code that is writing it to a file.

So what should you do? Find any lines that use the $T syntax and make sure the characters are not transposed.

If they're return statements you can comment them out and replace them with return null. If that works then the characters are likely transposed. The correct code sample looks like this:

ClassName arrayList = ClassName.get("java.util", "ArrayList");

ParameterizedTypeName parameterizedTypeName = ParameterizedTypeName.get(List.class, MyClass.class);

return typeSpecBuilder.addMethod(
    MethodSpec.methodBuilder("returnEmpty")
              .addStatement("return new $T<>()", arrayList)
              .build());
👆This is the right way to do it👍