This is an automated email from the ASF dual-hosted git repository.

ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new 838e6f477b Make instantiating Gson singletons easier (#3531)
838e6f477b is described below

commit 838e6f477ba0ea1ecd6d4efe5f79267f6ecdb298
Author: Christopher Tubbs <ctubb...@apache.org>
AuthorDate: Fri Jun 23 17:12:59 2023 -0400

    Make instantiating Gson singletons easier (#3531)
    
    * Create LazySingletons class to host singleton suppliers
    * Add lazy GSON singleton supplier
    * Replace GsonSingleton class from #3516 with this
---
 .../core/clientImpl/bulk/BulkSerialize.java        |  4 +--
 .../apache/accumulo/core/lock/ServiceLockData.java |  9 +++----
 .../schema/ExternalCompactionFinalState.java       |  7 ++---
 .../schema/ExternalCompactionMetadata.java         |  6 ++---
 .../core/metadata/schema/RootTabletMetadata.java   |  6 ++---
 .../spi/compaction/DefaultCompactionPlanner.java   |  7 ++---
 .../spi/scan/ConfigurableScanServerSelector.java   |  6 ++---
 .../{GsonSingleton.java => LazySingletons.java}    | 30 ++++++++++------------
 pom.xml                                            |  4 +++
 .../accumulo/server/metadata/RootGcCandidates.java |  6 ++---
 .../accumulo/manager/tableOps/TraceRepo.java       |  5 ++--
 .../util/logging/AccumuloMonitorAppender.java      |  4 +--
 .../accumulo/test/CountNameNodeOpsBulkIT.java      |  4 +--
 13 files changed, 50 insertions(+), 48 deletions(-)

diff --git 
a/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
 
b/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
index bff210ee80..533a43c237 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/clientImpl/bulk/BulkSerialize.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.core.clientImpl.bulk;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
@@ -37,7 +38,6 @@ import org.apache.accumulo.core.clientImpl.bulk.Bulk.Files;
 import org.apache.accumulo.core.clientImpl.bulk.Bulk.Mapping;
 import org.apache.accumulo.core.data.TableId;
 import org.apache.accumulo.core.dataImpl.KeyExtent;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.core.util.json.ByteArrayToBase64TypeAdapter;
 import org.apache.hadoop.fs.Path;
 
@@ -98,7 +98,7 @@ public class BulkSerialize {
     final Path renamingFile = new Path(bulkDir, Constants.BULK_RENAME_FILE);
     try (OutputStream fsOut = output.create(renamingFile);
         BufferedWriter writer = new BufferedWriter(new 
OutputStreamWriter(fsOut))) {
-      GsonSingleton.getInstance().toJson(oldToNewNameMap, writer);
+      GSON.get().toJson(oldToNewNameMap, writer);
     }
   }
 
diff --git 
a/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java 
b/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
index ed624be642..736a36f0fe 100644
--- a/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
+++ b/core/src/main/java/org/apache/accumulo/core/lock/ServiceLockData.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.lock;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static java.util.Objects.requireNonNull;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.util.Collections;
 import java.util.EnumMap;
@@ -29,7 +30,6 @@ import java.util.Set;
 import java.util.UUID;
 
 import org.apache.accumulo.core.util.AddressUtil;
-import org.apache.accumulo.core.util.GsonSingleton;
 
 import com.google.common.net.HostAndPort;
 
@@ -117,7 +117,7 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
 
     @Override
     public String toString() {
-      return GsonSingleton.getInstance().toJson(this);
+      return GSON.get().toJson(this);
     }
 
   }
@@ -193,7 +193,7 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
   public byte[] serialize() {
     ServiceDescriptors sd = new ServiceDescriptors();
     services.values().forEach(s -> sd.addService(s));
-    return GsonSingleton.getInstance().toJson(sd).getBytes(UTF_8);
+    return GSON.get().toJson(sd).getBytes(UTF_8);
   }
 
   @Override
@@ -227,8 +227,7 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
     if (data.isBlank()) {
       return Optional.empty();
     }
-    return Optional.of(
-        new ServiceLockData(GsonSingleton.getInstance().fromJson(data, 
ServiceDescriptors.class)));
+    return Optional.of(new ServiceLockData(GSON.get().fromJson(data, 
ServiceDescriptors.class)));
   }
 
 }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
index 1ebf5c400c..421a707d75 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionFinalState.java
@@ -18,11 +18,12 @@
  */
 package org.apache.accumulo.core.metadata.schema;
 
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
 import java.util.Base64;
 
 import org.apache.accumulo.core.data.TableId;
 import org.apache.accumulo.core.dataImpl.KeyExtent;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.core.util.TextUtil;
 import org.apache.hadoop.io.Text;
 
@@ -121,11 +122,11 @@ public class ExternalCompactionFinalState {
     jd.fileSize = fileSize;
     jd.entries = fileEntries;
     jd.extent = new Extent(extent);
-    return GsonSingleton.getInstance().toJson(jd);
+    return GSON.get().toJson(jd);
   }
 
   public static ExternalCompactionFinalState fromJson(ExternalCompactionId 
ecid, String json) {
-    JsonData jd = GsonSingleton.getInstance().fromJson(json, JsonData.class);
+    JsonData jd = GSON.get().fromJson(json, JsonData.class);
     return new ExternalCompactionFinalState(ecid, jd.extent.toKeyExtent(),
         FinalState.valueOf(jd.state), jd.fileSize, jd.entries);
   }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
index de617e5e03..5eef8c3d5d 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/ExternalCompactionMetadata.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.metadata.schema;
 
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toSet;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.util.List;
 import java.util.Objects;
@@ -29,7 +30,6 @@ import org.apache.accumulo.core.metadata.ReferencedTabletFile;
 import org.apache.accumulo.core.metadata.StoredTabletFile;
 import org.apache.accumulo.core.spi.compaction.CompactionExecutorId;
 import org.apache.accumulo.core.spi.compaction.CompactionKind;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.core.util.compaction.CompactionExecutorIdImpl;
 import org.apache.hadoop.fs.Path;
 
@@ -137,11 +137,11 @@ public class ExternalCompactionMetadata {
     jData.propDels = propagateDeletes;
     jData.selectedAll = initiallySelectedAll;
     jData.compactionId = compactionId;
-    return GsonSingleton.getInstance().toJson(jData);
+    return GSON.get().toJson(jData);
   }
 
   public static ExternalCompactionMetadata fromJson(String json) {
-    GSonData jData = GsonSingleton.getInstance().fromJson(json, 
GSonData.class);
+    GSonData jData = GSON.get().fromJson(json, GSonData.class);
 
     return new ExternalCompactionMetadata(
         jData.inputs.stream().map(StoredTabletFile::new).collect(toSet()),
diff --git 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
index e0601f94a7..7ea03a19a4 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/metadata/schema/RootTabletMetadata.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.core.metadata.schema;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.nio.ByteBuffer;
 import java.nio.charset.CharacterCodingException;
@@ -37,7 +38,6 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.metadata.RootTable;
 import 
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.CurrentLocationColumnFamily;
 import 
org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.hadoop.io.Text;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,7 +96,7 @@ public class RootTabletMetadata {
 
   public RootTabletMetadata(String json) {
     log.trace("Creating root tablet metadata from stored JSON: {}", json);
-    this.data = GsonSingleton.getInstance().fromJson(json, Data.class);
+    this.data = GSON.get().fromJson(json, Data.class);
     checkArgument(data.version == VERSION, "Invalid Root Table Metadata JSON 
version %s",
         data.version);
     data.columnValues.forEach((fam, qualVals) -> {
@@ -162,7 +162,7 @@ public class RootTabletMetadata {
    * @return a JSON representation of the root tablet's data.
    */
   public String toJson() {
-    return GsonSingleton.getInstance().toJson(data);
+    return GSON.get().toJson(data);
   }
 
 }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
 
b/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
index f8a0cbd90d..1b5b662957 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/spi/compaction/DefaultCompactionPlanner.java
@@ -18,6 +18,8 @@
  */
 package org.apache.accumulo.core.spi.compaction;
 
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
@@ -31,7 +33,6 @@ import java.util.Set;
 
 import org.apache.accumulo.core.client.admin.compaction.CompactableFile;
 import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.core.util.compaction.CompactionJobPrioritizer;
 
 import com.google.common.base.Preconditions;
@@ -145,8 +146,8 @@ public class DefaultCompactionPlanner implements 
CompactionPlanner {
       justification = "Field is written by Gson")
   @Override
   public void init(InitParameters params) {
-    ExecutorConfig[] execConfigs = GsonSingleton.getInstance()
-        .fromJson(params.getOptions().get("executors"), 
ExecutorConfig[].class);
+    ExecutorConfig[] execConfigs =
+        GSON.get().fromJson(params.getOptions().get("executors"), 
ExecutorConfig[].class);
 
     List<Executor> tmpExec = new ArrayList<>();
 
diff --git 
a/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
 
b/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
index cb2848cef2..a90936832c 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/spi/scan/ConfigurableScanServerSelector.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.core.spi.scan;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.lang.reflect.Type;
 import java.security.SecureRandom;
@@ -35,7 +36,6 @@ import java.util.function.Supplier;
 
 import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
 import org.apache.accumulo.core.data.TabletId;
-import org.apache.accumulo.core.util.GsonSingleton;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Suppliers;
@@ -263,8 +263,8 @@ public class ConfigurableScanServerSelector implements 
ScanServerSelector {
 
   private void parseProfiles(Map<String,String> options) {
     Type listType = new TypeToken<ArrayList<Profile>>() {}.getType();
-    List<Profile> profList = GsonSingleton.getInstance()
-        .fromJson(options.getOrDefault("profiles", PROFILES_DEFAULT), 
listType);
+    List<Profile> profList =
+        GSON.get().fromJson(options.getOrDefault("profiles", 
PROFILES_DEFAULT), listType);
 
     profiles = new HashMap<>();
     defaultProfile = null;
diff --git 
a/core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java 
b/core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
similarity index 56%
rename from core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
rename to core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
index 44c7369305..ac476cc687 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/LazySingletons.java
@@ -18,27 +18,23 @@
  */
 package org.apache.accumulo.core.util;
 
+import java.util.function.Supplier;
+
+import com.google.common.base.Suppliers;
 import com.google.gson.Gson;
 
 /**
- * This class provides access to a shared instance of Gson that uses its 
default configuration. Gson
- * is thread-safe, so it should be safe to create and reuse a single instance.
- * <p>
- * If you need to use a Gson instance that is configured differently, if you 
want to configure
- * TypeAdapters for example, then you should not use this. You should 
construct your own instance of
- * Gson.
+ * This class provides easy access to global, immutable, lazily-instantiated, 
and thread-safe
+ * singleton resources. These should be used with static imports.
  */
-public class GsonSingleton {
-  private static Gson gsonInstance = null;
+public class LazySingletons {
+
+  // prevent instantiating this utility class
+  private LazySingletons() {}
 
-  private GsonSingleton() {
-    // private to prevent direct instantiation
-  }
+  /**
+   * A Gson instance constructed with defaults. Construct your own if you need 
custom settings.
+   */
+  public static final Supplier<Gson> GSON = Suppliers.memoize(Gson::new);
 
-  public static Gson getInstance() {
-    if (gsonInstance == null) {
-      gsonInstance = new Gson();
-    }
-    return gsonInstance;
-  }
 }
diff --git a/pom.xml b/pom.xml
index ad11c9e535..6d2275bef7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1144,6 +1144,10 @@
                   <property name="format" value="junit[.]framework[.]TestCase" 
/>
                   <property name="message" value="Use JUnit4+ @Test annotation 
instead of TestCase" />
                 </module>
+                <module name="RegexpSinglelineJava">
+                  <property name="format" value="import 
org[.]apache[.]accumulo[.]core[.]util[.]LazySingletons;" />
+                  <property name="message" value="Use static imports for 
LazySingletons for consistency" />
+                </module>
                 <module name="RegexpSinglelineJava">
                   <property name="format" value="import org[.]junit[.]Assert;" 
/>
                   <property name="message" value="Use static imports for 
Assert.* methods for consistency" />
diff --git 
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
 
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
index 3627024b68..e65813fd4c 100644
--- 
a/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
+++ 
b/server/base/src/main/java/org/apache/accumulo/server/metadata/RootGcCandidates.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.server.metadata;
 
 import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.util.SortedMap;
 import java.util.SortedSet;
@@ -27,7 +28,6 @@ import java.util.TreeSet;
 import java.util.stream.Stream;
 
 import org.apache.accumulo.core.metadata.StoredTabletFile;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.hadoop.fs.Path;
 
 public class RootGcCandidates {
@@ -61,7 +61,7 @@ public class RootGcCandidates {
   }
 
   public RootGcCandidates(String jsonString) {
-    this.data = GsonSingleton.getInstance().fromJson(jsonString, Data.class);
+    this.data = GSON.get().fromJson(jsonString, Data.class);
     checkArgument(data.version == VERSION, "Invalid Root Table GC Candidates 
JSON version %s",
         data.version);
     data.candidates.forEach((parent, files) -> {
@@ -93,7 +93,7 @@ public class RootGcCandidates {
   }
 
   public String toJson() {
-    return GsonSingleton.getInstance().toJson(data);
+    return GSON.get().toJson(data);
   }
 
 }
diff --git 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
index 5c9045a072..752bc90d44 100644
--- 
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
+++ 
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/TraceRepo.java
@@ -18,10 +18,11 @@
  */
 package org.apache.accumulo.manager.tableOps;
 
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
+
 import org.apache.accumulo.core.clientImpl.thrift.TInfo;
 import org.apache.accumulo.core.fate.Repo;
 import org.apache.accumulo.core.trace.TraceUtil;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.manager.Manager;
 
 import io.opentelemetry.api.trace.Span;
@@ -105,6 +106,6 @@ public class TraceRepo<T> implements Repo<T> {
 
     // Inorder for Gson to work with generic types, the following passes 
repo.getClass() to Gson.
     // See the Gson javadoc for more info.
-    return repo.getClass() + " " + GsonSingleton.getInstance().toJson(repo, 
repo.getClass());
+    return repo.getClass() + " " + GSON.get().toJson(repo, repo.getClass());
   }
 }
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
index ed14bb4f7d..dce3917910 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/util/logging/AccumuloMonitorAppender.java
@@ -19,6 +19,7 @@
 package org.apache.accumulo.monitor.util.logging;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -33,7 +34,6 @@ import java.util.function.Supplier;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.conf.SiteConfiguration;
 import org.apache.accumulo.core.fate.zookeeper.ZooCache.ZcStat;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.core.util.Pair;
 import org.apache.accumulo.monitor.rest.logs.LogResource;
 import org.apache.accumulo.monitor.rest.logs.SingleLogEvent;
@@ -116,7 +116,7 @@ public class AccumuloMonitorAppender extends 
AbstractAppender {
         pojo.message = event.getMessage().getFormattedMessage();
         pojo.stacktrace = throwableToStacktrace(event.getThrown());
 
-        String jsonEvent = GsonSingleton.getInstance().toJson(pojo);
+        String jsonEvent = GSON.get().toJson(pojo);
 
         var req = 
HttpRequest.newBuilder(uri).POST(BodyPublishers.ofString(jsonEvent, UTF_8))
             .setHeader("Content-Type", "application/json").build();
diff --git 
a/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java 
b/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
index 10f01dfc14..ba9bf2edbd 100644
--- a/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
@@ -20,6 +20,7 @@ package org.apache.accumulo.test;
 
 import static java.util.concurrent.TimeUnit.MINUTES;
 import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.accumulo.core.util.LazySingletons.GSON;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.net.URL;
@@ -46,7 +47,6 @@ import org.apache.accumulo.core.file.rfile.RFile;
 import org.apache.accumulo.core.manager.thrift.ManagerMonitorInfo;
 import org.apache.accumulo.core.metadata.UnreferencedTabletFile;
 import org.apache.accumulo.core.spi.crypto.NoCryptoServiceFactory;
-import org.apache.accumulo.core.util.GsonSingleton;
 import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.test.functional.ConfigurableMacBase;
@@ -78,7 +78,7 @@ public class CountNameNodeOpsBulkIT extends 
ConfigurableMacBase {
     URL url = new URL(uri + "/jmx");
     log.debug("Fetching web page " + url);
     String jsonString = FunctionalTestUtils.readWebPage(url).body();
-    Map<?,?> jsonObject = GsonSingleton.getInstance().fromJson(jsonString, 
Map.class);
+    Map<?,?> jsonObject = GSON.get().fromJson(jsonString, Map.class);
     List<?> beans = (List<?>) jsonObject.get("beans");
     for (Object bean : beans) {
       Map<?,?> map = (Map<?,?>) bean;

Reply via email to