After the vSphere Java API 5.0 beta was released, I got a very interesting bug that I think is worthwhile to share with the community. Note that I used the word “interesting.” It turned out to have no solution logically, but quite easy to work around and patch up. The workaround addresses only particular issue but does not prevent similar bugs from happening in the future.
Confused? Let’s take a quick look at the bug report:
Bothered by SLOW Web UI to manage vSphere? Want to manage ALL your VMware vCenters, AWS, Azure, Openstack, container behind a SINGLE pane of glass? Want to search, analyze, report, visualize VMs, hosts, networks, datastores, events as easily as Google the Web? Find out more about vSearch 3.0: the search engine for all your private and public clouds.
This was observed with the 2.1 version. This is a type that was observed in the EventEx for storage redundancy lost/restored. I have verified that on adding the type, the error is resolved. Attaching the file I added
at java.security.AccessController.doPrivileged(Native Method)
at java.lang.Class.forName0(Native Method)
at EventTest.main(EventTest.java:33) Exception in thread “main” java.rmi.RemoteException: Exception in WSClient.invoke:; nested exception is:
at EventTest.main(EventTest.java:33) Caused by: java.lang.NullPointerException
A little clarification here: although observed in 2.1 but it’s really with vSphere 5.
The call stack clearly states that the type ArrayOfDatastoreEventArgument is missing. Naturally I first verified whether it’s actually defined in the com.vmware.vim25 package. After failing to find it, I checked the WSDL files of vSphere 5.0. To my surprise, it’s not there neither. You may be thinking: why not the WSDL files of vSphere 4.1 which corresponds to the version 2.1. A good question. To be compatible, vSphere API does not remove types therefore the vSphere 5.0 API should have all of 4.1. Therefore not finding it in 5.0 is sufficient to say it’s not in 4.1.
Now it becomes a puzzle why there is a type that not defined. Further thinking about the case which it happens, I dig down to the EventEx data object. As the API reference states, “EventEx is a dynamically typed Event class who type is indicated by its eventTypeId property.” It means this EventEx type is a super type for these whose type is to be decided later.
All the properties of the EventEx look good except the arguments which is KeyAnyValue. Within KeyAnyValue object, two properties defined: key as xsd:string; and value as xsd:anyType. The key should have caused no trouble because string type is defined and used a lot in the API. Now the second one could be problematic because it basically says it can be any type, including types that are not yet defined.
The question then becomes how you can know before hand what future concrete types the value will be. Logically it’s impossible! That is why I said early there is no solution to this.
To be clear, there are other places where xsd:anyType is used. But in these places, they are mostly strings or other types that have been defined in the WSDL files. Therefore it does not cause trouble. In this particular bug, ArrayOfDatastoreEventArgument type is not defined anywhere but leaked from the server side.
Because the exception is clear and specific, working it around is very easy – just add that type as other existing ArrayOfXXX types in the WSDL. As you expect, it worked. So if you are using VI Java API 5.0 GA, you should be covered.
But I know it’s not future proof. Similar problem can come up without control of client side. Possible solutions to this issue include specifying specific types in place of xsd:anyType, which is a bit late given that it’s already out; or limiting the possible types to only existing ones in WSDL; or proactively add more possible types into WSDL.