This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/main by this push:
new 65f9784eb WW-5792 fix(config): warn instead of silently skipping
non-public action classes
65f9784eb is described below
commit 65f9784eba12f308581b337ed8e589ec51f277a6
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Oct 24 10:23:53 2026 +0200
WW-5792 fix(config): warn instead of silently skipping non-public action
classes
verifyAction threw "is not public" inside the try whose RuntimeException
handler swallowed it, so a non-public action class only produced a
misleading INFO line. It now logs a WARN naming the class and location
and skips the constructor check, so startup behaves as before.
Failing startup is tracked in WW-5809 for 8.0.0.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../providers/XmlDocConfigurationProvider.java | 3 +-
.../struts2/config/providers/NonPublicAction.java | 29 +++++++++++++++++
.../XmlConfigurationProviderActionsTest.java | 36 ++++++++++++++++++++++
.../providers/xwork-test-action-non-public.xml | 32 +++++++++++++++++++
4 files changed, 99 insertions(+), 1 deletion(-)
diff --git
a/core/src/main/java/org/apache/struts2/config/providers/XmlDocConfigurationProvider.java
b/core/src/main/java/org/apache/struts2/config/providers/XmlDocConfigurationProvider.java
index e7e7d4066..0080d97f3 100644
---
a/core/src/main/java/org/apache/struts2/config/providers/XmlDocConfigurationProvider.java
+++
b/core/src/main/java/org/apache/struts2/config/providers/XmlDocConfigurationProvider.java
@@ -542,7 +542,8 @@ public abstract class XmlDocConfigurationProvider
implements ConfigurationProvid
Class<?> clazz = allowAndLoadClass(className);
if (objectFactory.isNoArgConstructorRequired()) {
if (!Modifier.isPublic(clazz.getModifiers())) {
- throw new ConfigurationException("Action class [" +
className + "] is not public", loc);
+ LOG.warn("Action class [{}] is not public, this will fail
at startup in Struts 8.0.0 - {}", className, loc);
+ return;
}
clazz.getConstructor();
}
diff --git
a/core/src/test/java/org/apache/struts2/config/providers/NonPublicAction.java
b/core/src/test/java/org/apache/struts2/config/providers/NonPublicAction.java
new file mode 100644
index 000000000..6a54551db
--- /dev/null
+++
b/core/src/test/java/org/apache/struts2/config/providers/NonPublicAction.java
@@ -0,0 +1,29 @@
+/*
+ * 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.struts2.config.providers;
+
+import org.apache.struts2.action.Action;
+
+class NonPublicAction implements Action {
+
+ public String execute() {
+ return SUCCESS;
+ }
+
+}
diff --git
a/core/src/test/java/org/apache/struts2/config/providers/XmlConfigurationProviderActionsTest.java
b/core/src/test/java/org/apache/struts2/config/providers/XmlConfigurationProviderActionsTest.java
index 076fdaa6d..a7bda3a5e 100644
---
a/core/src/test/java/org/apache/struts2/config/providers/XmlConfigurationProviderActionsTest.java
+++
b/core/src/test/java/org/apache/struts2/config/providers/XmlConfigurationProviderActionsTest.java
@@ -18,6 +18,11 @@
*/
package org.apache.struts2.config.providers;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.struts2.ObjectFactory;
import org.apache.struts2.SimpleAction;
import org.apache.struts2.config.ConfigurationException;
@@ -161,6 +166,24 @@ public class XmlConfigurationProviderActionsTest extends
ConfigurationTestBase {
}
}
+ public void testNonPublicActionWarnsAndLoads() {
+ final String filename =
"org/apache/struts2/config/providers/xwork-test-action-non-public.xml";
+ LogCapture logCapture = new LogCapture();
+ Logger logger = (Logger)
LogManager.getLogger(XmlConfigurationProvider.class);
+ logger.addAppender(logCapture);
+ logCapture.start();
+ try {
+ buildConfigurationProvider(filename);
+ } finally {
+ logCapture.stop();
+ logger.removeAppender(logCapture);
+ }
+
+
assertNotNull(configuration.getPackageConfig("default").getActionConfigs().get("NonPublic"));
+ assertTrue(logCapture.events.stream().anyMatch(event ->
event.getLevel() == Level.WARN
+ && event.getMessage().getFormattedMessage().contains("Action
class [" + NonPublicAction.class.getName() + "] is not public")));
+ }
+
public void testPackageDefaultClassRef() {
final String filename =
"org/apache/struts2/config/providers/xwork-test-actions-packagedefaultclassref.xml";
@@ -221,4 +244,17 @@ public class XmlConfigurationProviderActionsTest extends
ConfigurationTestBase {
exceptionMappings = new ArrayList<>();
this.objectFactory = container.getInstance(ObjectFactory.class);
}
+
+ private static class LogCapture extends AbstractAppender {
+ private final List<LogEvent> events = new ArrayList<>();
+
+ LogCapture() {
+ super("LogCapture", null, null, false, null);
+ }
+
+ @Override
+ public void append(LogEvent event) {
+ events.add(event.toImmutable());
+ }
+ }
}
diff --git
a/core/src/test/resources/org/apache/struts2/config/providers/xwork-test-action-non-public.xml
b/core/src/test/resources/org/apache/struts2/config/providers/xwork-test-action-non-public.xml
new file mode 100644
index 000000000..4a55fc209
--- /dev/null
+++
b/core/src/test/resources/org/apache/struts2/config/providers/xwork-test-action-non-public.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+ "https://struts.apache.org/dtds/struts-6.0.dtd">
+<struts>
+ <include file="xwork-test-beans.xml"/>
+ <package name="default">
+
+ <action name="NonPublic"
class="org.apache.struts2.config.providers.NonPublicAction"/>
+
+ </package>
+</struts>