[ https://issues.apache.org/jira/browse/WW-5546?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17950466#comment-17950466 ]
Jesus M commented on WW-5546: ----------------------------- Sure, Sorry about that. It is I am migrating from 2.5 to 7.x. This is because I have an app on production and we are taking the time to migrate this app to the latest version. I wanted to thoroughly verify what you explained about the new 'UploadedFilesAware' interface. For this reason, I created a minimal test example to validate the implementation once again - but it still doesn't work. Previously, I believed there were two possible approaches: # Using AJAX with direct setters in the VO, or # Implementing the UploadedFilesAware interface. While I initially relied on the first approach, I also tested the second option (following the examples), but neither worked. Since you've confirmed that the only supported method now is using UploadedFilesAware, once again I focused entirely on creating a basic project to ensure proper functionality before migrating it to my main application. However, I still can't get it to work." Principal points in my Action: public class HelloAction extends ActionSupport implements UploadedFilesAware { private Logger logger = LogManager.getLogger(HelloAction.class); private List<String> actionErrors; // Mensajes globales de error private List<String> actionMessages; // Mensajes de éxito public UploadedFile upload; private String contentType; public String fileName; private String originalName; @Override public String execute() { if (upload == null) { logger.info("File has an error"); addActionError("We dont have any file :("); return INPUT; } try { // we gonna process the file... logger.info("Success uploading file... " + fileName); return SUCCESS; } catch (Exception e) { addActionError("Error al procesar el archivo: " + e.getMessage()); return ERROR; } } @Override public void withUploadedFiles(List<UploadedFile> uploadedFiles) { if (!uploadedFiles.isEmpty()) { this.upload = uploadedFiles.get(0); this.fileName = upload.getName(); this.contentType = upload.getContentType(); this.originalName = upload.getOriginalName(); } } } My Struts.xml is: <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 6.5//EN" "https://struts.apache.org/dtds/struts-6.5.dtd"> <struts> <constant name="struts.multipart.parser" value="jakarta" /> <constant name="struts.multipart.maxSize" value="10485760" /> <!-- 10MB --> <constant name="struts.multipart.saveDir" value="C:\\temp"/> <!-- Ruta absoluta --> <package name="default" extends="struts-default"> <action name=""><result>/hello.jsp</result></action> <action name="hello" class="mx.com.jeser.ejemplo.actions.HelloAction"> <interceptor-ref name="actionFileUpload" /> <interceptor-ref name="basicStack" /> <result name="success">/success.jsp</result> <result name="input">/input.jsp</result> <result name="error">/error.jsp</result> </action> </package></struts> My init jsp: <%@ page contentType="text/html; charset=UTF-8" %> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html> <html> <head> <title>Struts 7.0.3</title> </head> <body> <s:form action="hello" method="POST" enctype="multipart/form-data"> <s:file name="upload" label="Select a file"/> <s:submit value="Subir"/> </s:form> </body></html> Result notes: * Basically in the action I can see upload is null * The trace: * 2025-05-09 01:00:25 DEBUG Dispatcher:1036 - Support for multipart request is enabled: true 2025-05-09 01:00:25 DEBUG Dispatcher:1054 - Validating if this is a proper Multipart request. Request is POST: true and ContentType matches pattern (^multipart/form-data(?:\s*;\s*boundary=[0-9a-zA-Z'"()+_,\-./:=?]\{1,70})?(?:\s*;\s*charset=[a-zA-Z\-0-9]\{3,14})?): true 2025-05-09 01:00:25 DEBUG Dispatcher:1012 - Wrapping multipart request with: MultiPartRequestWrapper 2025-05-09 01:00:25 DEBUG Dispatcher:926 - saveDir=C:\\temp 2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:66 - Using file save directory: C:\temp 2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:69 - Sets minimal buffer size to always write file to disk 2025-05-09 01:00:25 DEBUG JakartaMultiPartRequest:72 - Using charset: UTF-8 2025-05-09 01:00:25 DEBUG AbstractMultiPartRequest:196 - Applies max size: 10485760 to file upload request 2025-05-09 01:00:25 DEBUG AbstractMultiPartRequest:200 - Applies max files number: 256 to file upload request 2025-05-09 01:00:25 DEBUG InstantiatingNullHandler:106 - Entering nullPropertyValue [target=[org.apache.struts2.text.DefaultTextProvider@55a6d16f], property=struts] 2025-05-09 01:00:25 DEBUG InstantiatingNullHandler:106 - Entering nullPropertyValue [target=[org.apache.struts2.text.DefaultTextProvider@55a6d16f], property=struts] 2025-05-09 01:00:25 DEBUG DefaultActionProxy:88 - Creating an DefaultActionProxy for namespace [/] and action name [hello] 2025-05-09 01:00:25 DEBUG DefaultActionInvocation:310 - Executing conditional interceptor: ActionFileUploadInterceptor 2025-05-09 01:00:25 DEBUG ActionFileUploadInterceptor:200 - Found multipart request: MultiPartRequestWrapper 2025-05-09 01:00:25 DEBUG ActionFileUploadInterceptor:179 - No files have been uploaded/accepted * Inspect class ActionFileUploadInterceptor.class acceptedFiles parameter always is empty, that's reason message "No files have been uploaded/accepted". I assume there is a problem with the loading. * Always is present this warning: 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'. This is probably an error! But, as you can see method is there. * I have a question: Does the Struts Parameter notation also apply to this type of sending? I would sincerely appreciate some assistance to properly understand this process, as the implementation isn't working according to the official documentation! > NPE in AbstractFileUploadInterceptor > ------------------------------------ > > Key: WW-5546 > URL: https://issues.apache.org/jira/browse/WW-5546 > Project: Struts 2 > Issue Type: Bug > Components: Core, Core Interceptors > Affects Versions: 6.7.4 > Reporter: Barta Tamás > Assignee: Lukasz Lenart > Priority: Major > Fix For: 6.8.0, 7.1.0 > > Time Spent: 1.5h > Remaining Estimate: 0h > > I got the following exception: > > {code:java} > java.lang.NullPointerException: Cannot invoke "java.io.File.length()" because > "this.file" is null > at > deployment.deployment.ear//org.apache.struts2.dispatcher.multipart.StrutsUploadedFile.length(StrutsUploadedFile.java:52) > at > deployment.deployment.ear//org.apache.struts2.interceptor.AbstractFileUploadInterceptor.acceptFile(AbstractFileUploadInterceptor.java:133) > at > deployment.deployment.ear//org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:232) > at > deployment.deployment.ear//com.opensymphony.xwork2.interceptor.AbstractInterceptor.intercept(AbstractInterceptor.java:36) > at > deployment.deployment.ear//com.opensymphony.xwork2.DefaultActionInvocation.executeConditional(DefaultActionInvocation.java:303) > {code} > I think the bug is in AbstractFileUploadInterceptor: > > > {code:java} > if (file.getContent() == null) { > String errMsg = getTextMessage(action, > STRUTS_MESSAGES_ERROR_UPLOADING_KEY, new String[]{originalFilename}); > > errorMessages.add(errMsg); > LOG.warn(errMsg); > } > if (maximumSize != null && maximumSize < file.length()) { {code} > If file.getContent() is null (which means StrutsUploadedFile.file is null), > then warning is logged but there is no "return false" so execution continues > and file.length() will throw NPE as file is null in StrutsUploadedFile. > -- This message was sent by Atlassian Jira (v8.20.10#820010)