This is an automated email from the ASF dual-hosted git repository.
damccorm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new cdaa5ff456d [Java] Remove MS_EXPOSE_REP from the global SpotBugs
filter (#39951)
cdaa5ff456d is described below
commit cdaa5ff456dfc0b3550ca92eef7a564d45e5844d
Author: Maksym Tymoshyk <[email protected]>
AuthorDate: Thu Sep 3 20:58:28 2026 +0300
[Java] Remove MS_EXPOSE_REP from the global SpotBugs filter (#39951)
The global filter turns off MS_EXPOSE_REP for every module. That hides 34
findings today, and hides any new one automatically.
Remove that line and mark the existing sites one by one with
@SuppressFBWarnings, each carrying the reason it is exempt. Nothing changes
at runtime. What changes is that the next accessor someone writes that
returns a mutable static will fail spotbugsMain instead of passing quietly.
The three Guava sites cannot be configured away. SpotBugs checks its list of
known immutable types by fully qualified name, so it does not recognise
Guava relocated into org.apache.beam.vendor.guava, and the fallback scan
finds setter-named methods on ImmutableCollection. See
https://github.com/spotbugs/spotbugs/issues/1601.
Addresses #35312.
---
.../apache/beam/runners/spark/metrics/MetricsAccumulator.java | 5 +++++
.../spark/structuredstreaming/metrics/MetricsAccumulator.java | 5 +++++
.../java/build-tools/src/main/resources/beam/spotbugs-filter.xml | 1 -
.../core/src/main/java/org/apache/beam/sdk/metrics/Lineage.java | 9 +++++++++
.../src/main/java/org/apache/beam/sdk/metrics/SourceMetrics.java | 9 +++++++++
.../java/org/apache/beam/sdk/util/construction/ModelCoders.java | 7 +++++++
.../apache/beam/sdk/util/construction/PTransformTranslation.java | 7 +++++++
.../main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java | 5 +++++
.../main/java/org/apache/beam/sdk/testutils/NamedTestResult.java | 7 +++++++
.../src/main/java/org/apache/beam/sdk/tpcds/TpcdsSchemas.java | 6 ++++++
10 files changed, 60 insertions(+), 1 deletion(-)
diff --git
a/runners/spark/src/main/java/org/apache/beam/runners/spark/metrics/MetricsAccumulator.java
b/runners/spark/src/main/java/org/apache/beam/runners/spark/metrics/MetricsAccumulator.java
index dbdfe11a585..612d71b1aea 100644
---
a/runners/spark/src/main/java/org/apache/beam/runners/spark/metrics/MetricsAccumulator.java
+++
b/runners/spark/src/main/java/org/apache/beam/runners/spark/metrics/MetricsAccumulator.java
@@ -17,6 +17,7 @@
*/
package org.apache.beam.runners.spark.metrics;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import org.apache.beam.runners.core.metrics.MetricsContainerStepMap;
import org.apache.beam.runners.spark.SparkPipelineOptions;
@@ -82,6 +83,10 @@ public class MetricsAccumulator {
}
}
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Spark merges only the accumulator instance the driver registered. A
copy would collect metrics that nothing reports.")
public static MetricsContainerStepMapAccumulator getInstance() {
if (instance == null) {
throw new IllegalStateException("Metrics accumulator has not been
instantiated");
diff --git
a/runners/spark/src/main/java/org/apache/beam/runners/spark/structuredstreaming/metrics/MetricsAccumulator.java
b/runners/spark/src/main/java/org/apache/beam/runners/spark/structuredstreaming/metrics/MetricsAccumulator.java
index 63407b9f14d..e8cbd895082 100644
---
a/runners/spark/src/main/java/org/apache/beam/runners/spark/structuredstreaming/metrics/MetricsAccumulator.java
+++
b/runners/spark/src/main/java/org/apache/beam/runners/spark/structuredstreaming/metrics/MetricsAccumulator.java
@@ -17,6 +17,7 @@
*/
package org.apache.beam.runners.spark.structuredstreaming.metrics;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.beam.runners.core.metrics.MetricsContainerStepMap;
import
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.annotations.VisibleForTesting;
import org.apache.spark.sql.SparkSession;
@@ -85,6 +86,10 @@ public class MetricsAccumulator
* Get the {@link MetricsAccumulator} on this driver. If there's no such
accumulator yet, it will
* be created and registered using the provided {@link SparkSession}.
*/
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Spark merges only the accumulator instance the driver registered. A
copy would collect metrics that nothing reports.")
public static MetricsAccumulator getInstance(SparkSession session) {
MetricsAccumulator current = instance;
if (current != null) {
diff --git a/sdks/java/build-tools/src/main/resources/beam/spotbugs-filter.xml
b/sdks/java/build-tools/src/main/resources/beam/spotbugs-filter.xml
index 4393ec6a624..5f6f368228e 100644
--- a/sdks/java/build-tools/src/main/resources/beam/spotbugs-filter.xml
+++ b/sdks/java/build-tools/src/main/resources/beam/spotbugs-filter.xml
@@ -57,7 +57,6 @@
<!-- TODO(https://github.com/apache/beam/issues/35312) resolve findings-->
<Bug pattern="CT_CONSTRUCTOR_THROW"/>
- <Bug pattern="MS_EXPOSE_REP"/>
<!--
Many test classes are captured by lambdas and marked `implements
Serializable`. They are not
diff --git
a/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/Lineage.java
b/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/Lineage.java
index f845d8fde94..681f022c904 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/Lineage.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/Lineage.java
@@ -19,6 +19,7 @@ package org.apache.beam.sdk.metrics;
import static
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Preconditions.checkNotNull;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@@ -122,6 +123,10 @@ public class Lineage {
}
/** {@link Lineage} representing sources and optionally side inputs. */
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Every reporter writes into the same metric cell, so all callers
need the one shared instance. A copy would drop the lineage it records.")
public static Lineage getSources() {
Lineage localSources = sources;
if (localSources == null) {
@@ -131,6 +136,10 @@ public class Lineage {
}
/** {@link Lineage} representing sinks. */
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Every reporter writes into the same metric cell, so all callers
need the one shared instance. A copy would drop the lineage it records.")
public static Lineage getSinks() {
Lineage localSinks = sinks;
if (localSinks == null) {
diff --git
a/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/SourceMetrics.java
b/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/SourceMetrics.java
index e9677626f88..5d033d4a91a 100644
---
a/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/SourceMetrics.java
+++
b/sdks/java/core/src/main/java/org/apache/beam/sdk/metrics/SourceMetrics.java
@@ -17,6 +17,7 @@
*/
package org.apache.beam.sdk.metrics;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Joiner;
/** Standard {@link org.apache.beam.sdk.io.Source} Metrics. */
@@ -69,6 +70,10 @@ public class SourceMetrics {
}
/** Gauge for source backlog in bytes. */
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "A Gauge is a handle onto one metric cell, not a value. A copy would
send the reading nowhere.")
public static Gauge backlogBytes() {
return BACKLOG_BYTES_GAUGE;
}
@@ -84,6 +89,10 @@ public class SourceMetrics {
}
/** Gauge for source backlog in elements. */
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "A Gauge is a handle onto one metric cell, not a value. A copy would
send the reading nowhere.")
public static Gauge backlogElements() {
return BACKLOG_ELEMENTS_GAUGE;
}
diff --git
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/ModelCoders.java
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/ModelCoders.java
index 5059cc1c6b8..f625e376abc 100644
---
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/ModelCoders.java
+++
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/ModelCoders.java
@@ -22,6 +22,7 @@ import static
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Pr
import static
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Preconditions.checkState;
import com.google.auto.value.AutoValue;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Set;
import org.apache.beam.model.pipeline.v1.RunnerApi.Coder;
import org.apache.beam.model.pipeline.v1.RunnerApi.FunctionSpec;
@@ -97,6 +98,12 @@ public class ModelCoders {
SHARDED_KEY_CODER_URN,
NULLABLE_CODER_URN);
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Returns a Guava ImmutableSet."
+ + " Spotbugs matches its known-immutable list by fully qualified
name, so it cannot recognise collections relocated into
org.apache.beam.vendor.guava."
+ + " See https://github.com/spotbugs/spotbugs/issues/1601.")
public static Set<String> urns() {
return MODEL_CODER_URNS;
}
diff --git
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java
index 5f8782265f1..88bfb8b5b53 100644
---
a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java
+++
b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PTransformTranslation.java
@@ -22,6 +22,7 @@ import static
org.apache.beam.model.pipeline.v1.ExternalTransforms.ExpansionMeth
import static org.apache.beam.sdk.util.construction.BeamUrns.getUrn;
import static
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Preconditions.checkState;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
@@ -417,6 +418,12 @@ public class PTransformTranslation {
knownPayloadTranslators;
@Internal
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Returns a Guava ImmutableMap."
+ + " Spotbugs matches its known-immutable list by fully qualified
name, so it cannot recognise collections relocated into
org.apache.beam.vendor.guava."
+ + " See https://github.com/spotbugs/spotbugs/issues/1601.")
public static Map<Class<? extends PTransform>, TransformPayloadTranslator>
getKnownPayloadTranslators() {
if (knownPayloadTranslators == null) {
diff --git
a/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java
b/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java
index e4e698faffa..b24f132a001 100644
---
a/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java
+++
b/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftSchema.java
@@ -19,6 +19,7 @@ package org.apache.beam.sdk.io.thrift;
import static java.util.Collections.unmodifiableMap;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
@@ -121,6 +122,10 @@ public final class ThriftSchema extends
GetterBasedSchemaProviderV2 {
*
* @see #custom() for how to manually pass the beam type for container
typedefs
*/
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "The default provider holds an empty typedef map that is never
mutated. Callers needing typedefs go through custom(), which builds a separate
instance.")
public static @NonNull SchemaProvider provider() {
return defaultProvider;
}
diff --git
a/sdks/java/testing/test-utils/src/main/java/org/apache/beam/sdk/testutils/NamedTestResult.java
b/sdks/java/testing/test-utils/src/main/java/org/apache/beam/sdk/testutils/NamedTestResult.java
index a4f40598d5a..112c29b30ee 100644
---
a/sdks/java/testing/test-utils/src/main/java/org/apache/beam/sdk/testutils/NamedTestResult.java
+++
b/sdks/java/testing/test-utils/src/main/java/org/apache/beam/sdk/testutils/NamedTestResult.java
@@ -18,6 +18,7 @@
package org.apache.beam.sdk.testutils;
import com.google.cloud.bigquery.LegacySQLTypeName;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;
import org.apache.beam.sdk.testutils.publishing.InfluxDBPublisher;
import
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.collect.ImmutableMap;
@@ -83,6 +84,12 @@ public class NamedTestResult implements TestResult {
.build();
}
+ @SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Returns a Guava ImmutableMap."
+ + " Spotbugs matches its known-immutable list by fully qualified
name, so it cannot recognise collections relocated into
org.apache.beam.vendor.guava."
+ + " See https://github.com/spotbugs/spotbugs/issues/1601.")
public static Map<String, String> getSchema() {
return schema;
}
diff --git
a/sdks/java/testing/tpcds/src/main/java/org/apache/beam/sdk/tpcds/TpcdsSchemas.java
b/sdks/java/testing/tpcds/src/main/java/org/apache/beam/sdk/tpcds/TpcdsSchemas.java
index a22bab1c89e..763e8164dee 100644
---
a/sdks/java/testing/tpcds/src/main/java/org/apache/beam/sdk/tpcds/TpcdsSchemas.java
+++
b/sdks/java/testing/tpcds/src/main/java/org/apache/beam/sdk/tpcds/TpcdsSchemas.java
@@ -17,12 +17,18 @@
*/
package org.apache.beam.sdk.tpcds;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.beam.sdk.schemas.Schema;
import
org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.collect.ImmutableMap;
+@SuppressFBWarnings(
+ value = "MS_EXPOSE_REP",
+ justification =
+ "Fixed TPC-DS table definitions, built once at class load."
+ + " Schema is mutable only through setUUID, which no caller here
uses, and copying twenty-four schemas on every accessor call would cost real
time in a benchmark harness.")
public class TpcdsSchemas {
/**
* Get all tpcds table schemas automatically by reading json files. In this
case all field will be