[Error] Problemas con SLF4JLogFactory y Alfresco 4.2.x

Muy buenas.

Cuando nos toca trabajar con la SDK 1.1.1 – porque algunas veces puede ocurrir que nos encontremos algún cliente sigue usando Alfresco 4.2.x – nos tocará lidiar con esta versión de SDK siguiendo la tabla de compatibilidades publicada por Alfresco. Si utilizamos el arqueotipo “todo en uno” por defecto tenemos un error nada más arrancar:

GRAVE: Servlet /alfresco threw load() exception
org.apache.commons.discovery.DiscoveryException: Class org.apache.commons.logging.impl.SLF4JLogFactory does not implement org.apache.commons.logging.LogFactory
at org.apache.commons.discovery.tools.ClassUtils.verifyAncestory(ClassUtils.java:180)
at org.apache.commons.discovery.tools.SPInterface.verifyAncestory(SPInterface.java:201)
at org.apache.commons.discovery.tools.SPInterface.newInstance(SPInterface.java:195)
at org.apache.commons.discovery.tools.DiscoverClass.newInstance(DiscoverClass.java:579)
at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:418)
at org.apache.commons.discovery.tools.DiscoverSingleton.find(DiscoverSingleton.java:378)
at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
at org.apache.axis.transport.http.AxisServletBase.<clinit>(AxisServletBase.java:58)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1002)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlClassNewInstance(ReflectiveInterceptor.java:989)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:138)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1144)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1088)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5033)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5317)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)

Incluso el error está reconocido por Alfresco en este ticket, pero lamentablemente la solución que proponen no funciona :-(

Después de horas de quebramiento de cabeza, cientos de pruebas y combinaciones, esto es lo que me funcionó:

pom.xml “padre” (alojado en el proyecto que tengáis creado, por ejemplo: miProyecto/pom.xml)


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>es.extension</groupId>
    <artifactId>miProyecto</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>Quickstart of Alfresco and Share with DB and runner embedded</name>
    <description>This All-in-One project allows to manage all the components involved in Alfresco development (Repo, Share, Solr, AMPs) in one project</description>
    <packaging>pom</packaging>    

    <parent>
        <groupId>org.alfresco.maven</groupId>
        <artifactId>alfresco-sdk-parent</artifactId>
        <version>1.1.1</version>
    </parent>
    
    <!-- 
       | SDK properties have sensible defaults in the SDK parent, but you can override the properties below to use another version. 
       | For more available properties see the alfresco-sdk-parent POM. 
       -->
    <properties>
        <!-- 
            | Defines the Alfresco GroupId \ Edition to work against. Allowed values are: org.alfresco | org.alfresco.enterprise
            | NOTE: Please Refer to Alfresco Support for access to Enterprise artifacts -->
        <alfresco.groupId>org.alfresco</alfresco.groupId>
        <!-- Defines the Alfresco version to work against. Allowed values are: org.alfresco | org.alfresco.enterprise -->
        <alfresco.version>4.2.0</alfresco.version>
        <!-- This control the root logging level for all apps -->
        <app.log.root.level>WARN</app.log.root.level>
        <!-- This controls the default data location for dir.root -->
        <alfresco.data.location>alf_data_dev</alfresco.data.location>
        <!-- This controls which properties will be picked in multi-enviromment build -->
        <env>local</env>
    <module.log.level>DEBUG</module.log.level>
   </properties>

   <!-- Here we realize the connection with the Alfresco selected platform (e.g.version and edition) -->
   <dependencyManagement>
     <dependencies>
          <!-- This will import the dependencyManagement for all artifacts in the selected Alfresco plaftorm
               (see http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies)
               NOTE: You still need to define dependencies in your POM, but you can omit version as it's enforced by this dependencyManagement.
               NOTE: It defaults to the latest version this SDK pom has been tested with, but alfresco version can/should be overridden in your project's pom   
           -->
          <dependency>
              <groupId>${alfresco.groupId}</groupId>
              <artifactId>alfresco-platform-distribution</artifactId>
              <version>${alfresco.version}</version>
              <type>pom</type>
              <scope>import</scope>
          </dependency>
</dependencies>
  </dependencyManagement>
  
    <!-- This repository is only needed to retrieve Alfresco parent POM. 
        NOTE: This can be removed when/if Alfresco will be on Maven Central 
        
        NOTE: The repository to be used for Alfresco Enterprise artifacts is
        https://artifacts.alfresco.com/nexus/content/groups/private/. Please check
        with Alfresco Support to get credentials to add to your ~/.m2/settings.xml
        if you are a Enterprise customer or Partner  
        -->
    <repositories>
        <repository>
            <id>alfresco-private</id>
            <url>https://artifacts.alfresco.com/nexus/content/groups/private</url>
        </repository>
        <repository>
            <id>alfresco-private-snapshots</id>
            <url>https://artifacts.alfresco.com/nexus/content/groups/private-snapshots</url>
        </repository>
    </repositories>
  <modules>
    <module>amp</module>
    <module>alfresco</module>
    <module>solr</module>
    <module>share</module>
    <module>runner</module>
  </modules>
</project>

pom.xml “repo” (por ejemplo: miProyecto/alfresco/pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
    license agreements. See the NOTICE file distributed with this work for additional 
    information regarding copyright ownership. The ASF licenses this file to 
    You under the Apache License, Version 2.0 (the "License"); you may not use 
    this file except in compliance with the License. You may obtain a copy of 
    the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
    by applicable law or agreed to in writing, software distributed under the 
    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
    OF ANY KIND, either express or implied. See the License for the specific 
    language governing permissions and limitations under the License. -->
    
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>alfresco</artifactId>
    <name>Alfresco Repository and Explorer Client</name>
    <packaging>war</packaging>
    <description>Alfresco Repository and Explorer Client</description>

    <parent>
        <groupId>es.extension</groupId>
        <artifactId>miProyecto</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>${alfresco.groupId}</groupId>
            <artifactId>alfresco</artifactId>
            <type>war</type>
        </dependency>
        <!-- Demonstrating the dependency on the repo AMP developed in the 'amp' module -->
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>amp</artifactId>
            <version>${project.version}</version>
            <type>amp</type>
        </dependency>
        <!-- Demonstrating the usage of a well known GA AMP (SharePoint Protocol Support) -->
        <dependency>
            <groupId>${alfresco.groupId}</groupId>
            <artifactId>alfresco-spp</artifactId>
            <version>${alfresco.version}</version>
            <type>amp</type>
        </dependency>
         <!-- LOGS -->
         <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>jcl-over-slf4j</artifactId>
               <version>1.5.11</version>
        </dependency>
        <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>slf4j-log4j12</artifactId>
               <version>1.5.11</version>
        </dependency>
        <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.5.11</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
</dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <!--  Here is can control the order of overlay of your (WAR, AMP, etc.) dependencies
                        | NOTE: At least one WAR dependency must be uncompressed first
                        | NOTE: In order to have a dependency effectively added to the WAR you need to 
                        | explicitly mention it in the overlay section.
                        | NOTE: First-win resource strategy is used by the WAR plugin
                         -->
                    <overlays>
                        <!-- Current project customizations -->
                        <overlay/>
                        <!-- The Alfresco WAR -->
                        <overlay>
                            <groupId>${alfresco.groupId}</groupId>
                            <artifactId>alfresco</artifactId>
                            <type>war</type>
                            <!-- To allow inclusion of META-INF -->
                            <excludes/>
                        </overlay>
                        <!-- Add / order your AMPs here -->
                        <overlay>
                            <groupId>${project.groupId}</groupId>
                            <artifactId>amp</artifactId>
                            <type>amp</type>
                        </overlay>
                        <overlay>
                            <groupId>${alfresco.groupId}</groupId>
                            <artifactId>alfresco-spp</artifactId>
                            <type>amp</type>
                        </overlay>
                    </overlays>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <profiles>
        <!-- Overrides the run profile to disable securecomms -->
        <profile>
            <id>run</id>
            <build>
                <plugins>
                    <plugin>
                        <artifactId>maven-war-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>prepare-exploded-war</id>
                                <goals>
                                    <goal>exploded</goal>
                                </goals>
                                <phase>prepare-package</phase>
                            </execution>
                            <execution>
                                <id>default-war</id>
                                <configuration>
                                    <webXml>${project.build.directory}/${project.build.finalName}-nossl/WEB-INF/web.xml</webXml>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- Replaces web.xml where applicable, commenting out the security-constraints -->
                    <plugin>
                        <groupId>com.google.code.maven-replacer-plugin</groupId>
                        <artifactId>replacer</artifactId>
                        <executions>
                            <execution>
                                <id>disable-securecomms</id>
                                <phase>prepare-package</phase>
                                <goals>
                                    <goal>replace</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <ignoreErrors>true</ignoreErrors>
                            <file>${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml</file>
                            <outputDir>${project.build.directory}/${project.build.finalName}-nossl/WEB-INF/</outputDir>
                            <preserveDir>false</preserveDir>
                            <replacements>
                                <replacement>
                                    <token><![CDATA[<!-- Toggle securecomms placeholder start -->]]></token>
                                    <value><![CDATA[<!--]]></value>
                                </replacement>
                                <replacement>
                                    <token><![CDATA[<!-- Toggle securecomms placeholder end -->]]></token>
                                    <value><![CDATA[-->]]></value>
                                </replacement>
                            </replacements>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

pom.xml “share” (por ejemplo: miProyecto/share/pom.xml)


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>share</artifactId>
    <name>Alfresco Share Client</name>
    <packaging>war</packaging>
    <description>Alfresco Share Client</description>

    <parent>
        <groupId>es.extension</groupId>
        <artifactId>miProyecto</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>${alfresco.groupId}</groupId>
            <artifactId>share</artifactId>
            <type>war</type>
        </dependency>
        <!-- Here you can add your Share AMP dependencies -->
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <!-- Here is can control the order of overlay of your (WAR, AMP, etc.) dependencies
                        | NOTE: At least one WAR dependency must be uncompressed first 
                        | NOTE: In order to have a dependency effectively added to the WAR you need to 
                        | explicitly mention it in the overlay section. 
                        | NOTE: First-win resource strategy is used by the WAR plugin 
                        -->
                    <overlays>
                        <!-- The current project customizations -->
                        <overlay/>
                        <!-- The Share WAR -->
                        <overlay>
                            <groupId>${alfresco.groupId}</groupId>
                            <artifactId>share</artifactId>
                            <type>war</type>
                            <!-- To allow inclusion of META-INF -->
                            <excludes/>
                        </overlay>
                        <!-- Add / order here the Share AMPs declared above -->
                    </overlays>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Dos cosas a destacar:

  • En el pom padre he quitado toda referencia a logs.
  • Y en el pom del repo, o sea de Alfresco, he añadido las siguientes dependencias dentro del tag de dependencies:
...
         <!-- LOGS -->
         <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>jcl-over-slf4j</artifactId>
               <version>1.5.11</version>
        </dependency>
        <dependency>
               <groupId>org.slf4j</groupId>
               <artifactId>slf4j-log4j12</artifactId>
               <version>1.5.11</version>
        </dependency>
        <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.5.11</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.15</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.jms</groupId>
                    <artifactId>jms</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jmx</groupId>
                    <artifactId>jmxri</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.sun.jdmk</groupId>
                    <artifactId>jmxtools</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
...

Y con esto solucioné el dichoso error.

Por cierto, después de trabajar un tiempo con el All-In-One tuve que pasar al arqueotipo de Alfresco-AMP debido a un problema con la configuración de Spring y los logs.

Espero que os haya servido, al menos para ahorraros algo de tiempo y dolores varios de cabeza :-P

¡Un saludo!

Deja un comentario