Monday, November 6, 2017

Why ImageMagick Fails in Alfresco 5.2.1 and How to Fix It

The Problem

If you are using Alfresco Content Services 5.2.1 on Windows, you may have noticed some image files fail to display their thumbnail and preview renditions in Alfresco Share. When you look at the ImageMagick configuration in the Alfresco Admin Console, you see that ImageMagick is disabled:


And, the following ImageMagick error is seen the alfresco.log file:

2017-10-24 11:07:20,320 ERROR [org.alfresco.repo.content.transform.magick.AbstractImageMagickContentTransformerWorker] [localhost-startStop-1] ImageMagickContentTransformerWorker not available: 09240020 Failed to perform ImageMagick transformation: 
Execution result: 
   os:         Windows Server 2012 R2
   command:    C:\Alfresco\5.2.1\imagemagick\convert.exe C:\Alfresco\52D9B8~1.1\tomcat\temp\Alfresco\ImageMagickContentTransformerWorker_init_source_137991397234068809.gif -strip -quiet C:\Alfresco\52D9B8~1.1\tomcat\temp\Alfresco\ImageMagickContentTransformerWorker_init_target_9151095455871890262.png
   succeeded:  false
   exit code:  1
   out:        
   err:        convert.exe: RegistryKeyLookupFailed `CoderModulesPath' @ error/module.c/GetMagickModulePath/670.
convert.exe: no decode delegate for this image format `GIF' @ error/constitute.c/ReadImage/509.
convert.exe: no images defined `C:\Alfresco\52D9B8~1.1
20

In the Alfresco 5.2.1 release, Alfresco replaced the previously used Ghostscript PDF interpreter with the new Alfresco PDF Render transformer (i.e., alfresco-pdf-renderer). This application is responsible for generating thumbnails and previews of various document formats. Unfortunately, the Windows version of this transformer conflicts with the ImageMagick transformer causing ImageMagick transformations to fail. The conflict occurs because two different Spring bean references were given the same name. As a result, the same parameters are being passed to both ImageMagick and the Alfresco PDF Render.

It's worth noting that this issue is fixed in the Alfresco 5.2.2 release, but if you are still using Alfresco 5.2.1, here's how you can fix it.

The Fix

You can resolve the transformer conflict by placing a copy of the custom-alfresco-pdf-renderer-transform-context.xml and custom-imagemagick-transform-context.xml files (contents shown below) in the tomcat/shared/classes/alfresco/extension folder and restarting Alfresco. Before you do the restart, ensure the img.gslib property does not exist (or is commented out) in the alfresco-global.properties file.

The Files

custom-alfresco-pdf-renderer-transform-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>

   <bean id="transformer.worker.subsys.alfresco-pdf-renderer" class="org.alfresco.repo.content.transform.pdfrenderer.AlfrescoPdfRendererContentTransformerWorker">
      <property name="mimetypeService">
         <ref bean="mimetypeService" />
      </property>
      <property name="executer">
         <bean name="transformer.alfresco-pdf-renderer.command" class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandsAndArguments">
               <map>
                  <entry key=".*">
                     <list>
                        <value>${alfresco-pdf-renderer.exe}</value>
                        <value>SPLIT:${options}</value>
                        <value>${source}</value>
                        <value>${target}</value>
                     </list>
                  </entry>
               </map>
            </property>
            <property name="processProperties" ref="#{systemProperties['os.name'].contains('Windows') ? 'transformer.worker.subsys.alfresco-pdf-renderer.processPropertiesWindows' : 'transformer.worker.subsys.alfresco-pdf-renderer.processPropertiesUnix'}" />
            <property name="defaultProperties">
               <props>
                  <prop key="options"></prop>
               </props>
            </property>
            <property name="errorCodes" >
               <value>1</value>
            </property>
         </bean>
      </property>
      <property name="checkCommand">
         <bean name="transformer.Pdfium.CheckCommand" class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandsAndArguments">
               <map>
                  <entry key=".*">
                     <list>
                        <value>${alfresco-pdf-renderer.exe}</value>
                        <value>--version</value>
                     </list>
                  </entry>
               </map>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="transformer.worker.subsys.alfresco-pdf-renderer.processPropertiesWindows" class="org.springframework.beans.factory.config.MapFactoryBean">
      <property name="sourceMap"> 
         <map>
            <entry key="ALFRESCO-PDF-RENDERER_HOME">
               <value>${alfresco-pdf-renderer.root}</value>
            </entry>
         </map>
      </property>
   </bean>

   <bean id="transformer.worker.subsys.alfresco-pdf-renderer.processPropertiesUnix" class="org.springframework.beans.factory.config.MapFactoryBean">
      <property name="sourceMap">
         <map>
            <entry key="ALFRESCO-PDF-RENDERER_HOME">
               <value>${alfresco-pdf-renderer.root}</value>
            </entry>
         </map>
      </property>
   </bean>

</beans>

custom-imagemagick-transform-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>

   <bean id="transformer.worker.ImageMagick" class="org.alfresco.repo.content.transform.magick.ImageMagickContentTransformerWorker">
      <property name="mimetypeService">
         <ref bean="mimetypeService" />
      </property>
      <property name="executer">
         <bean name="transformer.ImageMagick.Command" class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandsAndArguments">
               <map>
                  <entry key=".*">
                     <list>
                        <value>${img.exe}</value>
                        <value>${source}</value>
                        <value>SPLIT:${options}</value>
                        <value>-strip</value>
                        <value>-quiet</value>
                        <value>${target}</value>
                     </list>
                  </entry>
               </map>
            </property>
            <property name="processProperties" ref="#{systemProperties['os.name'].contains('Windows') ? 'transformer.worker.ImageMagick.processPropertiesWindows' : 'transformer.worker.ImageMagick.processPropertiesUnix'}" />
            <property name="defaultProperties">
               <props>
                  <prop key="options"></prop>
               </props>
            </property>
            <property name="errorCodes" >
               <!-- The published error and fatal error codes are in the 400 and 700 ranges, but 1 is the most common and have seen 255 (could that by -1) -->
               <value>1,2,255,400,405,410,415,420,425,430,435,440,450,455,460,465,470,475,480,485,490,495,499,700,705,710,715,720,725,730,735,740,750,755,760,765,770,775,780,785,790,795,799</value>
            </property>
         </bean>
      </property>
      <property name="checkCommand">
         <bean name="transformer.ImageMagick.CheckCommand" class="org.alfresco.util.exec.RuntimeExec">
            <property name="commandsAndArguments">
               <map>
                  <entry key=".*">
                     <list>
                        <value>${img.exe}</value>
                        <value>-version</value>
                     </list>
                  </entry>
               </map>
            </property>
         </bean>
      </property>
   </bean>

   <bean id="transformer.worker.ImageMagick.processPropertiesWindows" class="org.springframework.beans.factory.config.MapFactoryBean">
      <property name="sourceMap"> 
         <map>
            <entry key="MAGICK_HOME">
               <value>${img.root}</value>
            </entry>
            <entry key="MAGICK_CODER_MODULE_PATH">
               <value>${img.coders}</value>
            </entry>
            <entry key="MAGICK_CONFIGURE_PATH">
               <value>${img.config}</value>
            </entry>
            <entry key="DYLD_FALLBACK_LIBRARY_PATH">
               <value>${img.dyn}</value>
            </entry>
            <entry key="LD_LIBRARY_PATH">
               <value>${img.dyn}</value>
            </entry>
         </map>
      </property>
   </bean>

   <bean id="transformer.worker.ImageMagick.processPropertiesUnix" class="org.springframework.beans.factory.config.MapFactoryBean">
      <property name="sourceMap">
         <map>
            <entry key="MAGICK_HOME">
               <value>${img.root}</value>
            </entry>
            <entry key="DYLD_FALLBACK_LIBRARY_PATH">
               <value>${img.dyn}</value>
            </entry>
            <entry key="LD_LIBRARY_PATH">
               <value>${img.dyn}</value>
            </entry>
         </map>
      </property>
   </bean>

</beans>

No comments:

Post a Comment