Notes with attachments cannot be created after changing storage directory
A lean social communication platform for teams and small organizations
Brought to you by:
christempel
Originally created by: rwi
Steps to reproduce:
The logs contain the following exception
2016-07-11 15:51:43,078 ERROR http-apr-53080-exec-1 com.communote.server.core.storing.ResourceStoringManagementImpl - Content Storing failed: Error wri
ting to file content.jpg /opt/communote/data-dir/filerepository2/global/default_filesystem_connector/1468245103076_755539063/content.jpg (No such file or directory)
com.communote.server.persistence.crc.ContentRepositoryException: Error writing to file content.jpg /opt/communote/data-dir/filerepository2/global/default_filesystem_connector/1468245103076_755539063/content.jpg (No such file or directory)
at com.communote.server.core.crc.FilesystemConnector.storeContent(FilesystemConnector.java:407)
at com.communote.server.core.crc.RepositoryConnectorDelegateImpl.handleStoreContent(RepositoryConnectorDelegateImpl.java:277)
at com.communote.server.core.crc.RepositoryConnectorDelegateBase.storeContent(RepositoryConnectorDelegateBase.java:343)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java:111)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy150.storeContent(Unknown Source)
at com.communote.server.core.storing.ResourceStoringManagementImpl.storeInRepository(ResourceStoringManagementImpl.java:565)
at com.communote.server.core.storing.ResourceStoringManagementImpl.handleStoreAttachment(ResourceStoringManagementImpl.java:396)
at com.communote.server.core.storing.ResourceStoringManagementBase.storeAttachment(ResourceStoringManagementBase.java:213)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
and a lot more
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: /opt/communote/data-dir/filerepository2/global/default_filesystem_connector/1468245103076_755539063/content.jpg (No such file or directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
at com.communote.server.core.vo.content.AttachmentTO.write(AttachmentTO.java:335)
at com.communote.server.core.crc.FilesystemConnector.storeContent(FilesystemConnector.java:403)
... 132 more
View and moderate all "tickets Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Tickets"
View and moderate all "tickets Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Tickets"
Originally posted by: rwi
No simple and clean fix available.
The problem is that the new directory does not exist. The FilesystemConnector, responsible for storing the attachments on disk, creates the storage directory if it does not exist, but only during instantiation. The controller of the administration page just modifies an application property which holds the path to the storage directory and is used by the FilesystemConnector as base path. Thus, the connector is not aware that the directory changed.
Although, one could modify the connector to check whether the value changed and create the directory if needed, this isn't a clean solution because it isn't done when the path is modified by the administrator who therefore won't be informed if the creation of the directory fails.
Another approach would be to only let the FilesystemConnector read / modify the application property and expose these operations via methods which could be called by the controller. But this wouldn't make much sense with the current design of the repository connectors because there can be several filesystem connectors which then would all use the same property. Which one should be called? This solution requires some redesign...
View and moderate all "tickets Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Tickets"
Originally posted by: rwi
Not severe because there are some simple workarounds: