LotusScript Web Services and NullPointerException

by Bernd Hort,
assono GmbH, Standort Hamburg,

DominoDesigner_90x90.png

Recently I worked on a demo application for a customer to show how to use Web Service Consumer in LotusScript. At one point I got a java.lang.NullPointerException error. It took me quite some time to figure out the reason for this error. So this blog post should help anyone how might run in the same problem. Because frankly the solution was really simple once I had found it. smile.gif

I give you the summary first and the full technical explanation later in this blog post. So even if you are not interested in the details the main point to take away is:

LotusScript Web Services Consumer and Provider use internally Java and Java is case sensitive. If you do not obey this you might loose some hours of your life time chasing an error where no error is.

Here are the technical details.

One part of the demo were the different styles to use to generate the WSDL file from a Web Service Provider. There is a great article from IBM developerWorks Which style of WSDL should I use? on this topic. Highly recommended!

To be able to show the differences between RPC/encoded and Document/literal style I implemented two different Web Service Providers. Both providers had the same identical LotusScript code.

Then I implemented two Web Service Consumers just by importing the WSDL file from the previous generated Web Service Providers. Here are the two methods from the Web Service Consumers.

Web Service Consumer calling a RPC/encoded Web Service Provider
Web Service Provider RPC/encoded Settings

Function checkout_status(auftragnr As String) As String
  If Not IsDebugMode Then On Error Goto errorHandler
  On Error lsERR_NOTES_WSENGINE_UNINIT_METHOD_ARG Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_NOTINIT Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_ERROR Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_METHOD_ERROR Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_METHOD_FAULT Goto wsErrorHandler
  
  Let checkout_status = Service.Invoke("checkout_status", auftragnr)
  
  Exit Function
  
errorHandler:
  If HandleErrorWithContext(CreateErrorContext(Nothing,|auftragnr: "| & auftragnr & |"| )) = RESUME_NEXT_LINE Then Resume Next
  Call RethrowError()
  Exit Function
  
wsErrorHandler:
  If HandleErrorWithContext(CreateErrorContext(Nothing,|auftragnr: "| & auftragnr & |"| )) = RESUME_NEXT_LINE Then Resume Next
  Call CreateWebServiceLogEntry(Me, |auftragnr: "| & auftragnr & |"|, Nothing)
  Call RethrowError()
End Function

Web Service Consumer calling a Document/literal Web Service Provider
Web Service Provider Document/literal Settings

Function checkout_status(auftragnr As String) As String
  If Not IsDebugMode Then On Error Goto errorHandler
  On Error lsERR_NOTES_WSENGINE_UNINIT_METHOD_ARG Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_NOTINIT Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_ERROR Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_METHOD_ERROR Goto wsErrorHandler
  On Error lsERR_NOTES_WSENGINE_METHOD_FAULT Goto wsErrorHandler
  
  Let checkout_status = Service.Invoke("CHECKOUT_STATUS", auftragnr)
  
  Exit Function
  
errorHandler:
  If HandleErrorWithContext(CreateErrorContext(Nothing,|auftragnr: "| & auftragnr & |"| )) = RESUME_NEXT_LINE Then Resume Next
  Call RethrowError()
  Exit Function
  
wsErrorHandler:
  If HandleErrorWithContext(CreateErrorContext(Nothing,|auftragnr: "| & auftragnr & |"| )) = RESUME_NEXT_LINE Then Resume Next
  Call CreateWebServiceLogEntry(Me, |auftragnr: "| & auftragnr & |"|, Nothing)
  Call RethrowError()
End Function

Can you spot the difference? I guess it is easier after giving you the solution.

In the Document/literal version the line for actually calling the Web Service must be
Let CHECKOUT_STATUS = Service.Invoke("CHECKOUT_STATUS", auftragnr)
with capital CHECKOUT_STATUS.

I found out because I took the original generated code and enhanced it with some error handling. Since there could be not code without properly error handling. This is specially true for calling Web Service.

Since I'm a lazy programmer I copied the code from the one Web Service Consumer to the next not looking at the case. I was very confusing that the first Web Service Consumer worked and the second one returned a java.lang.NullPointerException.

After checking for all kind of reasons I finally started again with a new Web Service Consumer and then found the difference in the case.

The reason behind is the internal use of Java. While calling Service.Invoke in the background the Java Reflection API is used to find the corresponding method to call. Those two different WSDL styles lead to two different method names: checkout_status and CHECKOUT_STATUS. In LotusScript the case of a method name makes no difference. In Java it can mean you can spend hours looking for an error.

By the way if I had used Java in the first place to program the Web Service Consumer (or Provider) I would not have had this problem. wink.gif

Technical article JavaScript Java Development Other

Sie haben Fragen zu diesem Artikel? Kontaktieren Sie uns gerne: blog@assono.de

Do you want an individual solution? Contact us

More interesting entries

Any questions? Contact us.

If you want to know more about our offers, you can contact us at any time. There are several ways to contact us for a non-binding first consultation.

We don’t sell your data. 100% guaranteed. See: Privacy Policy
assono GmbH

Location Kiel (headquarters)
assono GmbH
Lise-Meitner-Straße 1–7
24223 Schwentinental

Location Hamburg
assono GmbH
Bornkampsweg 58
22761 Hamburg

Phone numbers:
Human resources department: +49 4307 900 407
Marketing department: +49 4307 900 402

E-Mail adresses:
contact@assono.de
bewerbung@assono.de