I use a JSF 2.2 and a Primefaces 5.3. I'd like to save a uploaded file on a disk. Below you can see how I try to do this. When I push a Send
button I get a java.nio.file.NoSuchFileException
exception (at the end of my post I also put a full stacktrace):
ERROR [stderr] (default task-24) java.nio.file.NoSuchFileException: [PATH]\Wildfly_10\WILDFLY_HOME\standalone\tmp\MasterProject.war\undertow1357918758070690245upload
When I trace the stacktrace, I see that the exception is caused by this line (I think so):
try(InputStream input = uploadFile.getInputstream()){
It's strange for me. I can get the name of the uploaded file (by uploadFile.getFileName()
) but I can't get the size of the file (by uploadFile.getSize()
) and I can't get the InputStream
(by uploadFile.getInputstream()
). In both cases I get the NoSuchFileException
exception.
Additional information: I've to upload the large files (i.e. 200 MB or more). Of course I get the same exception when I upload the small file.
Have you got any idea why have I got this exception and how can I fix this issue?
This's part of the page where I upload the file:
<h:form>
<p:growl id="messages" showDetail="true" />
<p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign">
<p:outputLabel for="file" value="File:" />
<p:fileUpload id="file" fileLimit="1"
fileUploadListener="#{dataController.handleFileUpload}"
mode="advanced" dragDropSupport="true" sizeLimit="1000000000"
uploadLabel="Upload" cancelLabel="Delete" allowTypes="/(\.|\/)(csv|binetflow)$/" />
<p:commandButton id="buttonSend" value="Send"
action="#{dataController.send()}" update="messages"/>
</p:panelGrid>
</h:form>
This's the CDI bean which is the controller for the above page:
@Named
@ViewScoped
public class DataController implements Serializable {
private static final long serialVersionUID = 1383572529241805730L;
public void handleFileUpload(FileUploadEvent event){
uploadFile=event.getFile();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded"));
}
public void send(){
try(InputStream input = uploadFile.getInputstream()){
Path folder=Paths.get("F:/Files");
String filename = FilenameUtils.getBaseName(uploadFile.getFileName());
String extension = FilenameUtils.getExtension(uploadFile.getFileName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", "Uploaded file successfully saved in " + file));
} catch (IOException e1) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", null));
e1.printStackTrace();
}
}
private UploadedFile uploadFile;
}
This's the full stacktrace:
10:40:45,822 ERROR [stderr] (default task-24) java.nio.file.NoSuchFileException: [PATH]\Wildfly_10\WILDFLY_HOME\standalone\tmp\MasterProject.war\undertow1357918758070690245upload
10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
10:40:45,823 ERROR [stderr] (default task-24) at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
10:40:45,823 ERROR [stderr] (default task-24) at java.nio.file.Files.newByteChannel(Files.java:361)
10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.Files.newByteChannel(Files.java:407)
10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
10:40:45,824 ERROR [stderr] (default task-24) at java.nio.file.Files.newInputStream(Files.java:152)
10:40:45,824 ERROR [stderr] (default task-24) at io.undertow.servlet.spec.PartImpl.getInputStream(PartImpl.java:63)
10:40:45,824 ERROR [stderr] (default task-24) at org.primefaces.model.NativeUploadedFile.getInputstream(NativeUploadedFile.java:45)
10:40:45,824 ERROR [stderr] (default task-24) at com.system.controller.DataController.send(DataController.java:163)
10:40:45,824 ERROR [stderr] (default task-24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
10:40:45,825 ERROR [stderr] (default task-24) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
10:40:45,825 ERROR [stderr] (default task-24) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
10:40:45,825 ERROR [stderr] (default task-24) at java.lang.reflect.Method.invoke(Method.java:498)
10:40:45,825 ERROR [stderr] (default task-24) at javax.el.ELUtil.invokeMethod(ELUtil.java:308)
10:40:45,825 ERROR [stderr] (default task-24) at javax.el.BeanELResolver.invoke(BeanELResolver.java:415)
10:40:45,825 ERROR [stderr] (default task-24) at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256)
10:40:45,825 ERROR [stderr] (default task-24) at com.sun.el.parser.AstValue.invoke(AstValue.java:285)
10:40:45,825 ERROR [stderr] (default task-24) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
10:40:45,826 ERROR [stderr] (default task-24) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
10:40:45,826 ERROR [stderr] (default task-24) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
10:40:45,826 ERROR [stderr] (default task-24) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
10:40:45,826 ERROR [stderr] (default task-24) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UICommand.broadcast(UICommand.java:315)
10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
10:40:45,827 ERROR [stderr] (default task-24) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
10:40:45,827 ERROR [stderr] (default task-24) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
10:40:45,828 ERROR [stderr] (default task-24) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
10:40:45,828 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
10:40:45,829 ERROR [stderr] (default task-24) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
10:40:45,829 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
10:40:45,830 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
10:40:45,831 ERROR [stderr] (default task-24) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
10:40:45,831 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
10:40:45,832 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
10:40:45,833 ERROR [stderr] (default task-24) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
10:40:45,833 ERROR [stderr] (default task-24) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
10:40:45,833 ERROR [stderr] (default task-24) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
10:40:45,834 ERROR [stderr] (default task-24) at java.lang.Thread.run(Thread.java:745)
I noticed something new. If I move the contents of the send()
method to the handleFileUpload()
method (the code below) - the file is saved on the disk:
@Named
@ViewScoped
public class DataController implements Serializable {
private static final long serialVersionUID = 1383572529241805730L;
public void handleFileUpload(FileUploadEvent event){
uploadFile=event.getFile();
try(InputStream input = uploadFile.getInputstream()){
Path folder=Paths.get("F:/Files");
String filename = FilenameUtils.getBaseName(uploadFile.getFileName());
String extension = FilenameUtils.getExtension(uploadFile.getFileName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", "Uploaded file successfully saved in " + file));
} catch (IOException e1) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR", null));
e1.printStackTrace();
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded"));
}
public void send(){
}
private UploadedFile uploadFile;
}
But I'd like to save the uploaded file on the disk if the user push the Send
button, not earlier (i.e. not when the user push the Upload
button) so it's necessary to save the file in send()
method.
I also noticed that when I use a simple mode of the <p:fileUpload>
component (the modified form below), everything work (i.e. the file is saved when the user push the button). I had to create getter and setter for the uploadFile
object in the DataController
bean to use #{dataController.uploadFile}
. I had to add the enctype="multipart/form-data"
attribute to the <h:form>
component either (without this attribute it isn't work).
<h:form enctype="multipart/form-data">
<p:growl id="messages" showDetail="true" />
<p:panelGrid id="panel" columns="2" styleClass="ui-noborder" columnClasses="rightalign,leftalign">
<p:outputLabel for="file" value="File:" />
<p:fileUpload id="file" value="#{dataController.uploadFile}" mode="simple" skinSimple="true" sizeLimit="1000000000" allowTypes="/(\.|\/)(csv|binetflow)$/"/>
<p:commandButton value="Submit" ajax="false" actionListener="#{dataController.send()}" disabled="false" />
</p:panelGrid>
</h:form>
The problem of this solution is: I need the advanced mode of the <p:fileUpload>
component.
I don't understand why I can't access to the uploaded file in the send()
method when I use the advanced mode. I use the @ViewScoped
scope so it should work.
uploadFile.getInputstream() throws java.nio.file.NoSuchFileException
Your concrete problem is caused because you're attempting to read an uploaded file which was uploaded in a previous request. A bit decent container will clean up all temporary data associated with a HTTP request when the HTTP request finishes. This apparently also covers non-read uploaded files in case of WildFly (not sure how others behave though).
Your best bet is directly save them anyway, if necessary in some temporary location. Then, in the final action method, move/rename them to the desired permanent location/name. In order to cleanup "forgotten" files for the case the enduser never invokes the final action method after having uploaded a bunch of files, your best bet is to keep track of all those File
s in a session scoped bean and perform file.delete()
in @PreDestroy
annotated method. A concrete example can be found here: How to handle and delete "forgotten" uploaded files?
If the upload form is view scoped, and you're using OmniFaces, then you can alternatively also use OmniFaces CDI @ViewScoped
whose @PreDestroy
will already run when the user unloads the page by a navigation or close of tab/window.
I forgot to add the implementation of the selected answer so I'm doing it now. Based on one of the solution given by @BalusC:
UserFileManager
bean (the code below) which manages the unconfirmed files and deletes them if the session is expired. UserFileManager
to the DataController
bean. try catch
from send()
method to the handleFileUpload()
method, so at the moment the file is saved on the disk when the user pushes the Upload
button. userFileManager.addUnconfirmedUploadedFile(file)
in handleFileUpload()
method. Now we're sure that the file will be deleted (when the session expires) if the user doesn't push the Send
button.userFileManager.confirmUploadedFile(file)
in send()
method. Now we're sure that the user wants to keep the file on the disk so we delete this file from the list of the unconfirmed files.Note: Your uploaded files are stored in WildFly server's writable /standalone/data/upload
folder or in /standalone/data
folder if something went wrong during the creation of the upload
folder.
This's the modified DataController
bean:
@Named
@ViewScoped
public class DataController implements Serializable {
private static final long serialVersionUID = 1383572529241805730L;
public void handleFileUpload(FileUploadEvent event){
uploadFile=event.getFile();
try(InputStream input = uploadFile.getInputstream()){
Path folder=Paths.get(System.getProperty("jboss.server.data.dir"),"upload");
if(!folder.toFile().exists()){
if(!folder.toFile().mkdirs()){
folder=Paths.get(System.getProperty("jboss.server.data.dir"));
}
}
String filename = FilenameUtils.getBaseName(uploadFile.getFileName());
String extension = FilenameUtils.getExtension(uploadFile.getFileName());
Path filePath = Files.createTempFile(folder, filename + "-", "." + extension);
Files.copy(input, filePath, StandardCopyOption.REPLACE_EXISTING);
userFileManager.addUnconfirmedUploadedFile(filePath.toFile());
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Successful", event.getFile().getFileName() + " is uploaded"));
} catch (IOException e1) {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "ERROR I/O", "Code of the error: DC1"));
e1.printStackTrace();
}
}
public void send(){
userFileManager.confirmUploadedFile(filePath.toFile());
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The data has been added.", ""));
}
@Inject
private UserFileManager userFileManager;
private UploadedFile uploadFile;
}
This's the UserFileManager
bean which was created by @BalusC here:
@SessionScoped
public class UserFileManager implements Serializable {
private static final long serialVersionUID = -5410871255899363212L;
/**
* Initialization of list.
*/
@PostConstruct
public void init(){
unconfirmedUploadedFiles = new ArrayList<>();
}
/**
* Adding the unconfirmed file to the list.
* @param unconfirmedUploadedFile unconfirmed file.
*/
public void addUnconfirmedUploadedFile(File unconfirmedUploadedFile) {
unconfirmedUploadedFiles.add(unconfirmedUploadedFile);
}
/**
* Deleting the confirmed file from the list.
* @param confirmedUploadedFile confirmed file.
*/
public void confirmUploadedFile(File confirmedUploadedFile) {
unconfirmedUploadedFiles.remove(confirmedUploadedFile);
}
/**
* Deleting unconfirmed files from the disk if the session is expired.
*/
@PreDestroy
public void destroy() {
for (File unconfirmedUploadedFile : unconfirmedUploadedFiles) {
unconfirmedUploadedFile.delete();
}
}
//The list which stores the unconfirmed files.
private List<File> unconfirmedUploadedFiles;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With