This is an automated email from the ASF dual-hosted git repository.
mattcasters pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new 65b08dc32b move to environment so it's applied everywhere, fixes #7297
(#8572)
65b08dc32b is described below
commit 65b08dc32b9384a6acabaf7aa1c69f7014eb8d9c
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Thu Sep 24 13:25:53 2026 +0200
move to environment so it's applied everywhere, fixes #7297 (#8572)
---
.../java/org/apache/hop/core/HopEnvironment.java | 34 +++++++----
.../src/main/java/org/apache/hop/run/HopRun.java | 21 -------
.../hop/core/HopEnvironmentJulLoggersTest.java | 69 ++++++++++++++++++++++
3 files changed, 92 insertions(+), 32 deletions(-)
diff --git a/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
b/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
index c55464ac3c..50f7db499f 100644
--- a/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
+++ b/engine/src/main/java/org/apache/hop/core/HopEnvironment.java
@@ -281,26 +281,38 @@ public class HopEnvironment {
}
/**
- * Strong reference to prevent java.util.logging.LogManager from
garbage-collecting the logger.
+ * Verbose third-party JUL loggers that are defaulted to WARNING. The JUL
LogManager only holds
+ * weak references to loggers: a level set on a logger nobody references is
lost at the next
+ * garbage collection. That is why these are kept in a static field.
+ *
+ * <ul>
+ * <li>org.apache.hc.client5.http.wire: raw HTTP byte dumps (#8340)
+ * <li>com.microsoft.sqlserver.jdbc: MS SQL Server driver INFO messages,
such as "Discarding
+ * extra metadata which can be a result of SHOWPLAN settings", written
to stderr (#7297)
+ * </ul>
*/
@SuppressWarnings("java:S3985")
- private static final java.util.logging.Logger JUL_WIRE_LOGGER =
- java.util.logging.Logger.getLogger("org.apache.hc.client5.http.wire");
+ private static final List<java.util.logging.Logger> JUL_VERBOSE_LOGGERS =
+ List.of(
+
java.util.logging.Logger.getLogger("org.apache.hc.client5.http.wire"),
+ java.util.logging.Logger.getLogger("com.microsoft.sqlserver.jdbc"));
/**
* Default verbose third-party loggers to a non-debug level to prevent
dumping raw network bytes
- * to the console while preserving explicitly configured debug settings.
+ * or driver chatter to the console while preserving explicitly configured
levels.
*/
- private static void silenceVerboseThirdPartyLoggers() {
+ static void silenceVerboseThirdPartyLoggers() {
String wireLoggerName = "org.apache.hc.client5.http.wire";
- // Silence JUL logger to prevent verbose byte dumps on backends printing
via java.util.logging
- try {
- if (JUL_WIRE_LOGGER.getLevel() == null) {
- JUL_WIRE_LOGGER.setLevel(java.util.logging.Level.WARNING);
+ // Silence JUL loggers which would otherwise print to stderr via the
default ConsoleHandler
+ for (java.util.logging.Logger julLogger : JUL_VERBOSE_LOGGERS) {
+ try {
+ if (julLogger.getLevel() == null) {
+ julLogger.setLevel(java.util.logging.Level.WARNING);
+ }
+ } catch (Exception ignored) {
+ // Ignore if JUL cannot be configured
}
- } catch (Exception ignored) {
- // Ignore if JUL cannot be configured
}
// Configure Log4j2 if present on the classpath, preserving any explicit
configuration
diff --git a/engine/src/main/java/org/apache/hop/run/HopRun.java
b/engine/src/main/java/org/apache/hop/run/HopRun.java
index 161f69873d..e0655d6a20 100644
--- a/engine/src/main/java/org/apache/hop/run/HopRun.java
+++ b/engine/src/main/java/org/apache/hop/run/HopRun.java
@@ -17,8 +17,6 @@
package org.apache.hop.run;
-import java.util.logging.Level;
-import java.util.logging.Logger;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
@@ -48,12 +46,6 @@ public class HopRun extends HopRunBase implements Runnable,
IHasHopMetadataProvi
public static void main(String[] args) {
- // Silence verbose JUL loggers from third-party JDBC drivers (e.g.
Microsoft SQL Server)
- // that write INFO messages to stderr via the default ConsoleHandler. Hop
uses its own
- // logging system (HopLogStore) so this JUL output is unwanted noise.
(Fixes #7297)
- //
- silenceJulJdbcLoggers();
-
HopRun hopRun = new HopRun();
try {
@@ -152,17 +144,4 @@ public class HopRun extends HopRunBase implements
Runnable, IHasHopMetadataProvi
cmd.parseArgs(helpArgs);
}
-
- /**
- * Suppress INFO-level JUL output from third-party JDBC drivers that would
otherwise flood stderr
- * via the default {@link java.util.logging.ConsoleHandler}. Hop uses its
own logging subsystem
- * ({@link HopLogStore}) so JUL console output is unwanted noise.
- *
- * <p>This must be called early in {@link #main(String[])} — before {@link
HopEnvironment#init()}
- * — so the loggers are silenced before any driver classes are loaded.
- */
- private static void silenceJulJdbcLoggers() {
- // Microsoft SQL Server JDBC driver
(com.microsoft.sqlserver.jdbc.TDSTokenHandler et al.)
- Logger.getLogger("com.microsoft.sqlserver.jdbc").setLevel(Level.WARNING);
- }
}
diff --git
a/engine/src/test/java/org/apache/hop/core/HopEnvironmentJulLoggersTest.java
b/engine/src/test/java/org/apache/hop/core/HopEnvironmentJulLoggersTest.java
new file mode 100644
index 0000000000..8ac1f432cc
--- /dev/null
+++ b/engine/src/test/java/org/apache/hop/core/HopEnvironmentJulLoggersTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.hop.core;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+/**
+ * The JUL LogManager only keeps weak references to loggers. A level set on an
unreferenced logger
+ * is lost at the next garbage collection, after which a driver logs at the
root INFO level again
+ * (#7297). These tests force a GC before looking at the levels.
+ */
+class HopEnvironmentJulLoggersTest {
+
+ @ParameterizedTest
+ @ValueSource(
+ strings = {
+ "com.microsoft.sqlserver.jdbc.TDSTokenHandler",
+ "org.apache.hc.client5.http.wire.Something"
+ })
+ void verboseLoggersStaySilencedAfterGarbageCollection(String
childLoggerName) {
+ HopEnvironment.silenceVerboseThirdPartyLoggers();
+
+ for (int i = 0; i < 3; i++) {
+ System.gc();
+ }
+
+ Logger childLogger = Logger.getLogger(childLoggerName);
+ assertFalse(childLogger.isLoggable(Level.INFO));
+ assertTrue(childLogger.isLoggable(Level.WARNING));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"com.microsoft.sqlserver.jdbc",
"org.apache.hc.client5.http.wire"})
+ void explicitlyConfiguredLevelIsPreserved(String loggerName) {
+ Logger logger = Logger.getLogger(loggerName);
+ Level previousLevel = logger.getLevel();
+ try {
+ logger.setLevel(Level.FINE);
+
+ HopEnvironment.silenceVerboseThirdPartyLoggers();
+
+ assertEquals(Level.FINE, logger.getLevel());
+ } finally {
+ logger.setLevel(previousLevel);
+ }
+ }
+}