From 17836d53662701445de6cce198aedb4b4b15988e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 29 May 2026 16:13:25 +0200 Subject: [PATCH 1/2] build: add SpotBugs plugin and fix all reported findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the SpotBugs Maven plugin (effort=Max, threshold=Medium) with a `check` execution bound to the `verify` phase across all modules, plus a documented `spotbugs-exclude.xml` for intentional/false-positive findings. Real bug fixes: - ExecutorServiceManager: synchronize start()/stop() so `started` and `configurationService` are accessed consistently with the already-locked lazyInitWorkflowExecutorService() (IS2_INCONSISTENT_SYNC, AT_STALE_THREAD_WRITE_OF_PRIMITIVE). - AbstractEventSourceHolderDependentResource: make `isCacheFillerEventSource` volatile (written under lock, read from reconcile threads). - ManagedInformerEventSource: make `cache` and `controllerConfiguration` volatile (assigned under lock in start(), read lock-free). - AbstractOperatorExtension: the builder's `namespaceDeleteTimeout` was configurable but never plumbed into the extension, so the namespace deletion timeout always used the default. Threaded it through the constructors of both LocallyRunOperatorExtension and ClusterDeployedOperatorExtension. - MicrometerMetrics.addMetadataTags(): guard against null `metadata`, which incrementCounter() already tolerates (latent NPE, NP_NULL_PARAM_DEREF). - Bootstrapper.addTemplatedFile(): close the Writer via try-with-resources and write as UTF-8 (OBL_UNSATISFIED_OBLIGATION, DM_DEFAULT_ENCODING). Default-encoding fixes (DM_DEFAULT_ENCODING), all pinned to UTF-8: - LocallyRunOperatorExtension CRD apply/delete byte conversions. - AccumulativeMappingWriter reader and PrintWriter. - ClassMappingProvider InputStreamReader. - sample mysql-schema Secret/Schema Base64 encode/decode. - sample tomcat-operator WebappReconciler ByteArrayOutputStream.toString(). Sample cleanups: - TomcatReconciler: avoid unbox-then-rebox in a log argument (BX_UNBOXING_IMMEDIATELY_REBOXED). - OperationsSampleOperator: make the config path overridable via the CONFIG_PATH env var instead of a hardcoded absolute path (DMI_HARDCODED_ABSOLUTE_FILENAME). Suppressed in spotbugs-exclude.xml (intentional / false positives): EI_EXPOSE_REP(2) and CT_CONSTRUCTOR_THROW project-wide, plus DM_EXIT in LeaderElectionManager, NP_BOOLEAN_RETURN_NULL in BooleanWithUndefined, EQ_DOESNT_OVERRIDE_EQUALS in GroupVersionKindPlural, and SING_SINGLETON_HAS_NONPRIVATE_CONSTRUCTOR in SSABasedGenericKubernetesResourceMatcher and ConfigLoader. Co-Authored-By: Claude Opus 4.8 (1M context) Signed-off-by: Attila Mészáros --- .../boostrapper/Bootstrapper.java | 8 ++- .../micrometer/MicrometerMetrics.java | 3 +- .../api/config/ExecutorServiceManager.java | 4 +- ...actEventSourceHolderDependentResource.java | 2 +- .../informer/ManagedInformerEventSource.java | 4 +- .../junit/AbstractOperatorExtension.java | 4 +- .../ClusterDeployedOperatorExtension.java | 3 + .../junit/LocallyRunOperatorExtension.java | 11 ++- .../runtime/AccumulativeMappingWriter.java | 6 +- .../config/runtime/ClassMappingProvider.java | 4 +- pom.xml | 25 +++++++ .../dependent/SchemaDependentResource.java | 4 +- .../dependent/SecretDependentResource.java | 3 +- .../operations/OperationsSampleOperator.java | 3 +- .../operator/sample/TomcatReconciler.java | 4 +- .../operator/sample/WebappReconciler.java | 3 +- spotbugs-exclude.xml | 70 +++++++++++++++++++ 17 files changed, 141 insertions(+), 20 deletions(-) create mode 100644 spotbugs-exclude.xml diff --git a/bootstrapper-maven-plugin/src/main/java/io/javaoperatorsdk/boostrapper/Bootstrapper.java b/bootstrapper-maven-plugin/src/main/java/io/javaoperatorsdk/boostrapper/Bootstrapper.java index 1611b2e410..d2ef738cf0 100644 --- a/bootstrapper-maven-plugin/src/main/java/io/javaoperatorsdk/boostrapper/Bootstrapper.java +++ b/bootstrapper-maven-plugin/src/main/java/io/javaoperatorsdk/boostrapper/Bootstrapper.java @@ -18,6 +18,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -132,9 +133,10 @@ private void addTemplatedFile( targetDir == null ? projectDir : targetDir, targetFileName == null ? fileName : targetFileName); FileUtils.forceMkdir(targetFile.getParentFile()); - var writer = new FileWriter(targetFile); - mustache.execute(writer, values); - writer.flush(); + try (var writer = new FileWriter(targetFile, StandardCharsets.UTF_8)) { + mustache.execute(writer, values); + writer.flush(); + } } catch (IOException e) { throw new RuntimeException(e); } diff --git a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java index 2499b2f131..60f58b411f 100644 --- a/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java +++ b/micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java @@ -277,7 +277,8 @@ private void addMetadataTags( addTagOmittingOnEmptyValue(NAMESPACE, resourceID.getNamespace().orElse(null), tags, prefixed); } addTag(SCOPE, getScope(resourceID), tags, prefixed); - final var gvk = (GroupVersionKind) metadata.get(Constants.RESOURCE_GVK_KEY); + final var gvk = + metadata == null ? null : (GroupVersionKind) metadata.get(Constants.RESOURCE_GVK_KEY); if (gvk != null) { addGVKTags(gvk, tags, prefixed); } diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java index a66ed19abd..58928b1302 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/config/ExecutorServiceManager.java @@ -132,7 +132,7 @@ public ScheduledExecutorService scheduledExecutorService() { return scheduledExecutorService; } - public void start(ConfigurationService configurationService) { + public synchronized void start(ConfigurationService configurationService) { if (!started) { this.configurationService = configurationService; // used to lazy init workflow executor this.cachingExecutorService = Executors.newCachedThreadPool(); @@ -142,7 +142,7 @@ public void start(ConfigurationService configurationService) { } } - public void stop(Duration gracefulShutdownTimeout) { + public synchronized void stop(Duration gracefulShutdownTimeout) { try { log.debug("Closing executor"); var parallelExec = Executors.newFixedThreadPool(3); diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java index 7dff17baba..269a9b2279 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/AbstractEventSourceHolderDependentResource.java @@ -36,7 +36,7 @@ public abstract class AbstractEventSourceHolderDependentResource< private T eventSource; private final Class resourceType; - private boolean isCacheFillerEventSource; + private volatile boolean isCacheFillerEventSource; protected String eventSourceNameToUse; @SuppressWarnings("unchecked") diff --git a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java index f021101229..7254258f4f 100644 --- a/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java +++ b/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/ManagedInformerEventSource.java @@ -61,9 +61,9 @@ public abstract class ManagedInformerEventSource< Configurable { private static final Logger log = LoggerFactory.getLogger(ManagedInformerEventSource.class); - private InformerManager cache; + private volatile InformerManager cache; private final boolean comparableResourceVersions; - private ControllerConfiguration controllerConfiguration; + private volatile ControllerConfiguration controllerConfiguration; private final C configuration; private final Map>> indexers = new HashMap<>(); protected TemporaryResourceCache temporaryResourceCache; diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java index b11853c331..288b937c98 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/AbstractOperatorExtension.java @@ -61,7 +61,7 @@ public abstract class AbstractOperatorExtension protected final boolean preserveNamespaceOnError; protected final boolean skipNamespaceDeletion; protected final boolean waitForNamespaceDeletion; - protected final int namespaceDeleteTimeout = DEFAULT_NAMESPACE_DELETE_TIMEOUT; + protected final int namespaceDeleteTimeout; protected final Function namespaceNameSupplier; protected final Function perClassNamespaceNameSupplier; @@ -74,6 +74,7 @@ protected AbstractOperatorExtension( boolean preserveNamespaceOnError, boolean skipNamespaceDeletion, boolean waitForNamespaceDeletion, + int namespaceDeleteTimeout, KubernetesClient kubernetesClient, KubernetesClient infrastructureKubernetesClient, Function namespaceNameSupplier, @@ -90,6 +91,7 @@ protected AbstractOperatorExtension( this.preserveNamespaceOnError = preserveNamespaceOnError; this.skipNamespaceDeletion = skipNamespaceDeletion; this.waitForNamespaceDeletion = waitForNamespaceDeletion; + this.namespaceDeleteTimeout = namespaceDeleteTimeout; this.namespaceNameSupplier = namespaceNameSupplier; this.perClassNamespaceNameSupplier = perClassNamespaceNameSupplier; } diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java index 4bbfa3258d..84e5442096 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/ClusterDeployedOperatorExtension.java @@ -53,6 +53,7 @@ private ClusterDeployedOperatorExtension( boolean preserveNamespaceOnError, boolean skipNamespaceDeletion, boolean waitForNamespaceDeletion, + int namespaceDeleteTimeout, boolean oneNamespacePerClass, KubernetesClient kubernetesClient, KubernetesClient infrastructureKubernetesClient, @@ -65,6 +66,7 @@ private ClusterDeployedOperatorExtension( preserveNamespaceOnError, skipNamespaceDeletion, waitForNamespaceDeletion, + namespaceDeleteTimeout, kubernetesClient, infrastructureKubernetesClient, namespaceNameSupplier, @@ -231,6 +233,7 @@ public ClusterDeployedOperatorExtension build() { preserveNamespaceOnError, skipNamespaceDeletion, waitForNamespaceDeletion, + namespaceDeleteTimeout, oneNamespacePerClass, kubernetesClient, infrastructureKubernetesClient, diff --git a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java index 57860c9afc..2b2c3bec48 100644 --- a/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java +++ b/operator-framework-junit/src/main/java/io/javaoperatorsdk/operator/junit/LocallyRunOperatorExtension.java @@ -87,6 +87,7 @@ private LocallyRunOperatorExtension( boolean preserveNamespaceOnError, boolean skipNamespaceDeletion, boolean waitForNamespaceDeletion, + int namespaceDeleteTimeout, boolean oneNamespacePerClass, KubernetesClient kubernetesClient, KubernetesClient infrastructureKubernetesClient, @@ -103,6 +104,7 @@ private LocallyRunOperatorExtension( preserveNamespaceOnError, skipNamespaceDeletion, waitForNamespaceDeletion, + namespaceDeleteTimeout, kubernetesClient, infrastructureKubernetesClient, namespaceNameSupplier, @@ -184,7 +186,8 @@ public static void applyCrd(String resourceTypeName, KubernetesClient client) { private static void applyCrd(String crdString, String path, KubernetesClient client) { try { LOGGER.debug("Applying CRD: {}", crdString); - final var crd = client.load(new ByteArrayInputStream(crdString.getBytes())); + final var crd = + client.load(new ByteArrayInputStream(crdString.getBytes(StandardCharsets.UTF_8))); crd.serverSideApply(); appliedCRDs.add(new AppliedCRD.FileCRD(crdString, path)); Thread.sleep(CRD_READY_WAIT); // readiness is not applicable for CRD, just wait a little @@ -446,7 +449,10 @@ record FileCRD(String crdString, String path) implements AppliedCRD { public void delete(KubernetesClient client) { try { LOGGER.debug("Deleting CRD: {}", crdString); - final var items = client.load(new ByteArrayInputStream(crdString.getBytes())).items(); + final var items = + client + .load(new ByteArrayInputStream(crdString.getBytes(StandardCharsets.UTF_8))) + .items(); if (items == null || items.isEmpty() || items.get(0) == null) { LOGGER.warn("Could not determine CRD name from yaml: {}", path); return; @@ -620,6 +626,7 @@ public LocallyRunOperatorExtension build() { preserveNamespaceOnError, skipNamespaceDeletion, waitForNamespaceDeletion, + namespaceDeleteTimeout, oneNamespacePerClass, kubernetesClient, infrastructureKubernetesClient, diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AccumulativeMappingWriter.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AccumulativeMappingWriter.java index 39b0ee75cc..60a16fe74b 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AccumulativeMappingWriter.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/AccumulativeMappingWriter.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -51,7 +52,8 @@ public AccumulativeMappingWriter loadExistingMappings() { .getResource(StandardLocation.CLASS_OUTPUT, "", resourcePath); try (BufferedReader bufferedReader = - new BufferedReader(new InputStreamReader(readonlyResource.openInputStream()))) { + new BufferedReader( + new InputStreamReader(readonlyResource.openInputStream(), StandardCharsets.UTF_8))) { final var existingLines = bufferedReader .lines() @@ -81,7 +83,7 @@ public void flush() { processingEnvironment .getFiler() .createResource(StandardLocation.CLASS_OUTPUT, "", resourcePath); - printWriter = new PrintWriter(resource.openOutputStream()); + printWriter = new PrintWriter(resource.openOutputStream(), false, StandardCharsets.UTF_8); for (Map.Entry entry : mappings.entrySet()) { printWriter.println(entry.getKey() + "," + entry.getValue()); diff --git a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ClassMappingProvider.java b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ClassMappingProvider.java index 464b31eaaa..d7f942379b 100644 --- a/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ClassMappingProvider.java +++ b/operator-framework/src/main/java/io/javaoperatorsdk/operator/config/runtime/ClassMappingProvider.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; @@ -69,7 +70,8 @@ static Map provide(final String resourcePath, T key, V value) { } private static List retrieveClassNamePairs(URL url) throws IOException { - try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + try (BufferedReader br = + new BufferedReader(new InputStreamReader(url.openStream(), StandardCharsets.UTF_8))) { return br.lines().collect(Collectors.toList()); } } diff --git a/pom.xml b/pom.xml index 550a4cc001..89e7b81bec 100644 --- a/pom.xml +++ b/pom.xml @@ -103,6 +103,7 @@ 10.0.0 3.5.1 3.6.0 + 4.9.8.3 @@ -331,6 +332,11 @@ spotless-maven-plugin ${spotless.version} + + com.github.spotbugs + spotbugs-maven-plugin + ${spotbugs-maven-plugin.version} + @@ -431,6 +437,25 @@ + + com.github.spotbugs + spotbugs-maven-plugin + + Max + Medium + false + ${maven.multiModuleProjectDirectory}/spotbugs-exclude.xml + + + + spotbugs-check + + check + + verify + + + diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java index a34cab5384..1b8fb42520 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java @@ -15,6 +15,7 @@ */ package io.javaoperatorsdk.operator.sample.dependent; +import java.nio.charset.StandardCharsets; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -121,7 +122,8 @@ public void delete(MySQLSchema primary, Context context) { } public static String decode(String value) { - return new String(Base64.getDecoder().decode(value.getBytes())); + return new String( + Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); } @Override diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SecretDependentResource.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SecretDependentResource.java index 6afebd8535..23e176713d 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SecretDependentResource.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SecretDependentResource.java @@ -15,6 +15,7 @@ */ package io.javaoperatorsdk.operator.sample.dependent; +import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Set; @@ -43,7 +44,7 @@ public class SecretDependentResource extends KubernetesDependentResource(); configProviders.add(new EnvVarConfigProvider()); - configProviders.add(new YamlConfigProvider(Path.of("/config/config.yaml"))); + var configPath = System.getenv().getOrDefault("CONFIG_PATH", "/config/config.yaml"); + configProviders.add(new YamlConfigProvider(Path.of(configPath))); var configLoader = new ConfigLoader(new AggregatePriorityListConfigProvider(configProviders)); Metrics metrics = initOTLPMetrics(isLocal()); diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java index d2fa9a021f..de4ad180a2 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/TomcatReconciler.java @@ -51,7 +51,9 @@ public UpdateControl reconcile(Tomcat tomcat, Context context) { "Updating status of Tomcat {} in namespace {} to {} ready replicas", tomcat.getMetadata().getName(), tomcat.getMetadata().getNamespace(), - tomcat.getStatus() == null ? 0 : tomcat.getStatus().getReadyReplicas()); + tomcat.getStatus() == null + ? Integer.valueOf(0) + : tomcat.getStatus().getReadyReplicas()); return UpdateControl.patchStatus(updatedTomcat); }) .orElseGet(UpdateControl::noUpdate); diff --git a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java index 5d362113ba..9ab98d84c2 100644 --- a/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java +++ b/sample-operators/tomcat-operator/src/main/java/io/javaoperatorsdk/operator/sample/WebappReconciler.java @@ -16,6 +16,7 @@ package io.javaoperatorsdk.operator.sample; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; import java.util.Set; @@ -252,7 +253,7 @@ public void onFailure(Throwable t, Response response) { @Override public void onClose(int code, String reason) { log.debug("Exit with: {} and with reason: {}", code, reason); - data.complete(baos.toString()); + data.complete(baos.toString(StandardCharsets.UTF_8)); } } } diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml new file mode 100644 index 0000000000..f6107ac4ea --- /dev/null +++ b/spotbugs-exclude.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From b06f7503010606e91f833af3a0da42c6ca9c0e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Attila=20M=C3=A9sz=C3=A1ros?= Date: Fri, 29 May 2026 16:34:37 +0200 Subject: [PATCH 2/2] fix from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Attila Mészáros --- .../operator/sample/dependent/SchemaDependentResource.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java index 1b8fb42520..c03f7cced5 100644 --- a/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java +++ b/sample-operators/mysql-schema/src/main/java/io/javaoperatorsdk/operator/sample/dependent/SchemaDependentResource.java @@ -122,8 +122,7 @@ public void delete(MySQLSchema primary, Context context) { } public static String decode(String value) { - return new String( - Base64.getDecoder().decode(value.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); + return new String(Base64.getDecoder().decode(value), StandardCharsets.UTF_8); } @Override