On Mon, 2025-04-28 at 08:31 +0200, Emmanuel Bourg wrote:
> On 27/04/2025 21:31, Ben Hutchings wrote:
> 
> > So then I compared the build dependency versions in the last good and
> > first bad snapshots, and tried upgrading the Java packages one by one.
> > The result was that libsurefire-java (= 2.22.3-3) made the difference:
> > 
> > Now, the test failures have tracebacks like:
> > 
> > java.lang.IllegalStateException: Recursive update
> > 
> > So I don't know that this is really a regression in surefire, or whether
> > the plugin that was removed just happened to interact with the bug and
> > changed it from a deadlock into an exception.
> 
> Thank you for the analysis Ben, I confirm surefire 2.22.3-3 causes the 
> tests to hang.
> 
> So there are two issues here, the loop between slf4j and 
> commons-logging, and the test freeze.
> 
> * the loop is caused by a new slf4j log factory introduced in 
> commons-logging 1.3.0. Usually slf4j takes over commons-logging by 
> replacing its classes (in the org.slf4j:jcl-over-slf4j artifact) and 
> both libraries are not on the classpath at the same time. So we should 
> be able to ignore it, either by disabling the slf4j tests for now, or by 
> disabling the log factory in commons-logging.

It turns out that it is possible to do this from the slf4j side, by
replacing the Slf4jLogFactory class.  See the attached patch.  With the
patch applied *and libsurefire-java downgraded*, the tests pass.

> * the test freeze is surprising, the test threads seem to be idling for 
> an unknown reason. maven-surefire-report-plugin 2.22.3 isn't compatible 
> with maven-reporting-api 4.0 used by the version of Maven in Debian. 
> We'll have to upgrade surefire to the latest version to fix this, but 
> this won't be possible before Forky (too much impact on other Maven 
> components). I recommend disabling the slf4j tests for now.

That would be unfortunate.  And I wonder if we wouldn't end up with the
same issue in sfl4j's reverse-dependencies.

Ben.

-- 
Ben Hutchings
Kids!  Bringing about Armageddon can be dangerous.  Do not attempt it
in your own home. - Terry Pratchett and Neil Gaiman, `Good Omens'
From: Ben Hutchings <b...@decadent.org.uk>
Date: Mon, 28 Apr 2025 15:39:59 +0200
Subject: slf4j-jcl: Replace commons-logging Slf4jLogFactory class to
 prevent recursion
Bug-Debian: https://bugs.debian.org/1060960

Starting with commons-logging 1.3.0,
org.apache.commns.logging.LogFactory.getLogger tries to instantiate an
sfl4j logger, which results in mutual recursion wehn using slf4j-jcl.

Add a replacement for the
org.apache.commns.logging.impl.Slf4jLogFactory class whose constructor
always throws, forcing commons-logging to fall back to an alternative
logging back-end.
---
 .../commons/logging/impl/Slf4jLogFactory.java | 73 +++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 slf4j-jcl/src/main/java/org/apache/commons/logging/impl/Slf4jLogFactory.java

diff --git a/slf4j-jcl/src/main/java/org/apache/commons/logging/impl/Slf4jLogFactory.java b/slf4j-jcl/src/main/java/org/apache/commons/logging/impl/Slf4jLogFactory.java
new file mode 100644
index 00000000..dbcf3d6f
--- /dev/null
+++ b/slf4j-jcl/src/main/java/org/apache/commons/logging/impl/Slf4jLogFactory.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2025 Ben Hutchings
+ *
+ * Licensed 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.commons.logging.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogConfigurationException;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>
+ * Concrete subclass of {@link LogFactory} which always throws.  This
+ * is needed to avoid mutual recursion between JCLLoggerFactory.getLog
+ * and LogFactory.getLogger.
+ */
+public class Slf4jLogFactory extends LogFactory {
+    public Slf4jLogFactory() {
+        throw new IllegalStateException(
+	    "Preventing recursion between JCLLoggerFactory.getLog and LogFactory.getLogger");
+    }
+
+    private static Object unreachable() {
+	throw new IllegalStateException("should be unreachable");
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+	return unreachable();
+    }
+
+    @Override
+    public String[] getAttributeNames() {
+	return (String[])unreachable();
+    }
+
+    @Override
+    public Log getInstance(Class<?> clazz) throws LogConfigurationException {
+	return (Log)unreachable();
+    }
+
+    @Override
+    public Log getInstance(String name) throws LogConfigurationException {
+	return (Log)unreachable();
+    }
+
+    @Override
+    public void release() {
+	unreachable();
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+	unreachable();
+    }
+
+    @Override
+    public void setAttribute(final String name, final Object value) {
+	unreachable();
+    }
+}

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to