This post was authored by Ina Uzunova, Product Owner of vSphere Client SDK, and Vladimir Velikov, vSphere Client SDK Engineer.
The official vSphere Web Client SDK Documentation of vSphere 6.5 contains important best practices for developing your HTML based vSphere Client Plug-in which are explained in chapter “Best Practices for Developing Extensions”.
A common source of mistakes when building a vSphere Client plug-in is packaging: the way the final vSphere Client plug-in deliverable is built, released to end users and deployed in production environments.
There has been a number of error-prone techniques that were encountered with previous releases. The goal of this post is to address the most common pitfalls when packaging your plug-in and the negative impact those have on your plug-in’s design and operation.
vSphere Client plug-in structure
Each vSphere Client plug-in consists of the following elements:
- Plug-in manifest: the
plugin-package.xml
file where the plug-in defines its ID, version, general information and compatibility constraints. - Set of plug-in bundles: the
plugins/
folder with the plug-in UI bundle (.war), the plug-in Java service bundles (.jar) and all external library bundles (.jar) the plug-in depends on.
These .war and .jar files need to be correctly defined OSGi bundles with a validMANIFEST.MF
.
Common plug-in packaging mistakes
Here are a few common plug-in packaging mistakes with their impact and improvement recommendation:
A) Errors in the plug-in manifest metadata (plugin-package.xml
)
- Using wrong company name – “id” and “vendor” attributes do not refer to the correct company name
- Error example:
<pluginPackage id="com.mycompany1.myplugin" version="1.0" vendor="MyCompany2">
- Impact: The plug-in is displayed with wrong information on the UI and might clash with the “id” of another plug-in.
- Recommendation: use your company name for all “id”-s in the plug-in.
- Error example:
- Dependency on another plug-in – “pluginPackage” dependency tag refers to a plug-in which is not part of vSphere Client
- Error example:
<dependencies><pluginPackage id="com.mycompany2.plugin2" version="1.0"></dependencies>
- Impact: The plug-in lacks integrity and autonomy. The target plug-in might not exist in the system but even if it does it now lives in its own dependency scope (in isolation) which makes it inaccessible by your plug-in. As a result your plug-in might fail during deployment or at runtime.
- Recommendation: Depend only on vSphere Client plug-ins (e.g. “
com.vmware.vsphere.client
”)
- Error example:
- Dependency on plug-in bundles – “pluginPackage” dependency tag refers to a plug-in library or OSGi bundle
- Error example:
<dependencies><pluginPackage id="com.vmware.vim25" version="1.0"></dependencies>
- Impact: The plug-in will not be deployed by vSphere Client. The
plugin-package.xml
expects plug-in dependencies, not library/bundle dependencies. - Recommendation: Remove any library/bundle dependencies.
- Error example:
- Plugin version is incorrectly specified as a tag
- Error example:
<version>1.0</version>
- Impact: The plug-in manifest will be unreadable by vSphere Client and your plug-in will not be deployed.
- Recommendation: Specify the plug-in version as attribute (e.g.
<pluginPackage version="1.0" ...>
)
- Error example:
B) Problems in the plug-in bundles (.jar and .war files in the plugins/
folder)
- Split packages – two or more plug-in bundles export the same package id
- Error example: Two .jar bundles contain
com.mycompany1.package1
in theExport-Package
section of theirMANIFEST.MF
. - Impact: The plug-in will not be deployed by vSphere Client in isolation (default).
- Recommendation: If the two packages are part of the same feature move all respective classes to the same bundle to make it explicit. If the two packages represent different features rename one of the packages to indicate this conceptual difference.
- Error example: Two .jar bundles contain
- Packaging the vSphere Client SDK deliverable
- Error example: The plug-in contains
vsphere-client-lib.jar
. - Impact: Increased size of your plug-in. This jar is not an OSGi bundle and will be ignored during deployment. It is not intended for being packaged with the plug-in but for building the plug-in against the public set of Java APIs which are anyway available at vSphere Client’s runtime.
- Recommendation: Remove
vsphere-client-lib.jar
from the plug-in.
- Error example: The plug-in contains
- Packaging libraries without OSGi manifest
- Error example: The plug-in contains a .jar/.war with no
MANIFEST.MF
. - Impact: Increased size of your plug-in. The specified .jar/.war is not an OSGi bundle will be ignored during deployment.
- Recommendation: If the library is not used remove it from the plug-in. Otherwise, convert the library into an OSGi bundle by adding a
MANIFEST.MF
.
- Error example: The plug-in contains a .jar/.war with no
- Importing packages from nested libraries – a plug-in bundle both embeds a library and imports a package from it
- Error example: A plug-in .jar/.war bundle’s
MANIFEST.MF
containsImport-Package
section withcom.mycompany1.package1
andBundle-Classpath
section withmy-internal-lib.jar
. - Impact: The plug-in will not be deployed. The internal library is not an OSGi bundle so it does not export any packages that your bundle can import.
- iii. Recommendation: Remove the package import. The library is already available for direct use by the bundle because it is part of its classpath.
- Error example: A plug-in .jar/.war bundle’s
C) Plug-in interoperability issues with vSphere Client
- Delivering one or more plug-in bundles built with a higher Java version than vSphere Client supports.
- Error example: A plug-in .jar/.war bundle is built with target Java version 8 while target vSphere Client version contains bundles built with Java 7.
- Impact: The plug-in will not be deployed.
- Recommendation: Follow the environment requirements from the official documentation. Pay attention to what target Java compiler compliance level should be specified for your plug-in bundles.
- Packaging 3rd party libraries which are already delivered by vSphere Client
- Error example: The plug-in contains a
javax.servlet-api.jar
bundle. - Impact: Increased size of your plug-in and possible plug-in problems if any operations refer to APIs not present in the vSphere Client’s version of the library. At runtime vSphere Client will always deploy its required 3rd party dependencies first and plug-ins will always consume them even if they bring their own version of the library.
- Recommendation: Remove any 3rd party libraries from your plug-in which have counterparts in the
server/repository/usr
folder of vSphere Client’s server. Note that you need to check theBundle-SymbolicName
in theMANIFEST.MF
of the .jar bundle as the .jar file name is not always sufficient to be sure if the bundle maps to one of your plug-in bundles.
Common libraries delivered by vSphere Client to watch out for are:- Spring libraries
- Jackson libraries
- servlet, javax.servlet-api, javax.transaction
- apache.commons.logging
- joda-time
- Error example: The plug-in contains a
- The plugin is using the global context class loader.
- Error example: The plug-in tries to load resources it delivers using the global context ClassLoader.
- Impact: The plug-in will fail during deployment or at runtime because it is unable to load the required resource. The reason is that plug-ins are now deployed in isolation by default which makes plug-in resources not directly visible to the global context ClassLoader.
- Recommendation: Use current bundle class loader for loading resources (e.g. temporarily change the context ClassLoader with
Thread.currentThread().setContextClassLoader(getClass().getClassLoader())
).
Cleaning up the aforementioned drawbacks that might be present in your plug-in would facilitate its smooth deployment, operation and interoperability with vSphere Client. In addition, plug-ins would benefit from better design, smaller zip deliverables and faster deployment times.
For more hints check the Best Practices listed in the official vSphere Web Client SDK Documentation or refer to the other blog posts on Building vSphere Client plug-ins and OSGi-Specific Best Practices