[TECHNICAL SUPPORT | September 2] LPS-49670 Cannot register custom DLProcessor (dl.file.entry.processor) from a hook: causes NPE

https://issues.liferay.com/browse/LPS-49670

Hi Shinn,

This is caused by this: liferay@b82b41f1d0c7d094091e3ebbf5a8148ae55149c2

Verified that it worked on 6.1.10 EE GA1 (the version where https://issues.liferay.com/browse/LPS-18792 was initially released - added the ability to hook dl.file.entry.processors).

(FYI: the custom processor in the custom-pdfprocessor-hook looks like this:

````java
public class CustomPDFProcessorImpl
    extends DLPreviewableProcessor implements PDFProcessor { ... }
````

and contains dummy impl methods only. This hierarchy worked before LPS-28959, because on 6.1.10, method register in DLProcessorRegistryImpl was:

````java
	public void register(DLProcessor dlProcessor) {
		_dlProcessors.add(dlProcessor);
	}
````

After LPS-28959, it looks like:

````java
	@Override
	public void register(DLProcessor dlProcessor) {
		String type = _getType(dlProcessor);

		_dlProcessors.put(type, dlProcessor);
	}
````
and

````java
	private String _getType(DLProcessor dlProcessor) {
if (dlProcessor instanceof AudioProcessor) {
return DLProcessorConstants.AUDIO_PROCESSOR;
}
else if (dlProcessor instanceof ImageProcessor) {
return DLProcessorConstants.IMAGE_PROCESSOR;
}
else if (dlProcessor instanceof PDFProcessor) {
return DLProcessorConstants.PDF_PROCESSOR;
}
else if (dlProcessor instanceof RawMetadataProcessor) {
return DLProcessorConstants.RAW_METADATA_PROCESSOR;
}
else if (dlProcessor instanceof VideoProcessor) {
return DLProcessorConstants.VIDEO_PROCESSOR;
}
return null;
}
````

Though, when "dlProcessor" is created in *HookHotDeployListener#initPortalProperties*:

````java
...
		if (portalProperties.containsKey(PropsKeys.DL_FILE_ENTRY_PROCESSORS)) {
			String[] dlProcessorClassNames = StringUtil.split(
				portalProperties.getProperty(
					PropsKeys.DL_FILE_ENTRY_PROCESSORS));

			DLFileEntryProcessorContainer dlFileEntryProcessorContainer =
				new DLFileEntryProcessorContainer();

			_dlFileEntryProcessorContainerMap.put(	
				servletContextName, dlFileEntryProcessorContainer);

			for (String dlProcessorClassName : dlProcessorClassNames) {
				DLProcessor dlProcessor = (DLProcessor)newInstance(
					portletClassLoader, DLProcessor.class,
					dlProcessorClassName);

				dlFileEntryProcessorContainer.registerDLProcessor(dlProcessor);
			}
		}
````

it will be a Proxy instance, not the actual implementation, therefore it cannot be casted to any of those interfaces, so "_getType" returns null.

I could not find a better way to overcome this, though, the pattern seems to be valid as it comes from

PortletDisplayTemplateImpl.java:

````java
	@Override
	public List<TemplateHandler> getPortletDisplayTemplateHandlers() {
		List<TemplateHandler> templateHandlers =
			TemplateHandlerRegistryUtil.getTemplateHandlers();

		List<TemplateHandler> portletDisplayTemplateHandlers =
			new ArrayList<TemplateHandler>();

		for (TemplateHandler templateHandler : templateHandlers) {
			if (templateHandler instanceof BasePortletDisplayTemplateHandler) {
				portletDisplayTemplateHandlers.add(templateHandler);
			}
			else if (ProxyUtil.isProxyClass(templateHandler.getClass())) {
				InvocationHandler invocationHandler =
					ProxyUtil.getInvocationHandler(templateHandler);

				if (invocationHandler instanceof ClassLoaderBeanHandler) {
					ClassLoaderBeanHandler classLoaderBeanHandler =
						(ClassLoaderBeanHandler)invocationHandler;

					Object bean = classLoaderBeanHandler.getBean();

					if (bean instanceof BasePortletDisplayTemplateHandler) {
						portletDisplayTemplateHandlers.add(templateHandler);
					}
				}
			}
		}

		return portletDisplayTemplateHandlers;
	}
````

Regards,
Tibor