From 8f31ec2562d926e13ef06a9dafc6a5d7b4584796 Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:32:24 -0700 Subject: [PATCH 1/9] HDDS-15808. Replace json-simple with Jackson in httpfsgateway The httpfsgateway module was the only remaining consumer of the unmaintained com.googlecode.json-simple:json-simple library. Jackson (jackson-databind) is already a compile dependency, so this migrates all JSON serialization to Jackson and drops json-simple from the build. Co-Authored-By: Claude Opus 4.8 --- .../dist/src/main/license/bin/LICENSE.txt | 1 - .../dist/src/main/license/jar-report.txt | 1 - hadoop-ozone/httpfsgateway/pom.xml | 10 -- .../ozone/fs/http/server/FSOperations.java | 93 +++++++++---------- .../ozone/fs/http/server/HttpFSServer.java | 13 ++- .../InstrumentationService.java | 60 +++--------- .../ozone/lib/wsrs/JSONMapProvider.java | 9 +- .../apache/ozone/lib/wsrs/JSONProvider.java | 79 ---------------- .../TestInstrumentationSerialization.java | 78 ++++++++++++++++ .../ozone/lib/wsrs/TestJSONMapProvider.java | 71 ++++++++++++++ 10 files changed, 217 insertions(+), 198 deletions(-) delete mode 100644 hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONProvider.java create mode 100644 hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/service/instrumentation/TestInstrumentationSerialization.java create mode 100644 hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/wsrs/TestJSONMapProvider.java diff --git a/hadoop-ozone/dist/src/main/license/bin/LICENSE.txt b/hadoop-ozone/dist/src/main/license/bin/LICENSE.txt index 0c509fa59641..8456581dfc25 100644 --- a/hadoop-ozone/dist/src/main/license/bin/LICENSE.txt +++ b/hadoop-ozone/dist/src/main/license/bin/LICENSE.txt @@ -298,7 +298,6 @@ Apache License 2.0 com.google.inject.extensions:guice-servlet com.google.inject:guice com.google.j2objc:j2objc-annotations - com.googlecode.json-simple:json-simple com.jolbox:bonecp com.lmax:disruptor com.nimbusds:nimbus-jose-jwt diff --git a/hadoop-ozone/dist/src/main/license/jar-report.txt b/hadoop-ozone/dist/src/main/license/jar-report.txt index 274f53857215..1ab2063cf5c4 100644 --- a/hadoop-ozone/dist/src/main/license/jar-report.txt +++ b/hadoop-ozone/dist/src/main/license/jar-report.txt @@ -165,7 +165,6 @@ share/ozone/lib/jooq-codegen.jar share/ozone/lib/jooq-meta.jar share/ozone/lib/jooq.jar share/ozone/lib/jsch.jar -share/ozone/lib/json-simple.jar share/ozone/lib/jsp-api.jar share/ozone/lib/jspecify.jar share/ozone/lib/jsr311-api.jar diff --git a/hadoop-ozone/httpfsgateway/pom.xml b/hadoop-ozone/httpfsgateway/pom.xml index 4da62ff003f5..ea0a5798ffce 100644 --- a/hadoop-ozone/httpfsgateway/pom.xml +++ b/hadoop-ozone/httpfsgateway/pom.xml @@ -46,16 +46,6 @@ com.fasterxml.jackson.core jackson-databind - - com.googlecode.json-simple - json-simple - - - junit - junit - - - jakarta.ws.rs jakarta.ws.rs-api diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index 55d90ef99011..28db872aacad 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.LinkedHashMap; @@ -60,8 +61,6 @@ import org.apache.ozone.fs.http.HttpFSConstants; import org.apache.ozone.fs.http.HttpFSConstants.FILETYPE; import org.apache.ozone.lib.service.FileSystemAccess; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; /** * FileSystem operation executors used by {@link HttpFSServer}. @@ -107,7 +106,7 @@ private static Map toJson(FileStatus[] fileStatuses, boolean isFile) { Map json = new LinkedHashMap<>(); Map inner = new LinkedHashMap<>(); - JSONArray statuses = new JSONArray(); + List statuses = new ArrayList<>(); for (FileStatus f : fileStatuses) { statuses.add(toJsonInner(f, isFile)); } @@ -209,7 +208,7 @@ private static Map toJson(FileSystem.DirectoryEntries private static Map aclStatusToJSON(AclStatus aclStatus) { Map json = new LinkedHashMap(); Map inner = new LinkedHashMap(); - JSONArray entriesArray = new JSONArray(); + List entriesArray = new ArrayList<>(); inner.put(HttpFSConstants.OWNER_JSON, aclStatus.getOwner()); inner.put(HttpFSConstants.GROUP_JSON, aclStatus.getGroup()); inner.put(HttpFSConstants.PERMISSION_JSON, @@ -258,7 +257,7 @@ private static Map fileChecksumToJSON(FileChecksum checksum) { private static Map xAttrsToJSON(Map xAttrs, XAttrCodec encoding) throws IOException { Map jsonMap = new LinkedHashMap(); - JSONArray jsonArray = new JSONArray(); + List jsonArray = new ArrayList<>(); if (xAttrs != null) { for (Entry e : xAttrs.entrySet()) { Map json = new LinkedHashMap(); @@ -286,7 +285,7 @@ private static Map xAttrsToJSON(Map xAttrs, private static Map xAttrNamesToJSON(List names) throws IOException { Map jsonMap = new LinkedHashMap(); jsonMap.put(HttpFSConstants.XATTRNAMES_JSON, - JSONArray.toJSONString(names)); + JsonUtil.toJsonString(names)); return jsonMap; } @@ -374,17 +373,16 @@ private static Map quotaUsageToMap(QuotaUsage quotaUsage) { * * @return the JSON representation of the key-value pair. */ - @SuppressWarnings("unchecked") - private static JSONObject toJSON(String name, Object value) { - JSONObject json = new JSONObject(); + private static Map toJSON(String name, Object value) { + Map json = new LinkedHashMap<>(); json.put(name, value); return json; } - @SuppressWarnings({ "unchecked" }) - private static JSONObject storagePolicyToJSON(BlockStoragePolicySpi policy) { + private static Map storagePolicyToJSON( + BlockStoragePolicySpi policy) { BlockStoragePolicy p = (BlockStoragePolicy) policy; - JSONObject policyJson = new JSONObject(); + Map policyJson = new LinkedHashMap<>(); policyJson.put("id", p.getId()); policyJson.put("name", p.getName()); policyJson.put("storageTypes", toJsonArray(p.getStorageTypes())); @@ -395,24 +393,22 @@ private static JSONObject storagePolicyToJSON(BlockStoragePolicySpi policy) { return policyJson; } - @SuppressWarnings("unchecked") - private static JSONArray toJsonArray(StorageType[] storageTypes) { - JSONArray jsonArray = new JSONArray(); + private static List toJsonArray(StorageType[] storageTypes) { + List jsonArray = new ArrayList<>(); for (StorageType type : storageTypes) { jsonArray.add(type.toString()); } return jsonArray; } - @SuppressWarnings("unchecked") - private static JSONObject storagePoliciesToJSON( + private static Map storagePoliciesToJSON( Collection storagePolicies) { - JSONObject json = new JSONObject(); - JSONArray jsonArray = new JSONArray(); - JSONObject policies = new JSONObject(); + Map json = new LinkedHashMap<>(); + List jsonArray = new ArrayList<>(); + Map policies = new LinkedHashMap<>(); if (storagePolicies != null) { for (BlockStoragePolicySpi policy : storagePolicies) { - JSONObject policyMap = storagePolicyToJSON(policy); + Map policyMap = storagePolicyToJSON(policy); jsonArray.add(policyMap); } } @@ -507,8 +503,8 @@ public Void execute(FileSystem fs) throws IOException { * Executor that performs a truncate FileSystemAccess files system operation. */ @InterfaceAudience.Private - public static class FSTruncate implements - FileSystemAccess.FileSystemExecutor { + public static class FSTruncate implements + FileSystemAccess.FileSystemExecutor { private Path path; private long newLength; @@ -537,7 +533,7 @@ public FSTruncate(String path, long newLength) { * @throws IOException thrown if an IO error occurred. */ @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { boolean result = fs.truncate(path, newLength); HttpFSServerWebApp.get().getMetrics().incrOpsTruncate(); return toJSON( @@ -730,7 +726,7 @@ public static long copyBytes(InputStream in, OutputStream out, long count) */ @InterfaceAudience.Private public static class FSDelete - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { private Path path; private boolean recursive; @@ -756,7 +752,7 @@ public FSDelete(String path, boolean recursive) { * @throws IOException thrown if an IO error occurred. */ @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { boolean deleted = fs.delete(path, recursive); HttpFSServerWebApp.get().getMetrics().incrOpsDelete(); return toJSON( @@ -842,7 +838,7 @@ public Map execute(FileSystem fs) throws IOException { */ @InterfaceAudience.Private public static class FSHomeDir - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { /** * Executes the filesystem operation. @@ -854,10 +850,9 @@ public static class FSHomeDir * @throws IOException thrown if an IO error occurred. */ @Override - @SuppressWarnings("unchecked") - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { Path homeDir = fs.getHomeDirectory(); - JSONObject json = new JSONObject(); + Map json = new LinkedHashMap<>(); json.put(HttpFSConstants.HOME_DIR_JSON, homeDir.toUri().getPath()); return json; } @@ -955,7 +950,7 @@ public Map execute(FileSystem fs) throws IOException { */ @InterfaceAudience.Private public static class FSMkdirs - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { private Path path; private short permission; @@ -986,7 +981,7 @@ public FSMkdirs(String path, short permission, * @throws IOException thrown if an IO error occurred. */ @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { FsPermission fsPermission = new FsPermission(permission); if (unmaskedPermission != -1) { fsPermission = FsCreateModes.create(fsPermission, @@ -1039,7 +1034,7 @@ public InputStream execute(FileSystem fs) throws IOException { */ @InterfaceAudience.Private public static class FSRename - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { private Path path; private Path toPath; @@ -1065,7 +1060,7 @@ public FSRename(String path, String toPath) { * @throws IOException thrown if an IO error occurred. */ @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { boolean renamed = fs.rename(path, toPath); HttpFSServerWebApp.get().getMetrics().incrOpsRename(); return toJSON(HttpFSConstants.RENAME_JSON, renamed); @@ -1343,7 +1338,7 @@ public Void execute(FileSystem fs) throws IOException { */ @InterfaceAudience.Private public static class FSTrashRoot - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { private Path path; public FSTrashRoot(String path) { @@ -1351,10 +1346,9 @@ public FSTrashRoot(String path) { } @Override - @SuppressWarnings("unchecked") - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { Path trashRoot = fs.getTrashRoot(this.path); - JSONObject json = new JSONObject(); + Map json = new LinkedHashMap<>(); json.put(HttpFSConstants.TRASH_DIR_JSON, trashRoot.toUri().getPath()); return json; } @@ -1401,7 +1395,7 @@ public Map execute(FileSystem fs) throws IOException { */ @InterfaceAudience.Private public static class FSSetReplication - implements FileSystemAccess.FileSystemExecutor { + implements FileSystemAccess.FileSystemExecutor { private Path path; private short replication; @@ -1427,10 +1421,9 @@ public FSSetReplication(String path, short replication) { * @throws IOException thrown if an IO error occurred. */ @Override - @SuppressWarnings("unchecked") - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { boolean ret = fs.setReplication(path, replication); - JSONObject json = new JSONObject(); + Map json = new LinkedHashMap<>(); json.put(HttpFSConstants.SET_REPLICATION_JSON, ret); return json; } @@ -1610,13 +1603,12 @@ public Map execute(FileSystem fs) throws IOException { * Executor that performs a getAllStoragePolicies FileSystemAccess files * system operation. */ - @SuppressWarnings({ "unchecked" }) @InterfaceAudience.Private public static class FSGetAllStoragePolicies implements - FileSystemAccess.FileSystemExecutor { + FileSystemAccess.FileSystemExecutor { @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { Collection storagePolicies = fs .getAllStoragePolicies(); return storagePoliciesToJSON(storagePolicies); @@ -1627,10 +1619,9 @@ public JSONObject execute(FileSystem fs) throws IOException { * Executor that performs a getStoragePolicy FileSystemAccess files system * operation. */ - @SuppressWarnings({ "unchecked" }) @InterfaceAudience.Private public static class FSGetStoragePolicy implements - FileSystemAccess.FileSystemExecutor { + FileSystemAccess.FileSystemExecutor { private Path path; @@ -1639,9 +1630,9 @@ public FSGetStoragePolicy(String path) { } @Override - public JSONObject execute(FileSystem fs) throws IOException { + public Map execute(FileSystem fs) throws IOException { BlockStoragePolicySpi storagePolicy = fs.getStoragePolicy(path); - JSONObject json = new JSONObject(); + Map json = new LinkedHashMap<>(); json.put(HttpFSConstants.STORAGE_POLICY_JSON, storagePolicyToJSON(storagePolicy)); return json; @@ -1793,9 +1784,9 @@ public FSCreateSnapshot(String path, String snapshotName) { @Override public String execute(FileSystem fs) throws IOException { Path snapshotPath = fs.createSnapshot(path, snapshotName); - JSONObject json = toJSON(HttpFSConstants.HOME_DIR_JSON, + Map json = toJSON(HttpFSConstants.HOME_DIR_JSON, snapshotPath.toString()); - return json.toJSONString().replaceAll("\\\\", ""); + return JsonUtil.toJsonString(json).replaceAll("\\\\", ""); } } diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/HttpFSServer.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/HttpFSServer.java index 262b9fa69455..c6ac62a7f3f2 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/HttpFSServer.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/HttpFSServer.java @@ -83,7 +83,6 @@ import org.apache.ozone.lib.servlet.FileSystemReleaseFilter; import org.apache.ozone.lib.wsrs.InputStreamEntity; import org.apache.ozone.lib.wsrs.Parameters; -import org.json.simple.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -402,7 +401,7 @@ private Response handleGetStoragePolicy(String path, Response response; FSOperations.FSGetStoragePolicy command = new FSOperations.FSGetStoragePolicy(path); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); AUDIT_LOG.info("[{}]", path); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); return response; @@ -414,7 +413,7 @@ private Response handleGetAllStoragePolicy(String path, Response response; FSOperations.FSGetAllStoragePolicies command = new FSOperations.FSGetAllStoragePolicies(); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); AUDIT_LOG.info("[{}]", path); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); return response; @@ -649,7 +648,7 @@ private Response handleDelete(String path, AUDIT_LOG.info("[{}] recursive [{}]", path, recursive); FSOperations.FSDelete command = new FSOperations.FSDelete(path, recursive); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); return response; } @@ -769,7 +768,7 @@ private Response handleTruncate(String path, Long newLength = params.get(NewLengthParam.NAME, NewLengthParam.class); FSOperations.FSTruncate command = new FSOperations.FSTruncate(path, newLength); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); AUDIT_LOG.info("Truncate [{}] to length [{}]", path, newLength); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); return response; @@ -1078,7 +1077,7 @@ private Response handleRename(String path, String toPath = params.get(DestinationParam.NAME, DestinationParam.class); FSOperations.FSRename command = new FSOperations.FSRename(path, toPath); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); AUDIT_LOG.info("[{}] to [{}]", path, toPath); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); return response; @@ -1095,7 +1094,7 @@ private Response handleMkdirs(String path, UnmaskedPermissionParam.class); FSOperations.FSMkdirs command = new FSOperations.FSMkdirs(path, permission, unmaskedPermission); - JSONObject json = fsExecute(user, command); + Map json = fsExecute(user, command); AUDIT_LOG.info("[{}] permission [{}] unmaskedpermission [{}]", path, permission, unmaskedPermission); response = Response.ok(json).type(MediaType.APPLICATION_JSON).build(); diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java index 28b87518f348..5cb1a8e23c8a 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java @@ -17,8 +17,7 @@ package org.apache.ozone.lib.service.instrumentation; -import java.io.IOException; -import java.io.Writer; +import com.fasterxml.jackson.annotation.JsonValue; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -34,9 +33,6 @@ import org.apache.ozone.lib.server.ServiceException; import org.apache.ozone.lib.service.Instrumentation; import org.apache.ozone.lib.service.Scheduler; -import org.json.simple.JSONAware; -import org.json.simple.JSONObject; -import org.json.simple.JSONStreamAware; /** * Hadoop server instrumentation. @@ -195,7 +191,7 @@ void end() { } - static class Timer implements JSONAware, JSONStreamAware { + static class Timer { static final int LAST_TOTAL = 0; static final int LAST_OWN = 1; static final int AVG_TOTAL = 2; @@ -251,10 +247,10 @@ void addCron(Cron cron) { } } - @SuppressWarnings("unchecked") - private JSONObject getJSON() { + @JsonValue + private Map getJSON() { long[] values = getValues(); - JSONObject json = new JSONObject(); + Map json = new LinkedHashMap<>(); json.put("lastTotal", values[0]); json.put("lastOwn", values[1]); json.put("avgTotal", values[2]); @@ -262,16 +258,6 @@ private JSONObject getJSON() { return json; } - @Override - public String toJSONString() { - return getJSON().toJSONString(); - } - - @Override - public void writeJSONString(Writer out) throws IOException { - getJSON().writeJSONString(out); - } - } @Override @@ -295,7 +281,7 @@ public void addCron(String group, String name, Instrumentation.Cron cron) { timer.addCron((Cron) cron); } - static class VariableHolder implements JSONAware, JSONStreamAware { + static class VariableHolder { // Supressed, because it is only used in this class or in test files, // but the tests will be removed later. @SuppressWarnings("checkstyle:VisibilityModifier") @@ -308,23 +294,13 @@ static class VariableHolder implements JSONAware, JSONStreamAware { this.var = var; } - @SuppressWarnings("unchecked") - private JSONObject getJSON() { - JSONObject json = new JSONObject(); + @JsonValue + private Map getJSON() { + Map json = new LinkedHashMap<>(); json.put("value", var.getValue()); return json; } - @Override - public String toJSONString() { - return getJSON().toJSONString(); - } - - @Override - public void writeJSONString(Writer out) throws IOException { - out.write(toJSONString()); - } - } @Override @@ -334,7 +310,7 @@ public void addVariable(String group, String name, Variable variable) { holder.var = variable; } - static class Sampler implements JSONAware, JSONStreamAware { + static class Sampler { private Variable variable; private long[] values; private AtomicLong sum; @@ -362,23 +338,13 @@ void sample() { ((full) ? values.length : ((last == 0) ? 1 : last)); } - @SuppressWarnings("unchecked") - private JSONObject getJSON() { - JSONObject json = new JSONObject(); + @JsonValue + private Map getJSON() { + Map json = new LinkedHashMap<>(); json.put("sampler", getRate()); json.put("size", (full) ? values.length : last); return json; } - - @Override - public String toJSONString() { - return getJSON().toJSONString(); - } - - @Override - public void writeJSONString(Writer out) throws IOException { - out.write(toJSONString()); - } } @Override diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONMapProvider.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONMapProvider.java index bdb75490f83f..232993effe60 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONMapProvider.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONMapProvider.java @@ -17,6 +17,8 @@ package org.apache.ozone.lib.wsrs; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -33,7 +35,6 @@ import javax.ws.rs.ext.Provider; import org.apache.hadoop.hdds.annotation.InterfaceAudience; import org.apache.hadoop.http.JettyUtils; -import org.json.simple.JSONObject; /** * A MessageBodyWriter implementation providing a JSON map. @@ -43,6 +44,10 @@ @InterfaceAudience.Private public class JSONMapProvider implements MessageBodyWriter { private static final String ENTER = System.getProperty("line.separator"); + // AUTO_CLOSE_TARGET is disabled so the underlying response stream stays + // open for the trailing newline and container-managed close. + private static final ObjectMapper MAPPER = new ObjectMapper() + .disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); @Override public boolean isWriteable(Class aClass, @@ -72,7 +77,7 @@ public void writeTo(Map map, throws IOException, WebApplicationException { Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); - JSONObject.writeJSONString(map, writer); + MAPPER.writeValue(writer, map); writer.write(ENTER); writer.flush(); } diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONProvider.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONProvider.java deleted file mode 100644 index b98d4db19f18..000000000000 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/wsrs/JSONProvider.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 - * - * http://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.ozone.lib.wsrs; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; -import org.apache.hadoop.hdds.annotation.InterfaceAudience; -import org.apache.hadoop.http.JettyUtils; -import org.json.simple.JSONStreamAware; - -/** - * A MessageBodyWriter implementation providing a JSON stream. - */ -@Provider -@Produces(MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8) -@InterfaceAudience.Private -public class JSONProvider implements MessageBodyWriter { - private static final String ENTER = System.getProperty("line.separator"); - - @Override - public boolean isWriteable(Class aClass, - Type type, - Annotation[] annotations, - MediaType mediaType) { - return JSONStreamAware.class.isAssignableFrom(aClass); - } - - @Override - public long getSize(JSONStreamAware jsonStreamAware, - Class aClass, - Type type, - Annotation[] annotations, - MediaType mediaType) { - return -1; - } - - @Override - public void writeTo(JSONStreamAware jsonStreamAware, - Class aClass, - Type type, - Annotation[] annotations, - MediaType mediaType, - MultivaluedMap stringObjectMultivaluedMap, - OutputStream outputStream) - throws IOException, WebApplicationException { - Writer writer - = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); - jsonStreamAware.writeJSONString(writer); - writer.write(ENTER); - writer.flush(); - } - -} diff --git a/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/service/instrumentation/TestInstrumentationSerialization.java b/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/service/instrumentation/TestInstrumentationSerialization.java new file mode 100644 index 000000000000..19f0d033981c --- /dev/null +++ b/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/service/instrumentation/TestInstrumentationSerialization.java @@ -0,0 +1,78 @@ +/* + * 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 + * + * http://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.ozone.lib.service.instrumentation; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.ozone.lib.service.Instrumentation; +import org.junit.jupiter.api.Test; + +/** + * Verifies that the {@code @JsonValue}-annotated snapshot types in + * {@link InstrumentationService} serialize to the same JSON shape that the + * former json-simple based serialization produced. + */ +public class TestInstrumentationSerialization { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @Test + public void testTimerSerialization() { + InstrumentationService.Cron cron = new InstrumentationService.Cron(); + cron.start(); + cron.stop(); + InstrumentationService.Timer timer = new InstrumentationService.Timer(10); + timer.addCron(cron); + + JsonNode node = MAPPER.valueToTree(timer); + assertThat(node.isObject()).isTrue(); + assertThat(node.fieldNames()).toIterable() + .containsExactly("lastTotal", "lastOwn", "avgTotal", "avgOwn"); + assertThat(node.get("lastTotal").isNumber()).isTrue(); + assertThat(node.get("avgOwn").isNumber()).isTrue(); + } + + @Test + public void testVariableHolderSerialization() { + InstrumentationService.VariableHolder holder = + new InstrumentationService.VariableHolder<>( + (Instrumentation.Variable) () -> 42L); + + JsonNode node = MAPPER.valueToTree(holder); + assertThat(node.isObject()).isTrue(); + assertThat(node.fieldNames()).toIterable().containsExactly("value"); + assertThat(node.get("value").asLong()).isEqualTo(42L); + } + + @Test + public void testSamplerSerialization() { + InstrumentationService.Sampler sampler = + new InstrumentationService.Sampler(); + sampler.init(4, () -> 7L); + sampler.sample(); + + JsonNode node = MAPPER.valueToTree(sampler); + assertThat(node.isObject()).isTrue(); + assertThat(node.fieldNames()).toIterable() + .containsExactly("sampler", "size"); + assertThat(node.get("sampler").isNumber()).isTrue(); + assertThat(node.get("size").asInt()).isEqualTo(1); + } +} diff --git a/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/wsrs/TestJSONMapProvider.java b/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/wsrs/TestJSONMapProvider.java new file mode 100644 index 000000000000..606f31454309 --- /dev/null +++ b/hadoop-ozone/httpfsgateway/src/test/java/org/apache/ozone/lib/wsrs/TestJSONMapProvider.java @@ -0,0 +1,71 @@ +/* + * 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 + * + * http://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.ozone.lib.wsrs; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.jupiter.api.Test; + +/** + * Tests {@link JSONMapProvider} JSON output framing after the json-simple to + * Jackson migration. + */ +public class TestJSONMapProvider { + + private String writeToString(Map map, ByteArrayOutputStream out) + throws IOException { + new JSONMapProvider().writeTo(map, Map.class, Map.class, null, null, null, out); + return new String(out.toByteArray(), StandardCharsets.UTF_8); + } + + @Test + public void testWriteToEmitsJsonWithTrailingNewline() throws IOException { + Map map = new LinkedHashMap<>(); + map.put("boolean", true); + map.put("long", 42L); + map.put("string", "value"); + + String output = writeToString(map, new ByteArrayOutputStream()); + assertThat(output).isEqualTo( + "{\"boolean\":true,\"long\":42,\"string\":\"value\"}" + + System.getProperty("line.separator")); + } + + @Test + public void testWriteToDoesNotCloseUnderlyingStream() throws IOException { + AtomicBoolean closed = new AtomicBoolean(false); + ByteArrayOutputStream out = new ByteArrayOutputStream() { + @Override + public void close() { + closed.set(true); + } + }; + + Map map = new LinkedHashMap<>(); + map.put("k", "v"); + writeToString(map, out); + + assertThat(closed).isFalse(); + } +} From 94de6b59bf6524f56450660ac6b2dd17203f299d Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:47:01 -0700 Subject: [PATCH 2/9] HDDS-15808. Make @JsonValue getJSON() methods package-private for PMD PMD's UnusedPrivateMethod flagged the three @JsonValue-annotated getJSON() methods (Timer, VariableHolder, Sampler) as unused because it does not see Jackson's reflective invocation. Reducing them to package-private takes them out of the rule's scope while keeping them effectively internal; Jackson serializes @JsonValue methods at any visibility. Co-Authored-By: Claude Opus 4.8 --- .../lib/service/instrumentation/InstrumentationService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java index 5cb1a8e23c8a..52a8dbfd03d7 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java @@ -248,7 +248,7 @@ void addCron(Cron cron) { } @JsonValue - private Map getJSON() { + Map getJSON() { long[] values = getValues(); Map json = new LinkedHashMap<>(); json.put("lastTotal", values[0]); @@ -295,7 +295,7 @@ static class VariableHolder { } @JsonValue - private Map getJSON() { + Map getJSON() { Map json = new LinkedHashMap<>(); json.put("value", var.getValue()); return json; @@ -339,7 +339,7 @@ void sample() { } @JsonValue - private Map getJSON() { + Map getJSON() { Map json = new LinkedHashMap<>(); json.put("sampler", getRate()); json.put("size", (full) ? values.length : last); From 7afc6c54b567b3dd45bc841ea5942252633a5c5e Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:56:53 -0700 Subject: [PATCH 3/9] HDDS-15808. Address review: drop vestigial backslash strip and fix stale comment FSCreateSnapshot no longer strips all backslashes from the serialized JSON. That strip existed only to undo json-simple's forward-slash escaping (\/); Jackson does not escape forward slashes, so the strip was a no-op for normal paths and would corrupt any value Jackson legitimately escapes (\", \\, \n). Return the Jackson output as-is. Also reword the misspelled, stale VisibilityModifier comment on VariableHolder.var to describe the actual reason for the suppression. Co-Authored-By: Claude Opus 4.8 --- .../java/org/apache/ozone/fs/http/server/FSOperations.java | 2 +- .../lib/service/instrumentation/InstrumentationService.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index 28db872aacad..1929ac592834 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -1786,7 +1786,7 @@ public String execute(FileSystem fs) throws IOException { Path snapshotPath = fs.createSnapshot(path, snapshotName); Map json = toJSON(HttpFSConstants.HOME_DIR_JSON, snapshotPath.toString()); - return JsonUtil.toJsonString(json).replaceAll("\\\\", ""); + return JsonUtil.toJsonString(json); } } diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java index 52a8dbfd03d7..d441df55efd7 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/lib/service/instrumentation/InstrumentationService.java @@ -282,8 +282,8 @@ public void addCron(String group, String name, Instrumentation.Cron cron) { } static class VariableHolder { - // Supressed, because it is only used in this class or in test files, - // but the tests will be removed later. + // Package-private and mutable so the enclosing service can assign it + // directly; suppress the visibility check. @SuppressWarnings("checkstyle:VisibilityModifier") Variable var; From 3214d75321c86a76a6f1614bfb27b5745c1cf065 Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 00:59:11 -0700 Subject: [PATCH 4/9] HDDS-15808. Address review: fix toJSON Javadoc referencing removed JsonAware The toJSON Javadoc still described the value as a json-simple JsonAware instance. Update it to reflect Jackson serialization. Co-Authored-By: Claude Opus 4.8 --- .../java/org/apache/ozone/fs/http/server/FSOperations.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index 1929ac592834..48d14ae47adc 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -365,8 +365,8 @@ private static Map quotaUsageToMap(QuotaUsage quotaUsage) { /** * Converts an object into a Json Map with with one key-value entry. *

- * It assumes the given value is either a JSON primitive type or a - * JsonAware instance. + * The value may be a JSON primitive, a Map or List, or any object that + * Jackson can serialize. * * @param name name for the key of the entry. * @param value for the value of the entry. From 05b051aacea73eb8213c6901b2809e8f551519ed Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 01:06:04 -0700 Subject: [PATCH 5/9] HDDS-15808. Address review: remove duplicated word in toJSON Javadoc Co-Authored-By: Claude Opus 4.8 --- .../main/java/org/apache/ozone/fs/http/server/FSOperations.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index 48d14ae47adc..c128d17345b6 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -363,7 +363,7 @@ private static Map quotaUsageToMap(QuotaUsage quotaUsage) { } /** - * Converts an object into a Json Map with with one key-value entry. + * Converts an object into a Json Map with one key-value entry. *

* The value may be a JSON primitive, a Map or List, or any object that * Jackson can serialize. From 79c4f871171a50fd07aeb2b3cab60cf3d23a83d1 Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 01:13:55 -0700 Subject: [PATCH 6/9] HDDS-15808. Address review: narrow List to concrete element types Tighten the generic types of the JSON array locals introduced by the migration (previously json-simple JSONArray) to their actual element types: List> for status/policy lists and List for ACL entries and storage type names. No change to serialized JSON. Co-Authored-By: Claude Opus 4.8 --- .../org/apache/ozone/fs/http/server/FSOperations.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index c128d17345b6..51b7ac9b5fb3 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -106,7 +106,7 @@ private static Map toJson(FileStatus[] fileStatuses, boolean isFile) { Map json = new LinkedHashMap<>(); Map inner = new LinkedHashMap<>(); - List statuses = new ArrayList<>(); + List> statuses = new ArrayList<>(); for (FileStatus f : fileStatuses) { statuses.add(toJsonInner(f, isFile)); } @@ -208,7 +208,7 @@ private static Map toJson(FileSystem.DirectoryEntries private static Map aclStatusToJSON(AclStatus aclStatus) { Map json = new LinkedHashMap(); Map inner = new LinkedHashMap(); - List entriesArray = new ArrayList<>(); + List entriesArray = new ArrayList<>(); inner.put(HttpFSConstants.OWNER_JSON, aclStatus.getOwner()); inner.put(HttpFSConstants.GROUP_JSON, aclStatus.getGroup()); inner.put(HttpFSConstants.PERMISSION_JSON, @@ -393,8 +393,8 @@ private static Map storagePolicyToJSON( return policyJson; } - private static List toJsonArray(StorageType[] storageTypes) { - List jsonArray = new ArrayList<>(); + private static List toJsonArray(StorageType[] storageTypes) { + List jsonArray = new ArrayList<>(); for (StorageType type : storageTypes) { jsonArray.add(type.toString()); } @@ -404,7 +404,7 @@ private static List toJsonArray(StorageType[] storageTypes) { private static Map storagePoliciesToJSON( Collection storagePolicies) { Map json = new LinkedHashMap<>(); - List jsonArray = new ArrayList<>(); + List> jsonArray = new ArrayList<>(); Map policies = new LinkedHashMap<>(); if (storagePolicies != null) { for (BlockStoragePolicySpi policy : storagePolicies) { From 731cef423a61889bfd0e2e8fe11e410b38c6a2ee Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 01:20:10 -0700 Subject: [PATCH 7/9] HDDS-15808. Remove json-simple from root pom dependencyManagement The root pom still declared the json-simple version property and a dependencyManagement entry after the module dependency was dropped. No module or source references json-simple anymore, so remove both to complete the removal. Co-Authored-By: Claude Opus 4.8 --- pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pom.xml b/pom.xml index 97b7d0991a3b..74b4ad9fd7cb 100644 --- a/pom.xml +++ b/pom.xml @@ -118,7 +118,6 @@ 2.12.7 3.11.10 0.1.55 - 1.1.1 2.1 1.1.1 5.14.4 @@ -456,11 +455,6 @@ compile-testing ${compile-testing.version} - - com.googlecode.json-simple - json-simple - ${json-simple.version} - com.jcraft jsch From 2378d434cd01a6292a3b7a22879441d26f6784e2 Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 01:34:18 -0700 Subject: [PATCH 8/9] HDDS-15808. Address review: fully parameterize xAttrsToJSON Narrow the JSON array introduced by the migration to List> and parameterize the raw Map locals and return type in xAttrsToJSON. The unchecked/rawtypes suppression is no longer needed. No change to serialized JSON. Co-Authored-By: Claude Opus 4.8 --- .../org/apache/ozone/fs/http/server/FSOperations.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java index 51b7ac9b5fb3..eb2998e9cf60 100644 --- a/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java +++ b/hadoop-ozone/httpfsgateway/src/main/java/org/apache/ozone/fs/http/server/FSOperations.java @@ -253,14 +253,13 @@ private static Map fileChecksumToJSON(FileChecksum checksum) { * @return The JSON representation of the xAttrs. * @throws IOException */ - @SuppressWarnings({"unchecked", "rawtypes"}) - private static Map xAttrsToJSON(Map xAttrs, + private static Map xAttrsToJSON(Map xAttrs, XAttrCodec encoding) throws IOException { - Map jsonMap = new LinkedHashMap(); - List jsonArray = new ArrayList<>(); + Map jsonMap = new LinkedHashMap<>(); + List> jsonArray = new ArrayList<>(); if (xAttrs != null) { for (Entry e : xAttrs.entrySet()) { - Map json = new LinkedHashMap(); + Map json = new LinkedHashMap<>(); json.put(HttpFSConstants.XATTR_NAME_JSON, e.getKey()); if (e.getValue() != null) { json.put(HttpFSConstants.XATTR_VALUE_JSON, From 488d2e6f853f26d91bd306c4bb3f18b257375e8c Mon Sep 17 00:00:00 2001 From: Siyao Meng <50227127+smengcl@users.noreply.github.com> Date: Fri, 10 Jul 2026 01:48:10 -0700 Subject: [PATCH 9/9] HDDS-15808. Declare jackson-core and jackson-annotations in httpfsgateway The migration references jackson-core (JsonGenerator.Feature in JSONMapProvider) and jackson-annotations (@JsonValue in InstrumentationService) directly, but the module only pulled them in transitively via jackson-databind. maven-dependency-plugin analyze-only flagged them as used-undeclared. Declare both explicitly. Co-Authored-By: Claude Opus 4.8 --- hadoop-ozone/httpfsgateway/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hadoop-ozone/httpfsgateway/pom.xml b/hadoop-ozone/httpfsgateway/pom.xml index ea0a5798ffce..a8562e52c149 100644 --- a/hadoop-ozone/httpfsgateway/pom.xml +++ b/hadoop-ozone/httpfsgateway/pom.xml @@ -42,6 +42,14 @@ reload4j compile + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + com.fasterxml.jackson.core jackson-databind