cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with JBPMSpringActionHandler

bcoulson
Champ in-the-making
Champ in-the-making
All

I am attempting to connect to my Java class from within an advanced worfklow step. I have defined my process definition as follows.


<?xml version="1.0" encoding="UTF-8"?>

<process-definition  xmlns="urn:jbpm.org:jpdl-3.1"  name="scwf:publishDocument">

<swimlane name="initiator"/>

   <start-state name="Start">
      <task name="scwf:assignWorkflow" swimlane="initiator"/>
      <transition to="AnalystTask" name="toAnalyst"></transition>
   </start-state>

   <task-node name="AnalystTask">
      <task name="scwf:createDocument" swimlane="initiator">
         <event type="task-create">
            <script>
               if (bpm_workflowDueDate != void) taskInstance.dueDate = bpm_workflowDueDate;
                  if (bpm_workflowPriority != void) taskInstance.priority = bpm_workflowPriority;
            </script>
         </event>
      </task>
      <transition to="TeamLeadTask" name="toTeamLead">
           <action class="gov.dhs.ipds.alfresco.AlfrescoHelper" config-type="bean" name="reviewChanges"/>
      </transition>
   </task-node>

   <task-node name="TeamLeadTask">
      <task name="scwf:reviewDocument" swimlane="initiator">
         <event type="task-create">
            <script>
               if (bpm_workflowDueDate != void) taskInstance.dueDate = bpm_workflowDueDate;
                  if (bpm_workflowPriority != void) taskInstance.priority = bpm_workflowPriority;
            </script>
         </event>
      </task>

      <transition to="End" name="toProduction">
      </transition>
   </task-node>

   <end-state name="End"></end-state>
</process-definition>

And my Java code is as follows

package gov.dhs.ipds.alfresco;

import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
import org.springframework.beans.factory.BeanFactory;
import org.jbpm.graph.exe.ExecutionContext;

public class AlfrescoHelper extends  JBPMSpringActionHandler {

   private static final long serialVersionUID = 1000L;

   public void execute(ExecutionContext ctx) throws Exception {
      System.out.println("Inside AlfrescoHelp.execute()");
   }

   public AlfrescoHelper() {
      System.out.println("Inside AlfrescoHelper()");
   }
   
   @Override
   protected void initialiseHandler(BeanFactory factory) {
      System.out.println("Inside AlfrescoHelper.initialiseHandler()");
      // TODO Auto-generated method stub
   }
}

When I attempt to execute the workflow task that instantiates the Java action class, I get the following exception(s) in my logfile.


09:06:44,209  ERROR [web.context.ContextLoader] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gov.dhs.ipds.alfresco.AlfrescoHelper' defined in file [C:\Alfresco\tomcat\shared\classes\alfresco\extension\someco-model-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [gov.dhs.ipds.alfresco.AlfrescoHelper]: Constructor threw exception; nested exception is java.lang.NullPointerException
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:946)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:890)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
   at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
   at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
   at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
   at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
   at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
   at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
   at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
   at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:261)
   at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:192)
   at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
   at org.alfresco.web.app.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:63)
   at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3972)
   at org.apache.catalina.core.StandardContext.start(StandardContext.java:4467)
   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:546)
   at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:637)
   at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java: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(LifecycleSupport.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:519)
   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(DelegatingMethodAccessorImpl.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.BeanInstantiationException: Could not instantiate bean class [gov.dhs.ipds.alfresco.AlfrescoHelper]: Constructor threw exception; nested exception is java.lang.NullPointerException
   at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
   at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:72)
   at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:938)
   … 38 more
Caused by: java.lang.NullPointerException
   at org.springmodules.workflow.jbpm31.JbpmFactoryLocator.useBeanFactory(JbpmFactoryLocator.java:162)
   at org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler.<init>(JBPMSpringActionHandler.java:46)
   at gov.dhs.ipds.alfresco.AlfrescoHelper.<init>(AlfrescoHelper.java:15)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
   at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
   … 40 more

I cannot see what I am doing wrong nor have I been able to find any information in the forums here or on Spring or jBpm to determine what I am doing wrong. I have not added a Spring bean for my Java class. When I do add a bean for it, I get the same exception above so I just get it sooner rather than later - basically at instantiation time.

Any help would be greatly appreciated.
39 REPLIES 39

bcoulson
Champ in-the-making
Champ in-the-making
Oh ok - thanks for the clarification. I am compiling against the 3.4.d community edition of Alfresco. It is a somewhat muddled as I have also compiled the full source locally when attempting to debug this issue, but prior to doing the build myself, I tried 3.4.c and then upgraded to 3.4.d but the behavior stayed the same.

mcook
Champ in-the-making
Champ in-the-making
I am packaging and deploying class using an ant script. I create a jar file and then explode that jar file into the <alfresco_root>/tomcat/shared/classes directory structure. The build script is based off the one from the someCo samples. Right now AlfrescoHelper is the only one that we actually have written as we are still in prototype/proof of concept mode.

While putting your jar in <alfresco_root>/tomcat/shared/classes may "work", I think using ./web-server/webapps/alfresco.war/WEB-INF/lib is the recommended/best practice place to put extensions/custom jars (this is what several sources say to use, including Alfresco's documentation, the Alfresco Developer Guide book, and a few various websites).  To do this, you'll have to explode the alfresco.war (essentially unzip it).  It is a good idea to keep the folder name exactly the same as the war name, ie it should be "alfresco.war".

One thing I found interesting is that I had to put the following jar files in the  C:\Alfresco\tomcat\shared\lib directory, otherwise I received ClassNotFoundException error when I tried to access my class.
    alfresco-core-3.4.d.jar
    alfresco-repository-3.4.d.jar
    commons-logging-1.1.jar
    jbpm-jpdl.jar
    org.springframework.beans-3.0.0.jar
    springmodules-jbpm31.jar
I found this odd as they are in the <alfresco_root>/tomcat/webapps/alfresco/lib directory already. As I am writing this, I am wondering if this may be my problem - do I have the right jar files here? Am I missing some? Why do I need to include them here?

You should not have to include those jar files at all because they are included in the war.  Part of the issue may be the sdk/api you are using.  If the version you are using (if correctly stated in your profile) is 3.4.c, then at least some of those jars are for the wrong version (ie version d).  I would remove all of those added jars and download the proper sdk.  If you are using version 3.4.c you can get it here:

http://process.alfresco.com/ccdl/?file=release/community/build-3335/alfresco-community-sdk-3.4.c.zip

or go to http://wiki.alfresco.com/wiki/Community_file_list_3.4.c and go down to the sdk heading.

You'll need to update your eclipse build config to include this sdk.  If you have imported any of those jars into eclipse, I suggest that you remove them first and then import the 3.4.c sdk.  After that you should be good to compile and deploy your custom jar.  You should not have to add any of these jars in the 3.4.c sdk to the alfresco directories - they should already be there.

Here is my directory structure.

C:\Alfresco\tomcat\shared\classes\alfresco\extension:
someco-model-context.xml
scWorkflow.properties

C:\Alfresco\tomcat\shared\classes\alfresco\extension\model
scWorkflowModel.xml

C:\Alfresco\tomcat\shared\classes\alfresco\extension\workflow\PublishDocument
processdefinition.xml

This all looks fine and based on our past interactions - ie it should be working as intended.

Thank you for your persistence in trying to solve this issue.
Brenda

Not a problem.  I am glad to be of assistance.  We have gone through many pain points with alfresco primarily because back when we started using it, the documentation and resource was slimmer/sparser.  Things are better today; however, they still are not perfect.  While we have the luxury of alfresco's enterprise support now, we didn't always have it.  And there were many times in the past I wished I had help.  I had to figure out a lot on my own.  After gaining some experience, I figured I should help others get passed their problems so they don't have to go through what we had to go through.  For a while I was not fond of the software, but once I figured its "ins" and "outs" I have come to enjoy using it.

bcoulson
Champ in-the-making
Champ in-the-making
Ok - to make sure I understand your recommendation, I should  explode the alfresco.war into a directory called alfresco.war off webapps and put my files there? Everything I have read says to put extensions in shared/classes/alfresco/extension - is that only applicable for configuration and customization files and not my java files? It sounds like it. So I already have a directory alfresco under webapps, which is basically the alfresco.war unzipped from the install - so I do NOT put my files here, but rather in a separate directory off webapps called alfresco.war which would contain duplicate files to webapps/alfresco. Is that correct?

Regarding the SDK, I do have the SDK installed and setup as projects in my Eclipse workspace, however I could not find all the supporting jars in the SDK directory structure - I could find the alfresco jars, but not the spring and jbpm jar files there. 

I am definitely using 3.4.d now - I was originally using 3.4.c and I upgraded and now that you mention it, I am not sure I updated my SDK as well. I will do that.

But I will wait to hear back from you regarding webapps structure suggestion.

I have been researching Alfresco since early January for inclusion in our project and the learning curve is pretty steep - I understand it is because it offers ALOT of  functionality/features and it achieves that through a customizable framework. The model is quite different from what I am accustomed to so there is a learning curve there. I do see the potential for it to work really well within our organization.

mcook
Champ in-the-making
Champ in-the-making
Ok - to make sure I understand your recommendation, I should  explode the alfresco.war into a directory called alfresco.war off webapps and put my files there? Everything I have read says to put extensions in shared/classes/alfresco/extension - is that only applicable for configuration and customization files and not my java files? It sounds like it. So I already have a directory alfresco under webapps, which is basically the alfresco.war unzipped from the install - so I do NOT put my files here, but rather in a separate directory off webapps called alfresco.war which would contain duplicate files to webapps/alfresco. Is that correct?

the shared/classes/alfresco/extension folder is for "configuration" extensions.  For instance, model definitions, workflow definitions, context configurations, Alfresco Explorer UI additions/overrides, etc.  All jar files will need to go into webapps/alfresco.war/WEB-INF/lib.  Also, on a side note, once the war is exploded and you now have alfresco in a directory, the original war file should be moved/removed.

Here are some direct quotes from the Alfresco Developer's Guide by Jeff Potts (Ch 2) to help you out:

Once they are packaged, you have three options for deploying them as part of the Alfresco web application:
•   Copy your files on top of an exploded Alfresco web application.
•   Integrate your files with the Alfresco WAR, which you then deploy.
•   Package your changes as an Alfresco Module Package (AMP) file. The AMP is then installed in—merged into—an Alfresco WAR, which is then deployed to the application server.
The Java classes you develop as a part of your customization will go into a JAR file. The JAR file will reside in the WEB-INF|lib of the Alfresco web application. Therefore, you should name it such that it is easy to spot among the hundred or so JAR files distributed as part of Alfresco. Similarly, any tag libraries that you develop will reside in WEB-INF alongside Alfresco's taglibs.
Custom JSP pages should be kept separate from Alfresco's to make them easier to identify. One way to do this is to create an extension directory under jsp, but it is completely up to you. The same goes for scripts, images, and CSS.

Take away: Custom jars go into the exploded web application (…/alfresco.war/WEB-INF/lib

Like Spring, JSF relies on XML files to configure the framework. Alfresco's JSF files reside in the WEB-INF directory, and all begin with "faces". Custom JSF components and navigation rules are declared in a faces configuration file. Unfortunately, there is not as much flexibility in the location of your JSF configuration files as there is with Spring. For JSF, it comes down to two choices: WEB-INF|faces-config-custom.xml or faces-config.xml in META-INF within a JAR file that resides in Alfresco's WEB-INF|lib directory. Which one you use depends on what you are trying to do. If you are overriding Alfresco's existing JSF navigation rules, you have to go the META-INF route. If you are overriding Alfresco's existing JSF component declarations, you have to go the WEB-INF route. If you aren't overriding anything, you can pick either.

Take away: JSF faces config goes into …/alfresco.war/WEB-INF or in the META-INF in a jar.

Not all configurations are handled through standard frameworks such as Spring and JSF. Some configuration changes are made using properties files or Alfresco configuration XML. For example, the most commonly customized properties file is custom-repository.properties. In it, you can find things such as the username and password used to connect to the underlying relational database, the database driver, and the data directory file path. Like the Spring files, there are sample properties files in the extensions|extension directory of the Alfresco distribution.

Take away: xml configs (model definitions, workflow definitions, alfresco config overrides) and properties files should go in the extensions folder.

Hope this helps!

mcook
Champ in-the-making
Champ in-the-making
Not mentioned in my previous post but may be helpful to you in the future:

jsp files go into …/alfresco.war/jsp/

They cannot (as of yet) be packaged in a jar.

mcook
Champ in-the-making
Champ in-the-making
Oh and one more thing.  Custom model context files always go into the extension folder… It CANNOT go into any of the subdirectories.  Alfresco does not check for that.

ie someCo-model-context.xml

bcoulson
Champ in-the-making
Champ in-the-making
Thank you very much - this is very helpful. I do have Jeff Pott's ebook and obviously skimmed over that piece regarding putting jar files into the webapps directory and NOT the shared/classes/extension. I also was under the impression that Spring context files could go anywhere on the classpath, aka under shared/classes/alfresco/extension. The JSF piece does not apply to me as we are using Share and which uses FreeMarker Templates and Surf rather than JSF.

One final question/clarification - so my exploded Alfresco war is in webapps/alfresco - do I put my files under that root or make a separate root off webapps that is alfresco.war? I am guessing the former, otherwise I will have duplicate web applications.

I will not be able to get to this today, but will look at it over the weekend or first thing monday morning. Thank you.

mcook
Champ in-the-making
Champ in-the-making
After exploding the war (naming the root 'alfresco' in this case) you should see in the webapps directory:

alfresco <– all your jars will go under this directory in WEB-INF/lib.  It also should be renamed to alfresco.war after the actual war file is moved.
alfresco.war <– this file needs to be moved (in case you wish to keep it for future reference) or removed
share.war

bcoulson
Champ in-the-making
Champ in-the-making
Thank you very much - my issue has been resolved. I simply moved my JAR file into tomcat\webapps\alfresco\lib and it worked!

mcook
Champ in-the-making
Champ in-the-making
Great!!  I am glad it is working!