cancel
Showing results for 
Search instead for 
Did you mean: 

How to access Spring bean from javascript webscript

sorin_postelnic
Confirmed Champ
Confirmed Champ
Hello all!

Maybe this is a simple question, but I couldn't find any answer in Google:
How can I access a Spring bean from a javascript webscript running in a WebQuickstart application?

I have tried this (which is working in the Share javascript console):
  var ctx = Packages.org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext();
  var myBean= ctx.getBean("myBean");
but it's not working in my WCMQS javascript webscript, it says: "org.mozilla.javascript.EcmaError: ReferenceError: "Packages" is not defined."

What is the alfresco javascript syntax for accessing the Spring context?

Thanks!
1 ACCEPTED ANSWER

Ok, I solved it.
The wiki page does not specify what is the package of BaseProcessorExtension, and I didn't know there are two implementations of BaseProcessorExtension:
- one called org.springframework.extensions.webscripts.processor.BaseProcessorExtension (located in spring-webscripts-1.2.0.jar)
- and another one called org.alfresco.repo.processor.BaseProcessorExtension (located in alfresco-repository-4.2.4.jar).

I was incorrectly using the one from spring-webscripts, which is not the same as the one in alfresco-repository.
After changing to the correct org.alfresco.repo.processor.BaseProcessorExtension, now it's working.

View answer in original post

5 REPLIES 5

steven_okennedy
Star Contributor
Star Contributor
Hi

The capability to access the Packages object via the JavaScript console is actually part of the JavaScript console extension itself, and only runs within the console (which only the admin can get to).  The standard Alfresco implementation constrains the Rhino JavaScript engine to a select set of exported packages for security reasons and I would really suggest you consider the security implications of what you're looking at here as you may potentially be opening your system to attack.

If it is a specific bean that you want to expose then it's very easy to create a JavaScript wrapper that allows the bean itself to be surfaced within the JavaScript environment as a root-scoped variable - this is how the out of the box javascript services are provided.  It's straightforward, basically requiring a Java class that extends BaseProcessorExtension and defining a bean with a parent of "baseJavaScriptExtension" that points to it.   Have a look at https://wiki.alfresco.com/wiki/Configuring_the_ServiceRegistry_as_a_Javascript_Root_Object for some detail (an old example but still current as far as I know). 

Of course you could also use this mechanism to create a service that retrieved beans, but I really would not recommend it

Regards

Steven

Dear Steven,

I followed the steps described in the wiki page and I implemented the following class in order to be able to access configuration properties from inside javascript-based webscripts:


public class JavascriptCompatibleMyAppnameConfiguration extends BaseProcessorExtension {
   private MyAppnameConfigurationService myAppnameConfigurationService;
   private String otherConfigurationProperty1;
   private String otherConfigurationProperty2;

   public String getSomeConfigurationProperty1() {
      return myAppnameConfigurationService.getSomeConfigurationProperty1();
   }

   public String getSomeConfigurationProperty2() {
      return myAppnameConfigurationService.getSomeConfigurationProperty2();
   }

   public String getSomeConfigurationProperty3() {
      return myAppnameConfigurationService.getSomeConfigurationProperty3();
   }

   public String getOtherConfigurationProperty1() {
      return otherConfigurationProperty1;
   }

   public String getOtherConfigurationProperty2() {
      return otherConfigurationProperty2;
   }


   public void setMyAppnameConfigurationService(MyAppnameConfigurationService myAppnameConfigurationService) {
      this.myAppnameConfigurationService= myAppnameConfigurationService;
   }

   public void setOtherConfigurationProperty1(String otherConfigurationProperty1) {
      this.otherConfigurationProperty1 = otherConfigurationProperty1;
   }

   public void setOtherConfigurationProperty2(String otherConfigurationProperty2) {
      this.otherConfigurationProperty2 = otherConfigurationProperty2;
   }
}

with the following Spring bean definitions:


<beans>

   <bean id="myAppnameJsPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="placeholderPrefix" value="$myappconfigjs{"/>
      <property name="locations">
        <list>
         <value>classpath:/some-configuration.properties</value>
        </list>
      </property>
      <property name="ignoreUnresolvablePlaceholders" value="false"/>
   </bean>

   <bean id="JavascriptCompatibleMyAppnameConfiguration" parent="baseJavaScriptExtension"
        class="my.organisation.myappname.JavascriptCompatibleMyAppnameConfiguration">
      <property name="myAppnameConfigurationService" ref="myAppnameConfigurationService" />
      <property name="otherConfigurationProperty1" value="$myappconfigjs{otherConfigurationProperty1}" />
      <property name="otherConfigurationProperty2" value="$myappconfigjs{otherConfigurationProperty2}" />
      <property name="extensionName" value="MyAppnameConfiguration" /> <!– This defines the name of the javascript object which will be accessible in the webscripts –>
   </bean>

</beans>

But when I start the server I am getting this error:

org.springframework.beans.NotWritablePropertyException: Invalid property 'processor' of bean class [my.organisation.myappname.JavascriptCompatibleMyAppnameConfiguration]:
Bean property 'processor' is not writable or has an invalid setter method. Did you mean 'processors'?

I am using Alfresco 4.2
Did something change for this functionality in between the Alfresco versions?

Thanks!

Ok, I solved it.
The wiki page does not specify what is the package of BaseProcessorExtension, and I didn't know there are two implementations of BaseProcessorExtension:
- one called org.springframework.extensions.webscripts.processor.BaseProcessorExtension (located in spring-webscripts-1.2.0.jar)
- and another one called org.alfresco.repo.processor.BaseProcessorExtension (located in alfresco-repository-4.2.4.jar).

I was incorrectly using the one from spring-webscripts, which is not the same as the one in alfresco-repository.
After changing to the correct org.alfresco.repo.processor.BaseProcessorExtension, now it's working.

Hi

I can't see your import statements in your Java class, but make sure you're extending from org.alfresco.repo.processor.BaseProcessorExtension rather than org.springframework.extensions.webscripts.processor.BaseProcessorExtension Smiley Happy

The latter doesn't have a processor setter which is causing your error

Regards

Steven

sorin_postelnic
Confirmed Champ
Confirmed Champ
Thank you for your reply.
I will look into creating my own javascript wrapper, as the example shows.
Until now I have developed mainly Java-based webscripts, and I was expecting that you can access the Spring beans from a javascript webscript, similarly to how you can access them from Java webscripts.