AnsweredAssumed Answered

Deploying Java-backed class under extension classpath

Question asked by kooroshv on Jul 9, 2010
Latest reply on Jul 16, 2010 by chandu7ee
I have installed Alfresco version 3.3G on Windows and in process of evaluating it. Presently, I am trying to make JavaDir Java-Backed example from chapter 11th in "Professional Alfresco Practical Solutions" book to work. I have gotten the example working where I have placed my Java class file under the default installation path:

<Tomcat_Home>\webapps\alfresco\WEB-INF\classes

However, I am having trouble getting it working when I deploy it under the extension classpath as suggested in the book:

<Tomcat_home>\shared\classes\alfresco\extension

Here is the error message I get when starting Alfresco:

10:45:30,748  ERROR [web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean wit
h name 'LuceneFullTextSearchIndexer' defined in class path resource [alfresco/co
re-services-context.xml]: Cannot resolve reference to bean 'luceneFullTextSearch
Indexer' while setting bean property 'target'; nested exception is org.springfra
mework.beans.factory.BeanCreationException: Error creating bean with name 'lucen
eFullTextSearchIndexer' defined in class path resource [alfresco/core-services-c
ontext.xml]: Initialization of bean failed; nested exception is org.springframew
ork.beans.factory.CannotLoadBeanClassException: Cannot find class [org.example.J
avaDir] for bean with name 'webscript.org.example.javadir.get' defined in file [
C:\apache-tomcat-6.0.26-alfresco\shared\classes\alfresco\extension\javadir-conte
xt.xml]; nested exception is java.lang.ClassNotFoundException: org.example.JavaD
ir
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveReference(BeanDefinitionValueResolver.java:328)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1305)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.populateBean(AbstractAutowireCapableBeanFactory.java:1067)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:511)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:450)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:290)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe
an(AbstractBeanFactory.java:287)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:189)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.
preInstantiateSingletons(DefaultListableBeanFactory.java:540)
        at org.springframework.context.support.AbstractApplicationContext.finish
BeanFactoryInitialization(AbstractApplicationContext.java:842)
        at org.springframework.context.support.AbstractApplicationContext.refres
h(AbstractApplicationContext.java:416)
        at org.springframework.web.context.ContextLoader.createWebApplicationCon
text(ContextLoader.java:261)
        at org.springframework.web.context.ContextLoader.initWebApplicationConte
xt(ContextLoader.java:192)
        at org.springframework.web.context.ContextLoaderListener.contextInitiali
zed(ContextLoaderListener.java:47)
        at org.alfresco.web.app.ContextLoaderListener.contextInitialized(Context
LoaderListener.java:63)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContex
t.java:3972)
        at org.apache.catalina.core.StandardContext.start(StandardContext.java:4
467)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase
.java:791)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:77
1)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:546)

        at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.ja
va:637)
        at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.j
ava:563)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:498
)
        at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1277)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java
:321)
        at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(Lifecycl
eSupport.java:119)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)

        at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
        at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)

        at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443
)
        at org.apache.catalina.core.StandardService.start(StandardService.java:5
19)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:710
)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creati
ng bean with name 'luceneFullTextSearchIndexer' defined in class path resource [
alfresco/core-services-context.xml]: Initialization of bean failed; nested excep
tion is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot f
ind class [org.example.JavaDir] for bean with name 'webscript.org.example.javadi
r.get' defined in file [C:\apache-tomcat-6.0.26-alfresco\shared\classes\alfresco
\extension\javadir-context.xml]; nested exception is java.lang.ClassNotFoundExce
ption: org.example.JavaDir
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.createBean(AbstractAutowireCapableBeanFactory.java:450)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getOb
ject(AbstractBeanFactory.java:290)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistr
y.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBe
an(AbstractBeanFactory.java:287)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean
(AbstractBeanFactory.java:189)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver
.resolveReference(BeanDefinitionValueResolver.java:322)
        … 40 more
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Canno
t find class [org.example.JavaDir] for bean with name 'webscript.org.example.jav
adir.get' defined in file [C:\apache-tomcat-6.0.26-alfresco\shared\classes\alfre
sco\extension\javadir-context.xml]; nested exception is java.lang.ClassNotFoundE
xception: org.example.JavaDir
        at org.springframework.beans.factory.support.AbstractBeanFactory.resolve
BeanClass(AbstractBeanFactory.java:1208)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.predictBeanType(AbstractAutowireCapableBeanFactory.java:568)
        at org.springframework.beans.factory.support.AbstractBeanFactory.isFacto
ryBean(AbstractBeanFactory.java:1277)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeanNamesForType(DefaultListableBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeansOfType(DefaultListableBeanFactory.java:381)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.
getBeansOfType(DefaultListableBeanFactory.java:375)
        at org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexerImpl.se
tBeanFactory(FullTextSearchIndexerImpl.java:247)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1422)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.initializeBean(AbstractAutowireCapableBeanFactory.java:1389)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBean
Factory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
        … 46 more
Caused by: java.lang.ClassNotFoundException: org.example.JavaDir
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa
der.java:1516)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoa
der.java:1361)
        at org.springframework.util.ClassUtils.forName(ClassUtils.java:258)
        at org.springframework.beans.factory.support.AbstractBeanDefinition.reso
lveBeanClass(AbstractBeanDefinition.java:408)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doResol
veBeanClass(AbstractBeanFactory.java:1229)
        at org.springframework.beans.factory.support.AbstractBeanFactory.resolve
BeanClass(AbstractBeanFactory.java:1200)
        … 55 more

Since Alfresco error tells me it is having problem finding the class file, I experimented by deploying the class under <Tomcat_home>\shared\classes. By doing this Alfresco at start time sees my Java class, but then complains about undefined classes such as DeclarativeWebScript. By adding the corresponding Jar files under <Tomcat_home>\shared\lib I got over some of the undefined class errors, but finally I got stuck where it was complaining about 'no matching type' for 'repository'. This seems not to be the right approach.

Looking at the Wiki http://wiki.alfresco.com/wiki/Java-backed_Web_Scripts_Samples#Writing_the_Web_Script_.28Java.29, it does not mention the 'extension' path. Also I could not find any reference to this topic on the forum.

Any suggestions is greatly appropriated here.

For reference here are the listing of the files and their locations:

Via Alfresco Explorer:  Company Home -> Data Dictionary -> Web Scripts Extensions -> org -> example -> javadir.get.desc.xml

<webscript>
  <shortname>Folder Listing Utility</shortname>
  <description>Java-backed implementation of listing folder contents</description>
  <url>/javadir/{folderpath}?verbose={verbose?}</url>
  <authentication>user</authentication>
</webscript>

Via Alfresco Explorer:  Company Home -> Data Dictionary -> Web Scripts Extensions -> org -> example -> javadir.get.html.ftl

<html>
  <head>
    <title>Folder ${folder.displayPath}/${folder.name}</title>
  </head>
  <body>
     Alfresco ${server.edition} Edition v${server.version} : dir
    <p>
    Contents of folder ${folder.displayPath}/${folder.name}
    <p>
    <table>
    <#list folder.children as child>
       <tr>
           <td><#if child.isContainer>d</#if></td>
           <#if verbose>
              <td>${child.properties.modifier}</td>
              <td><#if child.isDocument>
                 ${child.properties.content.size}</#if></td>
              <td>${child.properties.modified?date}</td>
           </#if>
           <td>${child.name}</td>
       </tr>
    </#list>
    </table>
  </body>
</html>

JavaDir class is listed bellow. Note, I changed import path for 'DeclarativeWebScript' and others from 'org.alfresco.web.scripts' to 'org.springframework.extensions.webscripts' because of changes from 3.2 to 3.3 release:

package org.example;

import java.util.HashMap;
import java.util.Map;

import org.alfresco.repo.model.Repository;
import org.alfresco.service.cmr.repository.NodeRef;
//This classes are defined in spring-webscripts-1.0.0.CI-SNAPSHOT.jar which is in 3rd Party project.
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptRequest;

public class JavaDir extends DeclarativeWebScript
{
    private Repository repository;
   
    public void setRepository(Repository repository)
    {
        this.repository = repository; 
    }
   
    protected Map<String, Object> executeImpl(WebScriptRequest req,
        Status status, Cache cache)
    {
        // extract folder listing arguments from URI
        String verboseArg = req.getParameter("verbose");
        Boolean verbose = Boolean.parseBoolean(verboseArg);
        Map<String, String> templateArgs = req.getServiceMatch().getTemplateVars();
        String folderPath = templateArgs.get("folderpath");
       
        // search for folder within Alfresco content repository
        String nodePath = "workspace/SpacesStore/" + folderPath;
        NodeRef folder = repository.findNodeRef("path", nodePath.split("/"));
       
        // validate that folder has been found
        if (folder == null)
        {
            throw new WebScriptException(Status.STATUS_NOT_FOUND,
              "Folder " + folderPath + " not found");
        }

        // construct model for response template to render
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("verbose", verbose);
        model.put("folder", folder);
        return model;
    }
}

Outcomes