Repository: deepjavalibrary/djl
Pull request #3288 (2024-06-28 21:14:26)

[api] Allows to control json pretty print with env var
## Description ##

Brief description of what this PR is about

- If this change is a backward incompatible change, why must this change be made?
- Interesting edge cases to note here



Patch:
diff --git a/api/src/main/java/ai/djl/modality/nlp/translator/NamedEntity.java b/api/src/main/java/ai/djl/modality/nlp/translator/NamedEntity.java
index 4af9c141f..72d00c468 100644
--- a/api/src/main/java/ai/djl/modality/nlp/translator/NamedEntity.java
+++ b/api/src/main/java/ai/djl/modality/nlp/translator/NamedEntity.java
@@ -100,6 +100,6 @@ public class NamedEntity {
     /** {@inheritDoc} */
     @Override
     public String toString() {
-        return JsonUtils.GSON_PRETTY.toJson(this);
+        return JsonUtils.toJson(this);
     }
 }
diff --git a/api/src/main/java/ai/djl/ndarray/BytesSupplierImpl.java b/api/src/main/java/ai/djl/ndarray/BytesSupplierImpl.java
index 93ed023a1..d3f7198c1 100644
--- a/api/src/main/java/ai/djl/ndarray/BytesSupplierImpl.java
+++ b/api/src/main/java/ai/djl/ndarray/BytesSupplierImpl.java
@@ -40,7 +40,7 @@ class BytesSupplierImpl implements BytesSupplier {
     public byte[] getAsBytes() {
         if (buf == null) {
             if (value == null) {
-                value = JsonUtils.GSON.toJson(obj) + '\n';
+                value = JsonUtils.toJson(obj) + '\n';
             }
             buf = value.getBytes(StandardCharsets.UTF_8);
         }
@@ -52,7 +52,7 @@ class BytesSupplierImpl implements BytesSupplier {
     public String getAsString() {
         if (value == null) {
             if (obj != null) {
-                value = JsonUtils.GSON.toJson(obj) + '\n';
+                value = JsonUtils.toJson(obj) + '\n';
             } else {
                 value = new String(buf, StandardCharsets.UTF_8);
             }
diff --git a/api/src/main/java/ai/djl/util/JsonUtils.java b/api/src/main/java/ai/djl/util/JsonUtils.java
index 88d6af0b1..b691737b3 100644
--- a/api/src/main/java/ai/djl/util/JsonUtils.java
+++ b/api/src/main/java/ai/djl/util/JsonUtils.java
@@ -24,8 +24,9 @@ import java.util.List;
 /** An interface containing Gson constants. */
 public interface JsonUtils {
 
-    Gson GSON = new GsonBuilder().create();
-    Gson GSON_PRETTY = builder().create();
+    boolean PRETTY_PRINT = Boolean.parseBoolean(Utils.getEnvOrSystemProperty("DJL_PRETTY_PRINT"));
+    Gson GSON = builder().create();
+    Gson GSON_PRETTY = builder().setPrettyPrinting().create();
     Type LIST_TYPE = new TypeToken<List<String>>() {}.getType();
 
     /**
@@ -34,19 +35,33 @@ public interface JsonUtils {
      * @return a custom {@code GsonBuilder} instance.
      */
     static GsonBuilder builder() {
-        return new GsonBuilder()
-                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
-                .setPrettyPrinting()
-                .serializeSpecialFloatingPointValues()
-                .registerTypeAdapter(
-                        Double.class,
-                        (JsonSerializer<Double>)
-                                (src, t, ctx) -> {
-                                    long v = src.longValue();
-                                    if (src.equals(Double.valueOf(String.valueOf(v)))) {
-                                        return new JsonPrimitive(v);
-                                    }
-                                    return new JsonPrimitive(src);
-                                });
+        GsonBuilder builder =
+                new GsonBuilder()
+                        .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+                        .serializeSpecialFloatingPointValues()
+                        .registerTypeAdapter(
+                                Double.class,
+                                (JsonSerializer<Double>)
+                                        (src, t, ctx) -> {
+                                            long v = src.longValue();
+                                            if (src.equals(Double.valueOf(String.valueOf(v)))) {
+                                                return new JsonPrimitive(v);
+                                            }
+                                            return new JsonPrimitive(src);
+                                        });
+        if (PRETTY_PRINT) {
+            builder.setPrettyPrinting();
+        }
+        return builder;
+    }
+
+    /**
+     * Serializes the specified object into its equivalent JSON representation.
+     *
+     * @param src the source object
+     * @return the json string
+     */
+    static String toJson(Object src) {
+        return GSON.toJson(src);
     }
 }
diff --git a/basicdataset/src/main/java/ai/djl/basicdataset/nlp/StanfordQuestionAnsweringDataset.java b/basicdataset/src/main/java/ai/djl/basicdataset/nlp/StanfordQuestionAnsweringDataset.java
index 9912fe877..053395237 100644
--- a/basicdataset/src/main/java/ai/djl/basicdataset/nlp/StanfordQuestionAnsweringDataset.java
+++ b/basicdataset/src/main/java/ai/djl/basicdataset/nlp/StanfordQuestionAnsweringDataset.java
@@ -115,7 +115,7 @@ public class StanfordQuestionAnsweringDataset extends TextDataset implements Raw
         Map<String, Object> data;
         try (BufferedReader reader = Files.newBufferedReader(usagePath)) {
             data =
-                    JsonUtils.GSON_PRETTY.fromJson(
+                    JsonUtils.GSON.fromJson(
                             reader, new TypeToken<Map<String, Object>>() {}.getType());
         }
         List<Map<String, Object>> articles = (List<Map<String, Object>>) data.get("data");
@@ -227,7 +227,7 @@ public class StanfordQuestionAnsweringDataset extends TextDataset implements Raw
         Path usagePath = prepareUsagePath(null);
         Object data;
         try (BufferedReader reader = Files.newBufferedReader(usagePath)) {
-            data = JsonUtils.GSON_PRETTY.fromJson(reader, new TypeToken<Object>() {}.getType());
+            data = JsonUtils.GSON.fromJson(reader, new TypeToken<Object>() {}.getType());
         }
         return data;
     }
diff --git a/engines/mxnet/mxnet-model-zoo/src/main/java/ai/djl/mxnet/zoo/nlp/embedding/GloveWordEmbeddingTranslatorFactory.java b/engines/mxnet/mxnet-model-zoo/src/main/java/ai/djl/mxnet/zoo/nlp/embedding/GloveWordEmbeddingTranslatorFactory.java
index de9cb4ffc..a5d6213c1 100644
--- a/engines/mxnet/mxnet-model-zoo/src/main/java/ai/djl/mxnet/zoo/nlp/embedding/GloveWordEmbeddingTranslatorFactory.java
+++ b/engines/mxnet/mxnet-model-zoo/src/main/java/ai/djl/mxnet/zoo/nlp/embedding/GloveWordEmbeddingTranslatorFactory.java
@@ -70,6 +70,7 @@ public class GloveWordEmbeddingTranslatorFactory implements TranslatorFactory {
         /** {@inheritDoc} */
         @Override
         public NDList processOutput(TranslatorContext ctx, NDList list) {
+            list.detach();
             return list;
         }
 


Test patch:
diff --git a/extensions/tokenizers/src/test/java/ai/djl/huggingface/zoo/ModelZooTest.java b/extensions/tokenizers/src/test/java/ai/djl/huggingface/zoo/ModelZooTest.java
index ec149df38..4605702a1 100644
--- a/extensions/tokenizers/src/test/java/ai/djl/huggingface/zoo/ModelZooTest.java
+++ b/extensions/tokenizers/src/test/java/ai/djl/huggingface/zoo/ModelZooTest.java
@@ -84,7 +84,7 @@ public class ModelZooTest {
             Files.createDirectories(dir);
             Path file = dir.resolve("models.json");
             try (Writer writer = Files.newBufferedWriter(file)) {
-                writer.write(JsonUtils.GSON_PRETTY.toJson(map));
+                writer.write(JsonUtils.toJson(map));
             }
 
             // static variables cannot not be initialized properly if directly use new HfModelZoo()