Hi Lukasz, thanks for your appreciated comments. I would like to explain in more detail what we have done to try to find the problem and solve it. Here the context:
This is my environment: - Struts Version: 7.0.3 - Java Version: 17 - Servlet Container: Apache Tomcat 10.1.36 - Key Dependencies (pom): - struts2-core:7.0.3 - struts2-convention-plugin:7.0.3 - struts2-json-plugin:7.0.3 - jakarta.servlet-api:5.0.0 - log4j-core:2.17.2 - Enforced exclusions: javax.servlet:*, javax.activation:* We've created a basic Maven project (standard archetype) with a simple file upload form containing: - 4 regular text fields (working correctly with @StrutsParameter(depth=0)) - 1 file upload field (<input type="file" name="upload">) This is my basic jsp: <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html> <html> <head> <title>File upload result</title> </head> <body> <h1>Hola Mundo desde la tierra...</h1> <form action="hello" method="post" enctype="multipart/form-data"> <input type="text" name="name"/> <input type="text" name="lastname"/> <input type="text" name="gender"/> <input type="text" name="age"/> <input type="file" name="*upload*"/> <input type="submit" value="Subir" /> </form> </body> </html> Expected Behavior: - When implementing UploadedFilesAware, the framework should: - Detect multipart requests - Process uploaded files through withUploadedFiles(List<UploadedFile>) - Make files available to the action Where my action looks like: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ActionSupport; import org.apache.struts2.action.UploadedFilesAware; import org.apache.struts2.dispatcher.multipart.UploadedFile; import org.apache.struts2.interceptor.parameter.StrutsParameter; public class HelloAction extends ActionSupport implements UploadedFilesAware { private static final long serialVersionUID = 1L; private Logger logger = LogManager.getLogger(HelloAction.class); private UploadedFile upload; private String uploadFileName; private String uploadContentType; @StrutsParameter(depth = 0) public String name; @StrutsParameter(depth = 0) public String lastname; @StrutsParameter(depth = 0) public String gender; @StrutsParameter(depth = 0) public String age; @Override public String execute() { logger.info("Executing execute method..." + this.uploadFileName); return SUCCESS; } public UploadedFile getUpload() { return upload; } public void setUpload(UploadedFile upload) { this.upload = upload; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public Logger getLogger() { return logger; } public void setLogger(Logger logger) { this.logger = logger; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public void withUploadedFiles(List<UploadedFile> uploadedFiles) { if (uploadedFiles != null && !uploadedFiles.isEmpty()) { UploadedFile firstFile = uploadedFiles.get(0); // Take the file this.upload = firstFile; this.uploadFileName = firstFile.getName(); // String this.uploadContentType = firstFile.getContentType(); // String logger.info("File name: " + uploadFileName); } } Actual Behavior: Despite proper multipart request detection: The interceptor finds the request wrapper: 2025-05-31 DEBUG ActionFileUploadInterceptor:200 - Found multipart request: MultiPartRequestWrapper *Our custom DebugMultiPartRequest confirms file presence:* 2025-05-31 12:00:13 INFO DebugMultiPartRequest:26 - Todos los parámetros del request: 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - nombre: Jesus 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - apellido: Moreno 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - sexo: M 2025-05-31 12:00:13 INFO DebugMultiPartRequest:30 - - edad: 50 *2025-05-31 12:00:13 INFO DebugMultiPartRequest:39 - Part 'upload' encontrada:2025-05-31 12:00:13 INFO DebugMultiPartRequest:40 - - Nombre: Adaware.jpg2025-05-31 12:00:13 INFO DebugMultiPartRequest:41 - - Tamaño: 25546*2025-05-31 12:00:13 DEBUG InstantiatingNullHandler:106 - Entering nullPropertyValue [target=[org.apache.struts2.text.DefaultTextProvider@2a580722], property=struts] 2025-05-31 12:00:13 DEBUG ConfigurationManager:180 - Checking ConfigurationProviders for reload. 2025-05-31 12:00:13 DEBUG InstantiatingNullHandler:106 - Entering nullPropertyValue [target=[org.apache.struts2.text.DefaultTextProvider@2a580722], property=struts] 2025-05-31 12:00:13 DEBUG DefaultActionProxy:88 - Creating an DefaultActionProxy for namespace [/] and action name [hello] 2025-05-31 12:00:14 DEBUG DefaultActionInvocation:310 - Executing conditional interceptor: ActionFileUploadInterceptor 2025-05-31 12:00:14 DEBUG ActionFileUploadInterceptor:200 - Found multipart request: MultiPartRequestWrapper But the interceptor reports: *2025-05-31 12:00:14 DEBUG ActionFileUploadInterceptor:179 - No files have been uploaded/accepted* Investigation Steps Taken: 1. Verified all prerequisites: - Form uses enctype="multipart/form-data" - Using DTD 6.0 as suggested - Regularly cleaning Tomcat's work directory - Confirmed Jakarta EE 9+ compatibility 2. Created extensive debug instrumentation: - Custom DebugMultiPartRequest shows files reach the server - Interceptor-level logging confirms the disconnect Technical Findings: 1. The MultiPartRequestWrapper appears to lose file references between: - Initial parsing (where files are detectable via raw Part API) - Interceptor processing phase 2. Key suspicious behavior: - getFileParameterNames() returns empty enumeration - Despite request.getPart("upload") working correctly Finally As you suggested, we've: - Consistently cleaned deployment directories - Verified DTD compatibility - Followed migration guides carefully - Yet the team remains persistent in investigating this apparent framework bug rather than working around it. # Summary Files are received by the server (confirmed via custom DebugMultiPartRequest) but ActionFileUploadInterceptor fails to process them via UploadedFilesAware interface in Struts 7.0.3 (Jakarta EE 9/Tomcat 10 environment). This is my custom DebugMultiPartRequest: public class DebugMultiPartRequest extends JakartaMultiPartRequest { private static final Logger logger = LogManager.getLogger(DebugMultiPartRequest.class); @Override public void parse(HttpServletRequest request, String saveDir) throws IOException { super.parse(request, saveDir); // Procesa el request normalmente logger.info("=== DebugMultiPartRequest (Struts 7) ==="); // 1. Listar TODOS los parámetros del request (no solo archivos) logger.info("Todos los parámetros del request:"); Enumeration<String> paramNames = request.getParameterNames(); while (paramNames.hasMoreElements()) { String name = paramNames.nextElement(); logger.info(" - " + name + ": " + request.getParameter(name)); } // 2. Listar partes multipart (alternativa para Jakarta EE 9+) if (request instanceof jakarta.servlet.http.HttpServletRequest jakartaRequest) { jakarta.servlet.http.Part part; try { part = jakartaRequest.getPart("upload"); if (part != null) { * logger.info <http://logger.info>("Part 'upload' encontrada:"); logger.info <http://logger.info>(" - Nombre: " + part.getSubmittedFileName()); logger.info <http://logger.info>(" - Tamaño: " + part.getSize());* } else { logger.info("❌ Parte 'upload' NO encontrada en el request."); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServletException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Nombre de tu campo } } } After this investigation, we appreciated your feedback if there's any version where this issue we've identified has been resolved, or how we can make file uploads work properly. Regards JMC El mié, 14 may 2025 a las 0:09, Lukasz Lenart (<lukaszlen...@apache.org>) escribió: > sob., 10 maj 2025 o 07:09 Jesus Moreno <jesus...@gmail.com> napisał(a): > > 2025-05-09 01:00:25 WARN File:79 - Struts has detected a file upload UI > tag > > (s:file) being used without a form set to method 'POST' > > (Despite <s:form method="POST" enctype="multipart/form-data"> being > > correctly declared) > > This can be related to cached JSP files, please remove them from the > container "temp" folder or "work" folder. > > https://cwiki.apache.org/confluence/display/WW/Struts+6.x.x+to+7.x.x+migration#Struts6.x.xto7.x.xmigration-Temp/WorkdirectoryofApplicationServer/ServletContainer > > > struts.xml: > > <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts > > Configuration 6.5//EN" > > "https://struts.apache.org/dtds/struts-6.5.dtd"> > > There is no such version as 6.5, use 6.0 instead > https://struts.apache.org/dtds/ > > > Cheers > Łukasz > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@struts.apache.org > For additional commands, e-mail: user-h...@struts.apache.org > > -- Ing. Jesús Moreno Canseco Tel.: (55)6377-0600 Cel.: 55-1409-5156 jesus...@gmail.com <jmor...@ismarts.com.mx>