cancel
Showing results for 
Search instead for 
Did you mean: 

BPM API 7.3 get READY/RESERVED tasks for a user - Mobilize my BPM

0 Kudos

I am trying to create a SUP mobile application in order to approve/reject a task from my BPM process. So, I am trying to create a EJB in order, first to fetch all the ready and reserved task for a user in order to create the .wsdl to call it from the SUP.

I cannot find an example/tutorial of how to do this. I wrote the code:

public class HelloBean  {

 

 

          @WebMethod(operationName = "getMyTasks", exclude = false)

          public String getMyTasks() {

 

                    String testres = null;

                     try {

 

                              TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager();

 

  HashSet<Status> statuses = new HashSet<Status>();

                              statuses.add(Status.READY);

                              statuses.add(Status.RESERVED);

                              statuses.add(Status.IN_PROGRESS);

                        

                              Set<TaskAbstract> myTasks = taskInstanceManager.getMyTaskAbstracts(statuses);

                              testres = myTasks.toArray(new TaskAbstract[0]).toString();

                              }

                              catch (Exception e) {

                              }

                              return testres;

            }

}

I tried several other ways but I always get an empty list as a result. Can anyone help me on how can I create an EJB that will take as an input the user and will bring me the READY/RESERVED tasks assigned?

Please note that the RESTful services from the code exchange project are not a solution because the application will be used in a productive system.

Thanks in advance

Accepted Solutions (1)

Accepted Solutions (1)

0 Kudos

I tried the way Stefan suggested (or I think he suggested) .What I did was

To create a SC and inside the SC I created 2 DC one of type EJB Module and one of type Enterprise Application

I tried the way Stefan suggested (or I think he suggested) .What I did was

To create a SC and inside the SC I created 2 DC one of type EJB Module and one of type Enterprise Application

I added the dependencies as below. For my test/bpmapi/ear

For my test/bpmapi/ejb

In my ejb I have two classed, one for getting the logged username after entering the user/pass authentication and one for getting the tasks for the logged user

If I test my getUsers() class everything is ok.

If I try to get the tasks for the user with the code I pasted in above posts, I get an exception message:

Web service returned error. Fault Code: "(http://schemas.xmlsoap.org/soap/envelope/)Server" Fault String: "javax.ejb.EJBException: nested exception is: java.lang.RuntimeException: java.lang.NoClassDefFoundError: com/sap/bpm/api/BPMFactory"

In the deployment log I have some warning and if I open them I have a loooooooooong list with at com.sap.engine.... faults BECAUSE OF

Caused by: java.lang.NoClassDefFoundError: com/sap/bpm/exception/api/BPMException

Any helpful idea? The problem is the way I have added the dependencies?

UPDATE

I added the dependencies to the ear file and now it is ok!!! If I test it using a counter I can count the ready/reserved tasks for the logged user

The problem is now how to get them as an Array

public ArrayList getTasks()  { 

                     

        ArrayList testList = new ArrayList(); 

        int test = 0;

        try{

       

           TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager(); 

           HashSet<Status> statuses = new HashSet<Status>(); 

           statuses.add(Status.READY); 

           statuses.add(Status.RESERVED); 

           statuses.add(Status.IN_PROGRESS); 

           Set<TaskAbstract> myTasks = taskInstanceManager.getMyTaskAbstracts(statuses); 

           Iterator<TaskAbstract> taskIter = myTasks.iterator();  

       

        while(taskIter.hasNext()){  

       

              TaskAbstract ta = taskIter.next();                   

              java.net.URI taskInstanceId = ta.getId();                  

              URL taskExecutionURL = taskInstanceManager.generateTaskExecutionUrl(taskInstanceId);   

              TaskDetail taskDetail = taskInstanceManager.getTaskDetail(taskInstanceId);  

              testList.add(taskDetail);     

              test++;

             

                            } 

                  } 

                  catch (BPMException e){ 

                                                //return 0; 

                  } 

                            return testList; 

                    }

If I try the above code I get the following exception:

Web service returned error. Fault Code: "(http://schemas.xmlsoap.org/soap/envelope/)Server" Fault String: "com.sap.engine.services.webservices.espbase.server.additions.exceptions.ProcessException: Connection IO Exception. Check nested exception for details. (Exception; nested exception is: javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class com.sap.bpem.tm.impl.TaskDetailImpl nor any of its super class is known to this context.])."

Any idea?

stefan_henke
Contributor
0 Kudos

Hi,

the issue you are facing is that your webservice is returning directly the objects returned by the BPM API. The webservice runtime only supports objects that can be transformed into xml using JAXB. However, the TaskDetail interface (resp. its implementation) is not annotated as JAXB entity and thus does not allow the transformation. You have to create your own wrapper object that is returned by your webservice or provide a custom serializer (unfortunately, I don´t know how to do this).

You might take a look at the REST wrapper on CodeExchange. It is also covered there in a similar way.

Best regards,
Stefan

0 Kudos

Thanks a lot Stefan. It seems a tough task to build on BPM API. I finally managed to write classes to return the needed arguments one by one. (one array for the taskid, one for the presentation name etc)

Thanks again for your help. When I find time I will write a short tutorial on how to create webservices to use BPM APIs capabilities

Former Member
0 Kudos

Hello Alexandros,

Did you find any useful information about exposing BPM Task as WS? I am facing the same issue and I would really appreciate your help on this.

Thanks and regards.

0 Kudos

Hello Robert,

Yes, I managed to do it. Have you followed the discussion? I did all the above plus setting the authentication from NWA

NWA - SOA - Application and Scenario Configuration - Single Service Adminstration. I found the Web Services I have created and then I set the authentication to HTTP Authentication - User ID/Password


Also, search for jax-ws to see how you can get the response from the WS as xml response. If you need any specific help please let me know

Former Member
0 Kudos

Thanks Alexandros,

I've managed to retrieve the tasks as array of custom java class.

But the WS that I have generated acts quite strange...sometimes retrieves all the tasks, sometimes only one task, sometimes no task at all. Did it happen also to you? Do you know if it's a cache issue?

Thanks in advance.

Robert

0 Kudos

Hello Robert,

Are you testing the WS from the NWA? I didnt have any problems. If you test it from NWA, for sure it isnt a cache issue. The case is that you try to fetch the tasks of the UWL for the logged in user?

I think something goes wrong with the source code

Former Member
0 Kudos

Hi Alexandros,

Yes I'm testing it from WS Navigator of the NWA for the logged user. As for the source code, it's exactly the same as mentioned before, I have included just a custom class with some String attributes and change the return type to ArrayList<custom_class>.

Former Member
0 Kudos

Hi Robert,

You should start a new thread with this question as this thread is already marked 'Answered' by Alexandros and your different problem might not get so much attention. I will say from experience that you are best off sticking to the java types as defined in the API (List or ArrayList) especially while you are first working with the API. I will also add that BPM APi development is easier if you begin with your WSDL and then using the EJB web-service wizard to generate the EJB top-down. This way you have all the getters and setters made for you and your typing is accurate (as long as the WSDL typing is accurate). When I create WSDLs for the API I simply refer to the Javadocs to ensure the typing is proper. What's left then is only the implementation code for your operation.

regards, Nick

Answers (2)

Answers (2)

0 Kudos

Thanks to your help now I managed to set the authentication. So, a popup appears every time I run the webservice to get the logged user and it works correctly.

But I still cannot get the tasks for the logged user!!! I have tried everything. Even if I test this simple code I have problems:

    @WebMethod(operationName = "getTasks", exclude = false)

          public void getTasks() throws BPMException   {

                    TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager();

    }

When I test it I always get this error message:

Web service returned error. Fault Code: "(http://schemas.xmlsoap.org/soap/envelope/)Server" Fault String: "javax.ejb.EJBException: ASJ.ejb.005044 (Failed in component: sap.com/HelloWorldEJBEAR) Exception raised from invocation of public void com.sap.tutorial.helloworld.HelloBean.getTasks() throws com.sap.bpm.exception.api.BPMException method on bean instance com.sap.tutorial.helloworld.HelloBean@363624e5 for bean sap.com/HelloWorldEJBEAR*annotation|HelloWorldEJB.jar*annotation|HelloBean in application sap.com/HelloWorldEJBEAR.; nested exception is: java.lang.ClassCastException"

I have tried every possible code solution to get the tasks but no luck!With debbuging if I add a try/catch statement it always goes to the catch!!!

What can be the problem?Is it the code or some setting?

PS1) . Every time I try to create the webservice from the EJB, when I add the .. throws BPMException  I cannot expose the method to webservice because I get the below error message

Class com.sap.bpm.exception.api.BPMException does not have a default constructor

PS2)

The javadocs say that

To be able to use the BPM APIs, you need to add to your project the necessary dependencies to the following development component:

  • tc/bpem/facade/ear (public part api) in software component BPEM-FACADE.
  • tc/je/sdo21/api in software component ENGFACADE.

The only thing I did was to add to my EJB project the 2 .jar files. Do I have to do something more???

Sorry for the long text but I cannot find what is going wrong

stefan_henke
Contributor
0 Kudos

Hi,

can you post the full excepion stacktrace you are getting? In your sample, you have an empty catch block which makes it hard to figure out what the actual problem is.

One remark to your last statement mentioning the DC dependencies.In your EJB project, you have to have the described dependencies. However, the EAR project which assembles the EJB project needs these dependencies as well with flavor 'runtime'.

Best regards,

Stefan

0 Kudos

Hello Stefan. Let me summarize what I did. (I am trying to get the tasks for the logged in user using a webservice)

1) I created an EJB project and then an EJB Session Bean 3.0 like an HelloWorld example in order to publish it as an webservice.

2)I added the necessary .jars (tc~bpem~facade~ear~api.jar , tc~je~sdo21~api.jar and some others)

3) I wrote the code below

@AuthenticationDT(authenticationLevel = AuthenticationEnumsAuthenticationLevel.BASIC)

@WebService(name = "Hello", portName = "HelloBeanPort", serviceName = "HelloService", targetNamespace = "http://sap.com/tutorial/helloworld/")

@Stateless(name="HelloBean")

               public class HelloBean {

                             @WebMethod(operationName = "getTasks", exclude = false)

                                      

                                         public ArrayList getTasks()  {

                                                   ArrayList testList = new ArrayList();

                                                           try{

                                                      TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager();

                                                      HashSet<Status> statuses = new HashSet<Status>();

                                                      statuses.add(Status.READY);

                                                      statuses.add(Status.RESERVED);

                                                      statuses.add(Status.IN_PROGRESS);

                                                      Set<TaskAbstract> myTasks = taskInstanceManager.getMyTaskAbstracts(statuses);

                                                       Iterator<TaskAbstract> taskIter = myTasks.iterator();

                                 while(taskIter.hasNext()){            

                                                         TaskAbstract ta = taskIter.next();                 

                                                         java.net.URI taskInstanceId = ta.getId();                

                                                         URL taskExecutionURL = taskInstanceManager.generateTaskExecutionUrl(taskInstanceId); 

                                                         TaskDetail taskDetail = taskInstanceManager.getTaskDetail(taskInstanceId);

                                                         testList.add(taskDetail);    

                                                                     }

                                          }

    catch (BPMException e){

         //return 0;

         }

    return testList;

    }

4) I published it as a webservice and I also set the authentication to http mode, so every time I try to run it it prompts me with a popup asking for user/pass . Then the login is successful but I always get an exception

 

     Web service returned error. Fault Code: "(http://schemas.xmlsoap.org/soap/envelope/)Server" Fault String: "javax.ejb.EJBException: ASJ.ejb.005044 (Failed in component:      sap.com/HelloWorldEJBEAR) Exception raised from invocation of public void com.sap.tutorial.helloworld.HelloBean.getTasks() throws      com.sap.bpm.exception.api.BPMException method on bean instance com.sap.tutorial.helloworld.HelloBean@363624e5 for bean      sap.com/HelloWorldEJBEAR*annotation|HelloWorldEJB.jar*annotation|HelloBean in application sap.com/HelloWorldEJBEAR.; nested exception is:      java.lang.ClassCastException"

Even if I try only to write something very simple like

                   try{

                                                      TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager();

                    }

                   catch (BPMException e){

                           }

I get an exception.

Can anyone provide me with hints what can be the mistake? I am searching for days. I think the problem is not the code but I am missing something. When we say that I have to have the dependencies do I only have to add the .jar files to the EJB project or I have to do something else?

My EJB is not a SC but only an EAR project how can I add the dependencies. Is it a problem that if I go to the tc/bpem/facade/ear that some of them are red??(see attached image)

Can anyone try the code to test if it returns the tasks?

stefan_henke
Contributor
0 Kudos

Hi,

did you manually add the jar files to your EJB project? This is not the way it will work. The DC tc/bpem/facade/ear resp. tc/je/sdo21/api are exposing the jars as part of their public parts. You have to define them from your own DC. This way they can be looked up at runtime.

I attached a screenshot of an EJB DC having the correct dependencies. In addition, you have to add a dependency from your SC to the SC BPEM-FACADE.

Please take a look at the attached screenshots.

Hope this helps.

Best regards,
Stefan

0 Kudos

Hello again Stefan ,

I think I am developing the wrong way. I had created only o EJB project without any DC . I will convert my EJB project to Development Component and I will try to add the dependencies. My problem is that I cannot find some of the required DCs. Do I have to download them from the service marketplace as DCs and import them to my LocalDevelopment?

Thank you very much

stefan_henke
Contributor
0 Kudos

Hi,

using the NWDI component model based on SCs and DCs is mandatory to use the API of NetWeaver BPM. However, for local development everything is already pre-packaged in the NWDS (at least from the 7.30 release onwards). In the Development Infrastructure perspective, you see a config called 'Local Development' which contains all required DCs. Even if the DCs from BPEM-FACADE have some unresolved dependencies, this does not matter as you the DCs in BPEM-FACADE contain everything you need during compile time.

Only if you develop in a remote NWDI track, you have to manually import the BPEM-FACADE SC into the track. This you might have to download from SMP.

Best regards,
Stefan

0 Kudos

Although I think my code is correct I am stuck in the way to build and deploy a project in order to test it.

Firsty, I created an EJB Project and inside the project an Session Bean (EJB 3.x). I published my classes as webservice, and also I setup the authentication for them.

If I write a class to get the logged user, everything works well. I get a popup with user/pass and everything is ok. My problem is still to create a webservice in order to get the tasks for the logged user. As I understood I cannot do it the way I am trying(just adding the .jar files to my EJB project and publishing my EAR project to the server)

So, i created a new SC and then a new DC of type EJB Module. I added all the dependencies as above, I created a class with my code at the project and I successfully build my project. The problem is how to deploy and test my application! I cannot expose it as webservice and I cannot deploy it because the deploy option is gray.

Am I missing something or going the wrong way??? Although I know how to write the code I cannot find the way to create the webservice as described by Stefan

Thanks in advance

SandipAgarwalla
Active Contributor
0 Kudos

The problem is how to deploy and test my application! I cannot expose it as webservice and I cannot deploy it because the deploy option is gray.

Did you try this option for build and deploy

0 Kudos

obviously yes...I know how to deploy, my problem is how to create a SC or something to try to build using the BPM API.

The way i am trying as I used to create every web service(EJB Project - Session Bean and publish the webservice with the EAR project ) is not working. When I try to get the tasks for the logged users I always get the exception below

Web service returned error. Fault Code: "(http://schemas.xmlsoap.org/soap/envelope/)Server" Fault String: "javax.ejb.EJBException: ASJ.ejb.005044 (Failed in component: sap.com/TestApiBPMEAR) Exception raised from invocation of public java.util.ArrayList com.sap.tutorial.TestApiBPM.TestApiBPMBean.getTasks() method on bean instance com.sap.tutorial.TestApiBPM.TestApiBPMBean@1b90cca0 for bean sap.com/TestApiBPMEAR*annotation|TestApiBPM.jar*annotation|TestApiBPMBean in application sap.com/TestApiBPMEAR.; nested exception is: java.lang.ClassCastException"

Former Member
0 Kudos

Hello Alexandros/stefen,

How did you move the .ear to the a local development component DC? i have created the ejb (from new>project>ejb project) and while i created the .ejb i created the .ear file along with it . BUT i then moved/converted the ejb into a local DC, so that i can assign the dependencies (to use the BPM API). it works fine till that point . but i cannot move the .ear into the local swc DC therefore cannot see the ear file in the infrastructure perspective. please can some one help me with this and let me know the steps you follwed . thanks and appreciate it.

Regards,

tarik parkar

SandipAgarwalla
Active Contributor
0 Kudos

have you set the baseurl in the nwa, which will point to your server name?

NWA -> config -> infra -> java properties -

tc/bpem/base/earhttp.baseurlhttp://<yourhost>:<yourport>
0 Kudos

yes is it set i do not think this is the problem. But although i can see that it is configured correctly at the nwa, inside the NWDS I get some red at depedencies that I do not know what they are

SandipAgarwalla
Active Contributor
0 Kudos

Ok..I am assuming you have provided the correct user authorization.

I would probably change the code a little bit to see if that helps

Set<TaskAbstract> myTasks = taskInstanceManager.getMyTaskAbstracts(statuses);

          Iterator<TaskAbstract> taskIter = myTasks.iterator();

//                              testres = myTasks.toArray(new TaskAbstract[0]).toString();

          while(taskItel.hasnext()){          

               TaskAbstract ta = taskIter.next();               

                 // build the task url

                     java.net.URI taskInstanceId = ta.getId();              

                URL taskExecutionURL = taskInstanceManager.generateTaskExecutionUrl(taskInstanceId);

             TaskDetail taskDetail = taskInstanceManager.getTaskDetail(taskInstanceId);

               // build mobile list from ta object

          }

               

              }

                              catch (Exception e) {

                              }

                           

0 Kudos

I tried to create this class...

public ArrayList getMyTasks() {

                    int testres = 0 ;

                    ArrayList testList = new ArrayList();

                    try {

                              TaskInstanceManager taskInstanceManager = BPMFactory.getTaskInstanceManager();

                              HashSet<Status> statuses = new HashSet<Status>();

                              statuses.add(Status.READY);

                              statuses.add(Status.RESERVED);

                              statuses.add(Status.IN_PROGRESS);

                              Set<TaskAbstract> myTasks = taskInstanceManager.getMyTaskAbstracts(statuses);

                  Iterator<TaskAbstract> taskIter = myTasks.iterator(); 

                    //    testres = myTasks.size();

                  while(taskIter.hasNext()){            

                  TaskAbstract ta = taskIter.next();                 

                 // build the task url 

                  java.net.URI taskInstanceId = ta.getId();                

                  URL taskExecutionURL = taskInstanceManager.generateTaskExecutionUrl(taskInstanceId); 

                  TaskDetail taskDetail = taskInstanceManager.getTaskDetail(taskInstanceId);

                  testList.add(taskDetail);

                  }

                    //          testres = myTasks.toArray(new TaskAbstract[0]).toString();

                              }

                              catch (Exception e) {

                              }

                                        return testList;

            }

}

...But I still get an empty list. I try to run my EJB with the .wsdl with a connected user that has some tasks in the UWL but the return is 0.

0 Kudos

I want to add that I tried first to run this code

public String getLoggedInUserName() {

 

                                        IUser user = UMFactory.getAuthenticator().getLoggedInUser();

                                        String firstName = user.getFirstName();

                                        String lastName = user.getLastName();

                                        String userName = firstName != null ? firstName + " " + lastName: lastName;

                                        return userName;

                              }

 

 

}

And the result is always Guest(that is a locked user!!!). What can be the problem? I am testing using the webservice that I developed in an EJB Project- Session Bean 3.0

SandipAgarwalla
Active Contributor
0 Kudos

Ok, so the problem is not the code but the user authentication. The Guest user is not a locked user, its an anonymous user for the Portal....issue is with the authentication, you are not getting the logged in user in the EJB..

How have set the authentication for the web service?

Sandip

stefan_henke
Contributor
0 Kudos

Hi,

as Sandip pointed out, it is essiential to provide authentication for the webservice. This allows you to run the task query for this user.

Here is a link to the official documentation for the 7.3 release about webservice authentication:

http://help.sap.com/saphelp_nw73/helpdata/en/49/9d40514f133eeee10000000a421937/frameset.htm

This might help.

Best regards,

Stefan

0 Kudos

What I am trying to do is call the wsdl from SUP with input the user/pass and to get as a result the task ids.

But how can I setup the authentication in my EJB session bean in order to test if the code I have writen is correct? Even a hard coded solution is ok for now.

thanks