cancel
Showing results for 
Search instead for 
Did you mean: 

DeclarativeWebScript not working

kasperba
Champ in-the-making
Champ in-the-making
I have written a REST-signin call based on the Alfresco 2.1dev REST-login but when I call it from a browser then I get an exception which says the following:

freemarker.core.InvalidReferenceException: Expression ticket is undefined on line 2, column 11 in com/wannakey/user_signin.get.xml.ftl.

After some hardwork I found out that the setAuthenticationService in the Signin-class is called when Alfresco starts, but the executeImpl is never triggered. Not even when I GET the REST-call.

Alfresco's REST-login works, mine doesn't. What did I miss?


I use the following url:

http://localhost:8080/alfresco/service/user/signin?email=admin&password=admin

Below are the files that are used and they are in an AMP.

signin.java
package com.wannakey.user;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;

import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.web.scripts.WebScriptException;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

public class SignIn extends DeclarativeWebScript {

   //    Logger
    private static final Log log = LogFactory.getLog(SignIn.class);

    // dependencies
    private AuthenticationService authenticationService;
   
    /**
     * @param authenticationService
     */
    public void setAuthenticationService(AuthenticationService authenticationService)
    {
       this.authenticationService = authenticationService;
    }
   
   @Override
   protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status) {
      
       if (authenticationService == null) {
         log.debug("Signin.executeImpl authenticationService is null");
      } else {
         log.debug("Signin.executeImpl authenticationService is NOT null");
      }
      
      log.debug("Signin.executeImpl called CurrentUser=" + authenticationService.getCurrentUserName());
      
      String email = req.getParameter("email");
      String password = req.getParameter("password");
      
      if ((email == null) || (email.length() == 0)) {
            throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "email not specified");
      }
      
      if ((password == null) || (password.length() == 0)) {
            throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
      }
      
      try
        {
            // get ticket
            authenticationService.authenticate(email, password.toCharArray());

            // add ticket to model for javascript and template access
            Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
            model.put("ticket",  authenticationService.getCurrentTicket());
            return model;
        }
        catch(AuthenticationException e)
        {
            throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Signin failed");
        }
        finally
        {
            authenticationService.clearCurrentSecurityContext();
        }
   }
}

signin.get.desc.xml
<webscript>
  <shortname>signin</shortname>
  <description>Sign in with your wannakey-account</description>
  <url>/user/signin?email={email}&amp;password={password}</url>
  <format default="xml"/>
  <authentication>none</authentication>
  <transaction>required</transaction>
</webscript>

signin.get.xml.ftl
<?xml version="1.0" encoding="UTF-8"?>
<ticket>${ticket}</ticket>

module-context.xml
<bean id="webscript.com.wannakey.signin.get"
             class="com.wannakey.user.SignIn" parent="webscript"
             abstract="false" singleton="true" lazy-init="default"
             autowire="default" dependency-check="default">
      <property name="authenticationService" ref="authenticationService" />
   </bean>
19 REPLIES 19

tsgpartner_mui
Champ in-the-making
Champ in-the-making
i dont quite understand what you mean.



so instead of a jar file from my .class file, I need to put that somewhere or have that stated in my context.xml file??

davidc
Star Contributor
Star Contributor
Is your class in the java classpath? - either explicitly or implicitly via a .jar.

Nothing to do with the context.xml.

tsgpartner_mui
Champ in-the-making
Champ in-the-making
As I stated above, after I compiled my java file.  I took the .class file and converted it to a .jar file.  then moved that file into the WEB-INF folder.

Thats all I did.  So, I believe the class is in the java classpath, if thats what you are lookin for. 



I'm just learning how java works currently.

davidc
Star Contributor
Star Contributor
Well, I suggest you grasp the basics first - it's essential to understand the classpath.

Assuming you're using Tomcat, you have two choices:

a) create the folder /com/tsgrp/alfresco/webscript in <tomcat_home>/webapps/alfresco/WEB-INF/classes and place your class in it

or

b) create the folder /com/tsgrp/alfresco/webscript in your .jar file and place the .jar in <tomcat_home>/webapps/alfresco/WEB-INF/lib

tsgpartner_mui
Champ in-the-making
Champ in-the-making
I understand.  Thanks for the help.


I was able to get rid of the 'class cannot be found' error, but unfortunately I have another one.  Right now, I'm just trying to test how java-backed scripts work, so in the error below I have a hello world java script I created.  Basically I want to call the script from the url and then, use java to return a message "hello world' and would be displayed by the response template.


14:57:19,266 ERROR [org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/alfresco]] Exception sending context initialized event to listener instance of class org.alfresco.web.app.ContextListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webscript.com.tsgrp.helloworld.get' defined in file [C:\Alfresco\tomcat\shared\classes\alfresco\extension\auth-context.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'scriptContext' of bean class [com.tsgrp.alfresco.webscript.HelloWorld]: Bean property 'scriptContext' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Caused by:
org.springframework.beans.NotWritablePropertyException: Invalid property 'scriptContext' of bean class [com.tsgrp.alfresco.webscript.HelloWorld]: Bean property 'scriptContext' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
   at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:748)
   at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:606)
   at org.springframework.beans.AbstractPropertyAccessor.setPropertyValue(AbstractPropertyAccessor.java:49)
   at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:74)
   at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
   at org.springframework.beans.factory.support.AbstractBeanFactory.applyPropertyValues(AbstractBeanFactory.java:840)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1026)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:809)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:425)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:250)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:247)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:161)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:273)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:346)
   at org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.refresh(AbstractRefreshableWebApplicationContext.java:156)
   at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:246)
   at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:184)
   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:49)
   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3764)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4216)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:760)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544)
   at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)
   at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)
   at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
   at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)
   at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022)
   at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
   at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
   at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
   at org.apache.catalina.core.StandardService.start(StandardService.java:448)
   at org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
   at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
   at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)



Also, as an additional question, when creating java-backed webscripts, is the response template optional?
(From the wiki, it states that  theres one or more response templates when creating a webscript at least for javascript. )


Going back to java scripts, java code can build a data model that's available to "Response" templates. The Java to be executed is placed into the executeImpl method.  Are there any examples of that in documentation?


Thanks once again

tsgpartner_mui
Champ in-the-making
Champ in-the-making
I was able to build a data model to my template in java code.



by running the code in eclipse, it outputs what i want to see and theres no indication of errors at all.

but then I try to start alfresco with tomcat, I still receive that invalid property error.



SO
i tried moving the context.xml file to C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\alfresco, and

moving my desc.xml and ftl file to
C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\classes\alfresco\extension\<namespace>\files…

and then I was able to successfully start Alfresco without errors n such.

but it still says impl:webscript_default for my helloworld script
therefore, its still has not correctly bind to the script.
I tried hitting script via url, returns 500 error.

tsgpartner_mui
Champ in-the-making
Champ in-the-making
Any thoughts to why I cannot get this spring bean to bind correctly

davidc
Star Contributor
Star Contributor
You need to give your web script bean an appropriate id.  The convention for the id is described at

http://wiki.alfresco.com/wiki/Web_Scripts#Java-backed_Web_Scripts

If you still have trouble dump your bean xml definition and web scripts files here at the forum.

tsgpartner_mui
Champ in-the-making
Champ in-the-making
I actually got it to work now.

Was able to fix my errors and start tomcat.


The funny thing was that it didnt recognize my script. I went to web scripts home, refresh and still didnt show my script, signin.

So then I just upload the desc.xml and ftl files in the repository, then It was able to recognize the script.  And now it works.


Thanks for all the help david.

But one question, how come it worked but I had to upload the files in the repository??

robertito
Champ in-the-making
Champ in-the-making
Good Afternoon,

In your post you mentioned that you built an AMP for that Web Script. Where did you place the web script descriptor? I could only add it to Alfresco by doing it explicitly in folder [Company Home > Data Dictionary > Web Scripts].
Is there a way to deploy them automatically by including them in the AMP?

Thank you in advance.
Kind Regards,
robert