A co-worker of mine ran into a nasty bug the other day when working on some code that linked to the vSphere4 client’s VIClient assembly. He was using the following method to load a graphic VMware bundled as a resource:
When the code was executed on any version of the vSphere client prior to 4.1 an error message appeared:
Clearly there was some fishy business afoot as the same code worked flawlessly only a couple of weeks prior. It turns out that the problem was due to the changes I had made on the build server. When my co-worker built the same code locally it worked fine on vSphere Clients 4.0 U1, 4.0 U2, and 4.1. However, the artifact produced by the build server would only work on 4.1. This is because despite the VMware assemblies my co-workers link to at design time, I use the MSBuild ReferencePath property to build their code against the VMware assemblies I specify. At the end of September I configured the Maven POMs to reference VMware’s latest assemblies, of the 4.1 variety. And it turns out this was much more a major change than I had previously expected. VMware has always strongly-named most of their assemblies. With one major exception:
This is what
Lutz’s Red Gate’s Reflector shows when reflecting VIClient.dll version 220.127.116.11 (4.0 U2):
// Assembly VIClient, Version 18.104.22.168 Location: C:\Program Files\VMware\Infrastructure\ Virtual Infrastructure Client\4.0\VIClient.dll Name: VIClient, Version=22.214.171.124, Culture=neutral, PublicKeyToken=null Type: Library
Notice that the PublicKeyToken field in the assembly’s name is null. This means that this version of VIClient.dll is not strongly-named. Here is the same assembly for version 4.1:
// Assembly VIClient, Version 126.96.36.199 Location: C:\Program Files\VMware\Infrastructure\ Virtual Infrastructure Client\4.1\VIClient.dll Name: VIClient, Version=188.8.131.52, Culture=neutral, PublicKeyToken=7c80a434483c7c50 Type: Library
The PublicKeyToken field now has a value of 7c80a434483c7c50. It seems VMware finally got around to strongly naming the VIClient assembly. What does this mean for developers?
- If you link to version 4.1 of the VIClient assembly when you compile your assembly, that exact assembly must be loaded/available to the AppDomain when your code loads.
- Code that is compiled against the 4.1 version of the VIClient assembly is not backwards compatible with previous versions of the vSphere client since previous versions did not strongly name VIClient.dll.
In short — Don’t link against VMware’s internal assemblies. Or if you do, do it using late-binding at runtime by using all reflection all the time.
Hope this helps!