Java service coding practice discussion.

Hi Gurus…

I am curious on better coding practice for Java services. I would like to throw some ideas to you, to start and would love to hear your comments.

I have created java service using two different styles. Below is my test service examples for both.

Style 1. Create code using Tools=> Generate Code
Code created using this style is as below.

// pipeline
IDataCursor pipelineCursor = pipeline.getCursor();
    String    testin = IDataUtil.getString( pipelineCursor, "testin" );
pipelineCursor.destroy();

// pipeline
IDataCursor pipelineCursor_1 = pipeline.getCursor();
IDataUtil.put( pipelineCursor_1, "testout", testin );
pipelineCursor_1.destroy();

Advantages :
1. Ease of code creation.
2. Cursor is immediately destroyed (pipelineCursor.destroy():wink: after getting data of the pipeline to local variables. This can be significant for complex and heavy java service.
need more from you guys…

Style 2. Hand craft you java service.

IDataCursor c =  null;
try
{
    c = pipeline.getCursor();    
    String    testout =  null;
    if(c.first("testin"))
        testout = (String)c.getValue();     
    c.insertAfter("testout", testout);
}
catch(Exception e)
{
    throw new ServiceException(e.toString());
}
finally
{
    if(c != null)
                c.destroy();
}

Advantages :
1. Only one instance of cursor to for whole service. (not sure if this is good or not…)
2. Not using IDataUtil at all…(again not sure if this is good or not…!!)

Question I have are

  1. Which one is efficient from performance point of view.
     String    testin = IDataUtil.getString( pipelineCursor, "testin" );
 Or
     if(c.first("testin"))
        testout = (String)c.getValue();     
  1. If I throw service exception in catch block as throw new ServiceException(e.toString()); will it still go to finally block and destroy the cursor???
  2. Most of built in WM Java services uses Style 2. Does that mean its better practice or they are using different IDE to create java service…???

Please throw your idea and though on this and also let me know if there is any other Style or Practice is there for Java Services???

Cheers,
Ajit

  1. Java services are to be avoided. But if you must create them…
  2. I don’t know which approach is more efficient–I’ve never come across a case where profiling indicated that this is a meaningful bottleneck so have never investigated since the time savings of one over the other.
  3. Yes. Java guarantees that the finally block will executed no matter the exit path from the method.
  4. This pure speculation on my part, but IMO most of the wM-built Java services were created before IDataUtil existed. A lot of them still use the old Values class/interface.

I have Developer generate the service for me. Then I modify it to use just one cursor. I only use try/catch/finally when needed and I never catch Exception–I always catch the specific exception class.

My two cents.

Thanks Rob for your tow cents… its all worth it… I agree on

  1. Java services are to be avoided. But if you must create them…

I have to create Java Service for my custom TN web. I wrote service similar to wm.tn.query:createDocumentQuery which doesnt support, from/to date… multiple Sender Receiver and Multiple Doc Type to be specified to create query…:)… Has any one try this?? I know it can be a seperate thread :)…

Cheers,
Ajit

I’ll bet you that you don’t “have to create Java service” and that you can achieve what you need using FLOW.

[FONT=Tms Rmn]Okay here is the requirement.

I want to create Transaction Analyses Screen similar to WmTNWeb.[/font] But need ability to search for selection of Multiple Document type. i.e. Give me transactions for DocType A and Doc Type B, Multiple partner selection etc…
[FONT=Helv][SIZE=2]
I can invoke wm.tn.query:createDocumentQuery multiple time and append result, but they will not be in right sort order… that means I will have to use some short doclist shorting service…(again java !!)

That why I have built custom java service to createDocumentQuery which allows to pass DocTypeID as list etc…

How can I achieve this using flow services??

Cheers,
Ajit
[/size][/font]

I was being a bit too literal. I was pointing out that you don’t “have to” write the query service in Java, meaning that writing it in Java isn’t the only way.

While you can write the solution in FLOW it may not be the best approach. Personally, I’d probably do it in FLOW, calling createDocumentQuery/executeQuery multiple times and then using a sort service that I already have. The sort service is in Java, used in multiple contexts. This minimizes the amount of Java and IMO better facilitates debugging and maintenance.

But for your situation, writing the entire query service in Java may be the better way.

Thanks Rob,

I agree with you… I am not big fan of java services. I do it only when I have to… I am from .Net background anways :)…

I also have requirement for search based on From Datetime and To Datetime which is not there in built in API :(…

So back to original question… When we HAVE to write java service, which one is better practice ?? :slight_smile:

Cheers,
Ajit

Ajit,

I think you have 2 questions here.

  1. When to destroy the pipelineCursor object. Is it better to destroy the pipeline Cursor after retrieving the input or live it there till you finish processing and assigning the output.

As java uses objects reference rather than values when defining an object like pipelineCursor. The overhead of carrying and not carrying the pipelineCursor object is not that tolling to the performance. Personally I agree with Rob too. We should leave the template code developed by developer and work around with it if possible. This way you are not carrying any object which is not required.

  1. How to retrieve input parameters from cursor?

I personally think we should try to use the IDataUtil way, but would like to know what the experts think about it.

Ram Challuri

Thanks for your Input Ram.

So far we have 2 votes for webMethods generated code and also use IDataUtil to retrive input variables.

Any other comments…!!

Cheers,
Ajit

Depends on what you are trying to achieve. There are performance bottlenecks while looping and comparing (even with a clean flow ), which can be avoided using JavaService

I don’t like the generated code because its variable names are too long. I like to name the cursor on the pipeline “idc” and then name my other IDataCursor variables “idcFoo” where Foo helps me know which IData the cursor is pointed to.

I do use IDataUtil when I am getting anything out of the pipeline other than a String.

I keep my idc IDataCursor until the end of the java service when I insert the output variables.

One downside to this is that any exception before the end of the service would not destroy the pipeline cursor.

BTW, why is it so bad to not destroy IDataCursors when we never seem to need to explicitly destroy or nullify other objects or variables? Is it because by keeping a reference to an IData that the entire IData is prevented from being cleaned up by GC?

Mark