如何在自定义Java Sonar规则中获取用户自定义类型的全限定名
I'm building a custom Checkstyle check and ran into an issue when trying to get the fully qualified name (FQN) of user-defined class types. For standard types like String, the code correctly returns java.lang.String, but for my own UserDefined class, it outputs !unknownSymbol! instead of the expected FQN.
Here's my code setup:
public class UserDefinedDTO { // userDefined variable refers to UserDefined class private UserDefined userDefined; private String name; } @Rule(key = "UserDefinedChecks", name = "Java Doc check", description = "", priority = Priority.BLOCKER, tags = { "bug" }) public class UserDefinedChecks extends IssuableSubscriptionVisitor{ @Override public List<Kind> nodesToVisit() { return ImmutableList.of(Kind.VARIABLE); } @Override public void visitNode(Tree tree) { VariableTree variable = (VariableTree) tree; String name = variable.type().symbolType().fullyQualifiedName(); System.out.println(name); } }
When executing this check, the output I get is:
java.lang.String !unknownSymbol!
I need help figuring out how to properly resolve the FQN for user-defined classes in this context.
Solution
The issue happens because Checkstyle's symbol resolution might not have access to your user-defined class definitions, or the symbolType() method isn't properly resolving the symbol for custom classes yet. Here are a few fixes you can try:
1. Ensure your user-defined classes are in Checkstyle's classpath
First, make sure when running Checkstyle, you include the directory or JAR containing your UserDefined class in the classpath. Without this, Checkstyle can't resolve the class's symbol and will return !unknownSymbol!.
2. Use TypeMirror instead of symbolType()
You can retrieve the TypeMirror from the variable's type tree, which often provides a more reliable FQN for resolved types:
@Override public void visitNode(Tree tree) { VariableTree variable = (VariableTree) tree; TypeMirror typeMirror = variable.type().getTypeMirror(); if (typeMirror != null) { System.out.println(typeMirror.toString()); } else { // Fallback to symbol lookup if type mirror is unavailable Symbol symbol = variable.type().symbol(); if (symbol != null) { System.out.println(symbol.getQualifiedName()); } else { System.out.println("!unknownSymbol!"); } } }
3. Use Checkstyle's SymbolUtils utility
Checkstyle provides a SymbolUtils class that simplifies qualified name resolution. This handles edge cases like unresolved symbols more gracefully:
import com.puppycrawl.tools.checkstyle.utils.SymbolUtils; // ... @Override public void visitNode(Tree tree) { VariableTree variable = (VariableTree) tree; Symbol typeSymbol = variable.type().symbol(); String fqn = SymbolUtils.getQualifiedName(typeSymbol); System.out.println(fqn != null ? fqn : "!unknownSymbol!"); }
The key here is ensuring Checkstyle can access your user-defined classes during analysis, and using the right utility methods to resolve the symbol's qualified name.
内容的提问来源于stack exchange,提问作者Sandeep Choudhari

