Repository: apache/gravitino (Java)

Issue:
[Improvement] Fix NPE in TableFormat.java when a user has no roles
### What would you like to be improved?

In clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java, getOutput can NPE if a user has no roles.

Here's a test showing that:
```
  @Test
  void testUserDetailsWithNullRoles() {
    CommandContext mockContext = TestCliUtil.getMockContext();
    User mockUser = mock(User.class);
    when(mockUser.name()).thenReturn("user1");
    when(mockUser.roles()).thenReturn(null);

    TableFormat.output(mockUser, mockContext);
    String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
    Assertions.assertEquals(
        "+-------+-------+\n"
            + "| Name  | Roles |\n"
            + "+-------+-------+\n"
            + "| user1 |       |\n"
            + "+-------+-------+",
        output);
  }
```


### How should we improve?

Fix so no NPE happens.


Discussion:
@justinmclean Can I look in this issue?
Sure.  Please see our CONTRIBUTING guide.  For code contributions, it explains how to compile with Gradle, run unit tests (unit tests should cover all code changes), and format code with Spotless before submitting a PR.
Hi @vmanik2k , if you don't mind I can take a look on this one.
@playasim Sure you can



Patch:
diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
index 6ac3ff575a2..2eebb6e17e6 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/outputs/TableFormat.java
@@ -42,6 +42,7 @@
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -845,7 +846,9 @@ public String getOutput(User user) {
       Column columnRoles = new Column(context, "roles");
 
       columnName.addCell(user.name());
-      columnRoles.addCell(Command.COMMA_JOINER.join(user.roles()));
+
+      List<String> roleList = user.roles() == null ? new ArrayList<>() : user.roles();
+      columnRoles.addCell(Command.COMMA_JOINER.join(roleList));
 
       return getTableFormat(columnName, columnRoles);
     }


Test patch:
diff --git a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
index 54140a1d0dd..48fe9e580e2 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/output/TestTableFormat.java
@@ -950,4 +950,22 @@ public String getOutput(String entity) {
 
     Assertions.assertEquals(expected.trim(), outputString.trim());
   }
+
+  @Test
+  void testUserDetailsWithNullRoles() {
+    CommandContext mockContext = TestCliUtil.getMockContext();
+    User mockUser = mock(User.class);
+    when(mockUser.name()).thenReturn("user1");
+    when(mockUser.roles()).thenReturn(null);
+
+    TableFormat.output(mockUser, mockContext);
+    String output = new String(outContent.toByteArray(), StandardCharsets.UTF_8).trim();
+    Assertions.assertEquals(
+        "+-------+-------+\n"
+            + "| Name  | Roles |\n"
+            + "+-------+-------+\n"
+            + "| user1 |       |\n"
+            + "+-------+-------+",
+        output);
+  }
 }