This article documents a known issue in the export process if any asset has a forbidden character in the name. These characters are usually reserved for HTML and XML and thus should not be used. In the case of exporting a page template as a .LAR
, there is a console error and the export process fails.
The following characters have been blacklisted: !@#$%^&(): < / > ;~|+`={?"}'
Steps to Reproduce (Liferay Portal 6.2 EE):
- Click Admin → Control Panel.
- Click Page Templates.
- Click Add.
- Enter the following:
- Name: Page:Forum
- Description: This page has a colon in the name.
- Click the Save button.
- Verify that the new page template was created successfully.
- Click Actions → Export next to the new page template.
- Verify that the page template contains the colon in the
.LAR
name. - Click the Export button.
At this point the system attempts to generate the .LAR
file. Then the status page displays the export process has failed.
The console error displays below:
16:43:02,703 ERROR [liferay/background_task-1][BackgroundTaskMessageListener:133] Unable to execute background task com.liferay.portlet.documentlibrary.FileNameException: Forum:Stargate-201709281642.lar at com.liferay.portlet.documentlibrary.store.DLStoreImpl.validate(DLStoreImpl.java:622) at com.liferay.portlet.documentlibrary.store.DLStoreImpl.validate(DLStoreImpl.java:795) at com.liferay.portlet.documentlibrary.store.DLStoreImpl.validate(DLStoreImpl.java:835) at com.liferay.portlet.documentlibrary.store.DLStoreImpl.validate(DLStoreImpl.java:731) at com.liferay.portlet.documentlibrary.service.impl.DLFileEntryLocalServiceImpl.validateFile(DLFileEntryLocalServiceImpl.java:2778) at com.liferay.portlet.documentlibrary.service.impl.DLFileEntryLocalServiceImpl.addFileEntry(DLFileEntryLocalServiceImpl.java:203) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:65) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.cache.ThreadLocalCacheAdvice.invoke(ThreadLocalCacheAdvice.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at com.sun.proxy.$Proxy200.addFileEntry(Unknown Source) at com.liferay.portal.repository.liferayrepository.LiferayLocalRepository.addFileEntry(LiferayLocalRepository.java:128) at com.liferay.portlet.documentlibrary.service.impl.DLAppLocalServiceImpl.addFileEntry(DLAppLocalServiceImpl.java:201) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:65) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.cache.ThreadLocalCacheAdvice.invoke(ThreadLocalCacheAdvice.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at com.sun.proxy.$Proxy196.addFileEntry(Unknown Source) at com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil.addFileEntry(DLAppLocalServiceUtil.java:152) at com.liferay.portal.portletfilerepository.PortletFileRepositoryImpl.addPortletFileEntry(PortletFileRepositoryImpl.java:137) at com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil.addPortletFileEntry(PortletFileRepositoryUtil.java:59) at com.liferay.portal.service.impl.BackgroundTaskLocalServiceImpl.addBackgroundTaskAttachment(BackgroundTaskLocalServiceImpl.java:123) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:115) at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:65) at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.cache.ThreadLocalCacheAdvice.invoke(ThreadLocalCacheAdvice.java:51) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:56) at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:111) at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:175) at com.sun.proxy.$Proxy17.addBackgroundTaskAttachment(Unknown Source) at com.liferay.portal.service.BackgroundTaskLocalServiceUtil.addBackgroundTaskAttachment(BackgroundTaskLocalServiceUtil.java:295) at com.liferay.portal.lar.backgroundtask.LayoutExportBackgroundTaskExecutor.execute(LayoutExportBackgroundTaskExecutor.java:72) at com.liferay.portal.kernel.backgroundtask.SerialBackgroundTaskExecutor.execute(SerialBackgroundTaskExecutor.java:57) at com.liferay.portal.backgroundtask.messaging.BackgroundTaskMessageListener.doReceive(BackgroundTaskMessageListener.java:108) at com.liferay.portal.kernel.messaging.BaseMessageListener.receive(BaseMessageListener.java:26) at com.liferay.portal.kernel.messaging.InvokerMessageListener.receive(InvokerMessageListener.java:72) at com.liferay.portal.kernel.messaging.ParallelDestination$1.run(ParallelDestination.java:71) at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask._runTask(ThreadPoolExecutor.java:682) at com.liferay.portal.kernel.concurrent.ThreadPoolExecutor$WorkerTask.run(ThreadPoolExecutor.java:593) at java.lang.Thread.run(Thread.java:745)
Resolution
Status: Workaround Available
One immediate solution is to add the characters to the property dl.char.blacklist
found in the portal.properties
. Add the forbidden values to this list separated by commas. As a best practice, do not modify the portal.properties
file directly, but instead, create a portal-ext.properties
file.
Liferay Engineering has implemented a fix where the error will be caught much earlier in time than at the export process. This means the portal will have a validation check when site administrators are naming their site or page templates. However, at this point, this solution has not been implemented in any Liferay Portal 6.2 EE fix packs.
To receive this solution, open a ticket and ask for a hotfix that includes LPS-74521.
Additional Information
To track the status of the fix, see LPS-74521.