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

domgarguilo 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 06c55fbea4 Create Gson singleton to use in place of new instances 
(#3516)
06c55fbea4 is described below

commit 06c55fbea47f7ac376c7c93b48b76529e0d4a474
Author: Dom G <domgargu...@apache.org>
AuthorDate: Thu Jun 22 15:26:36 2023 -0400

    Create Gson singleton to use in place of new instances (#3516)
    
    * Create Gson singleton to use in place of new instances
    ---------
    
    Co-authored-by: Dave Marion <dlmar...@apache.org>
---
 .../core/clientImpl/bulk/BulkSerialize.java        |  3 +-
 .../apache/accumulo/core/lock/ServiceLockData.java | 11 +++---
 .../schema/ExternalCompactionFinalState.java       |  8 ++--
 .../schema/ExternalCompactionMetadata.java         |  9 ++---
 .../core/metadata/schema/RootTabletMetadata.java   |  8 ++--
 .../spi/compaction/DefaultCompactionPlanner.java   |  6 +--
 .../spi/scan/ConfigurableScanServerSelector.java   |  7 ++--
 .../apache/accumulo/core/util/GsonSingleton.java   | 44 ++++++++++++++++++++++
 .../accumulo/server/metadata/RootGcCandidates.java |  8 ++--
 .../accumulo/manager/tableOps/TraceRepo.java       |  5 +--
 .../util/logging/AccumuloMonitorAppender.java      |  6 +--
 .../accumulo/test/CountNameNodeOpsBulkIT.java      |  5 +--
 12 files changed, 75 insertions(+), 45 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 5c2771c3b5..bff210ee80 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
@@ -37,6 +37,7 @@ 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;
 
@@ -97,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))) {
-      new Gson().toJson(oldToNewNameMap, writer);
+      GsonSingleton.getInstance().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 746d5b5ce5..ed624be642 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
@@ -29,14 +29,12 @@ 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;
-import com.google.gson.Gson;
 
 public class ServiceLockData implements Comparable<ServiceLockData> {
 
-  private static final Gson gson = new Gson();
-
   /**
    * Thrift Service list
    */
@@ -119,7 +117,7 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
 
     @Override
     public String toString() {
-      return gson.toJson(this);
+      return GsonSingleton.getInstance().toJson(this);
     }
 
   }
@@ -195,7 +193,7 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
   public byte[] serialize() {
     ServiceDescriptors sd = new ServiceDescriptors();
     services.values().forEach(s -> sd.addService(s));
-    return gson.toJson(sd).getBytes(UTF_8);
+    return GsonSingleton.getInstance().toJson(sd).getBytes(UTF_8);
   }
 
   @Override
@@ -229,7 +227,8 @@ public class ServiceLockData implements 
Comparable<ServiceLockData> {
     if (data.isBlank()) {
       return Optional.empty();
     }
-    return Optional.of(new ServiceLockData(gson.fromJson(data, 
ServiceDescriptors.class)));
+    return Optional.of(
+        new ServiceLockData(GsonSingleton.getInstance().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 9212ccde9f..1ebf5c400c 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
@@ -22,16 +22,14 @@ 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;
 
 import com.google.common.base.Preconditions;
-import com.google.gson.Gson;
 
 public class ExternalCompactionFinalState {
 
-  private static final Gson GSON = new Gson();
-
   public enum FinalState {
     FINISHED, FAILED
   }
@@ -123,11 +121,11 @@ public class ExternalCompactionFinalState {
     jd.fileSize = fileSize;
     jd.entries = fileEntries;
     jd.extent = new Extent(extent);
-    return GSON.toJson(jd);
+    return GsonSingleton.getInstance().toJson(jd);
   }
 
   public static ExternalCompactionFinalState fromJson(ExternalCompactionId 
ecid, String json) {
-    JsonData jd = GSON.fromJson(json, JsonData.class);
+    JsonData jd = GsonSingleton.getInstance().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 2373160cfc..de617e5e03 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
@@ -29,15 +29,12 @@ 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;
 
-import com.google.gson.Gson;
-
 public class ExternalCompactionMetadata {
 
-  private static final Gson GSON = new Gson();
-
   private final Set<StoredTabletFile> jobFiles;
   private final Set<StoredTabletFile> nextFiles;
   private final ReferencedTabletFile compactTmpName;
@@ -140,11 +137,11 @@ public class ExternalCompactionMetadata {
     jData.propDels = propagateDeletes;
     jData.selectedAll = initiallySelectedAll;
     jData.compactionId = compactionId;
-    return GSON.toJson(jData);
+    return GsonSingleton.getInstance().toJson(jData);
   }
 
   public static ExternalCompactionMetadata fromJson(String json) {
-    GSonData jData = GSON.fromJson(json, GSonData.class);
+    GSonData jData = GsonSingleton.getInstance().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 3f01eed6c4..e0601f94a7 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
@@ -37,12 +37,11 @@ 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;
 
-import com.google.gson.Gson;
-
 /**
  * This class is used to serialize and deserialize root tablet metadata using 
GSon. The only data
  * stored about the Root Table is the COLUMN_FAMILY, COLUMN_QUALIFIER and 
VALUE.
@@ -93,12 +92,11 @@ public class RootTabletMetadata {
     }
   }
 
-  private final Gson gson = new Gson();
   private final Data data;
 
   public RootTabletMetadata(String json) {
     log.trace("Creating root tablet metadata from stored JSON: {}", json);
-    this.data = gson.fromJson(json, Data.class);
+    this.data = GsonSingleton.getInstance().fromJson(json, Data.class);
     checkArgument(data.version == VERSION, "Invalid Root Table Metadata JSON 
version %s",
         data.version);
     data.columnValues.forEach((fam, qualVals) -> {
@@ -164,7 +162,7 @@ public class RootTabletMetadata {
    * @return a JSON representation of the root tablet's data.
    */
   public String toJson() {
-    return gson.toJson(data);
+    return GsonSingleton.getInstance().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 11feb5c60e..f8a0cbd90d 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
@@ -31,10 +31,10 @@ 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;
-import com.google.gson.Gson;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
@@ -145,8 +145,8 @@ public class DefaultCompactionPlanner implements 
CompactionPlanner {
       justification = "Field is written by Gson")
   @Override
   public void init(InitParameters params) {
-    ExecutorConfig[] execConfigs =
-        new Gson().fromJson(params.getOptions().get("executors"), 
ExecutorConfig[].class);
+    ExecutorConfig[] execConfigs = GsonSingleton.getInstance()
+        .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 2e792180cc..cb2848cef2 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
@@ -35,13 +35,13 @@ 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;
 import com.google.common.collect.Sets;
 import com.google.common.hash.HashCode;
 import com.google.common.hash.Hashing;
-import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -263,9 +263,8 @@ public class ConfigurableScanServerSelector implements 
ScanServerSelector {
 
   private void parseProfiles(Map<String,String> options) {
     Type listType = new TypeToken<ArrayList<Profile>>() {}.getType();
-    Gson gson = new Gson();
-    List<Profile> profList =
-        gson.fromJson(options.getOrDefault("profiles", PROFILES_DEFAULT), 
listType);
+    List<Profile> profList = GsonSingleton.getInstance()
+        .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/GsonSingleton.java
new file mode 100644
index 0000000000..44c7369305
--- /dev/null
+++ b/core/src/main/java/org/apache/accumulo/core/util/GsonSingleton.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.accumulo.core.util;
+
+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.
+ */
+public class GsonSingleton {
+  private static Gson gsonInstance = null;
+
+  private GsonSingleton() {
+    // private to prevent direct instantiation
+  }
+
+  public static Gson getInstance() {
+    if (gsonInstance == null) {
+      gsonInstance = new Gson();
+    }
+    return gsonInstance;
+  }
+}
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 95874fc2be..3627024b68 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
@@ -27,15 +27,13 @@ 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;
 
-import com.google.gson.Gson;
-
 public class RootGcCandidates {
   // Version 1. Released with Accumulo version 2.1.0
   private static final int VERSION = 1;
 
-  private final Gson gson = new Gson();
   private final Data data;
 
   // This class is used to serialize and deserialize root tablet metadata 
using GSon. Any changes to
@@ -63,7 +61,7 @@ public class RootGcCandidates {
   }
 
   public RootGcCandidates(String jsonString) {
-    this.data = gson.fromJson(jsonString, Data.class);
+    this.data = GsonSingleton.getInstance().fromJson(jsonString, Data.class);
     checkArgument(data.version == VERSION, "Invalid Root Table GC Candidates 
JSON version %s",
         data.version);
     data.candidates.forEach((parent, files) -> {
@@ -95,7 +93,7 @@ public class RootGcCandidates {
   }
 
   public String toJson() {
-    return gson.toJson(data);
+    return GsonSingleton.getInstance().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 a97f9d27ff..5c9045a072 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
@@ -21,10 +21,9 @@ package org.apache.accumulo.manager.tableOps;
 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 com.google.gson.Gson;
-
 import io.opentelemetry.api.trace.Span;
 import io.opentelemetry.context.Scope;
 
@@ -106,6 +105,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() + " " + new Gson().toJson(repo, repo.getClass());
+    return repo.getClass() + " " + GsonSingleton.getInstance().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 7dfde0f3fa..ed14bb4f7d 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
@@ -33,6 +33,7 @@ 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;
@@ -46,8 +47,6 @@ import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.config.plugins.Plugin;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
 
-import com.google.gson.Gson;
-
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
@@ -75,7 +74,6 @@ public class AccumuloMonitorAppender extends AbstractAppender 
{
 
   }
 
-  private final Gson gson = new Gson();
   private final HttpClient httpClient = HttpClient.newHttpClient();
   private final Supplier<Optional<URI>> monitorLocator;
 
@@ -118,7 +116,7 @@ public class AccumuloMonitorAppender extends 
AbstractAppender {
         pojo.message = event.getMessage().getFormattedMessage();
         pojo.stacktrace = throwableToStacktrace(event.getThrown());
 
-        String jsonEvent = gson.toJson(pojo);
+        String jsonEvent = GsonSingleton.getInstance().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 4efdc52d22..10f01dfc14 100644
--- a/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/CountNameNodeOpsBulkIT.java
@@ -46,6 +46,7 @@ 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;
@@ -56,8 +57,6 @@ import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.Text;
 import org.junit.jupiter.api.Test;
 
-import com.google.gson.Gson;
-
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 
 /**
@@ -79,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 = new Gson().fromJson(jsonString, Map.class);
+    Map<?,?> jsonObject = GsonSingleton.getInstance().fromJson(jsonString, 
Map.class);
     List<?> beans = (List<?>) jsonObject.get("beans");
     for (Object bean : beans) {
       Map<?,?> map = (Map<?,?>) bean;

Reply via email to