Frequently Asked Questions

  1. General architecture / programming questions
  2. SDK setup and requirements
  3. Common Virgo questions
  4. Building and running a Flex UI plugin
  5. Building and running a Java service plugin
  6. Debugging and logging
  7. Common issues using the SDK API
  8. Plugin packaging and installation

1. General architecture / programming questions

What is the overall VWC platform architecture?

Here is a high-level picture showing the 3-tier architecture used by vSphere Web Client (VWC):

Your Java services running in Virgo are either data adapters handling queries from the Data Manager, or code handling remote API calls from the client. They can connect in turn to back-end servers with any preferred communication method (the vSphere Web Service SDK is the standard way to access the vCenter API).

Note that the app server should only be used as a pass-through to back-end processes or data sources. Java services should be limited to dispatching client requests and returning data, any real business logic should be implemented in your own server. Java services are created as singleton beans by the underlying Spring Framework, they should remain stateless and be thread-safe.

For more details please see the Programming Guide, the list of extension points, the Flex API docs and the Java API docs.

Do I have to use the View-Mediator pattern? Can I re-use existing Flex code or other UI frameworks?

The platform encourages you to define separate view and mediator classes for each UI extension, the view containing the visible components (in Flex .mxml format), and the mediator implementing the view business logic (in ActionScript). There is no strict requirement to use that pattern as long as your extension objects use the correct APIs. But, once you have seen a few examples, you should find that it is an easy pattern to implement, one which facilitates the integration with the rest of the platform.

You can use existing code for a particular view or component in various extension points, like the one below where the class com.example.MyView is used for a "global view" extension, i.e. is displayed in the client's main area.

   <extension id="com.example.myappview">
      <extendedPoint>vise.global.views</extendedPoint>
      <object>
         <name>App name</name>
         <componentClass className="com.example.MyView"/>
      </object>
   </extension>

However you will need to use the platform's Flex APIs in order to interact with VWC components. For instance, when a view extends some vSphere object UI, its class must implement the interface com.vmware.ui.IContextObjectHolder in order to get a hold of the selected object.

This applies to using other Flex frameworks as well. They should be compatible with VWC but some API integration is necessary in order to take advantage of VWC's extensibility and data access frameworks.

Can I display HTML content inside the client?

No, Flex doesn't support embedded HTML content. If you need to display HTML the recommended solution is to open a separate browser tab or window, with the Flex method navigateToURL.

The HTML support provided for legacy script plugins (i.e. built for vSphere Client on Windows) is internal to the platform. This is not a work-around that can be extended to any content because of its limitations.

Can my UI code by-pass Virgo server? What are the security implications?

Yes, the dotted line shows this use case in the picture above. Nothing prevents you for making direct calls to a remote server using the data access method of your choice.
The drawbacks are the following:

Can I run any java process in Virgo? If not, how to access other back-end processes or servers?

The short answer to the first question is no, you should not run just any java code in the Virgo app server!

Java service plugins must remain light-weight processes, i.e. used only as "pass-through" to communicate between the client and vCenter Server or other data sources. The VWC server is not intended to run 3rd party business processes implemented as extensions, it's easy to see in the picture above that this approach would not scale up and scale out! Typically a java service (or Data adapter) handles service calls (or data requests) from the client, and then dispatches them to another server, either to retrieve data or trigger some action. The service processing should be limited to preparing and dispatching the back-end call, and managing the results before returning to the client: in short there should be no risk of heavy CPU or RAM usage, thread blocking, or long delays for a response to the client. Any complex business logic should be done in a back-end server, any long operation should be implemented as a task (for instance you can create a vCenter task to represent your long operations).

Caching of data at the service level is also not recommended unless it is very small and you are confident this won't affect scalability.

Likewise, do not create thread pools in your Java service! Keep the processing to a minimum and pass off the real business process to your own back-end.

The Data and API connections between your Java service and another server can be done in anyway you prefer: Web Services, REST apis, database access, etc. There is no restriction on technologies other than any library required on the service side must be OSGI-enabled to run in Virgo.

The location of your server can be stored with the vCenter Extension object used to register your plugin package. When your Java service is called the first time, you can retrieve this location using the ExtensionManager in the vSphere Web Service SDK and cache it for all subsequent calls (see vsphere-wssdk-provider for sample code using WSSDK).

Should my Java services code be thread safe?

Absolutely! Your Java service or DataProviderAdapter classes must be able to handle different threads. They are created as Spring beans so use the Singleton pattern by default. You should keep them stateless or treat concurrency carefully.

2. SDK setup and requirements

See the SDK-Setup page for the detailed setup information.

Are Mac OS or Linux supported?

Mac OS is supported for plugin development, you can install the same tools as for the Windows setup. Linux is not supported because Flash Builder doesn't exist on Linux (however you should be able to do everything else that doesn't require FlashBuidler).

Are Flash Builder and Eclipse/STS required?

Eclipse (or STS) is the only IDE officially supported for SDK development. Of course you can edit code with any tool, use the Ant build scripts on the command line and deploy plugin packages manually with Virgo, but the Eclipse IDE and the Virgo integration will make you much more productive.

Adobe Flash Builder is not required for compiling Flex code (the build scripts work with the Flex SDK which is free to download) but Flex debugging and fast development cycle will be hard without it!

Can I use Eclipse or STS 64 bit version?

Yes, but only with Flash Builder 4.7. The older Flash Builder 4.6 is not compatible with Eclipse 64bits.

What Network configuration is required in Eclipse?

Open Window > Preferences > General > Network Connections and verify that your proxy settings are correct to access the internet otherwise you won't be able to install new software such as the Eclipse Virgo Tooling.

java.lang.OutOfMemoryError in Eclipse/STS

If Eclipse itself is running out of memory add these VM arguments to increase memory in your Eclipse.ini or STS.ini file (located where Eclipse or STS is installed)

-Xmx1024m
-XX:MaxPermSize=512m
    

If the error happens when the Virgo server starts (usually java.lang.OutOfMemoryError: PermGen space) then the extra memory must be added to the Virgo process, not Eclipse:

-XX:+CMSClassUnloadingEnabled
-XX:MaxPermSize=256m
    

If you still have problems the Virgo heap dump should provide more information. See also this Oracle article on Java Hotspot memory options. For instance you could try:

-Xmx1024m -Xms512m -XX:PermSize=128m -XX:MaxPermSize=256m

Where is the Eclipse/STS log to check for installation problems?

In case of installation problems in Eclipse you can check the Eclipse log by going to Help > About STS (or Eclipse)> Installation Details > Configuration > View error log

Installation problems with Flash Builder

See the Adobe Community forums at http://forums.adobe.com/community/flash_builder

3. Common Virgo questions

For more technical information on Virgo please see the Virgo FAQ or the various docs at http://www.eclipse.org/virgo. VWC 5.1.0 is using Virgo version 3.0.3, whose documentation can be downloaded here.

Do not modify the Virgo configuration unless you are absolutely sure that your change won't impact the normal behavior of vSphere Web Client.

Virgo error in Eclipse: "Failed to start Tomcat. Port 9090 is in use."

Check that the VMware vSphere Web Client service is not running already on the same machine (case where you have installed vSphere Web Client on your development machine with the Windows installer and didn't stop the service).
Another possible reason could be that a previous Virgo session wasn't terminated properly and that process is still running. You can see that either in Eclipse's Debug view (in which case it's easy to kill there) or in your machine's Task Manager (look for a Java process).

Where are the Virgo logs? How to configure them?

In a standard development environment the server full log vsphere_client_virgo.log is located in [VWC]/server/serviceability/logs, where [VWC] is the directory where you installed the vSphere Web Client.

The location is different if you deployed a VCVA vm or used the Windows installer:

vsphere_client_virgo.log is a rolling log that you can configure differently following the Virgo documentation.

The other logs under sub-directories of server/serviceability/logs are specific to different components but don't add more info, so it is easier to use vsphere_client_virgo.log for everything. Notice that when you start Virgo from Eclipse the console view contains only important messages. You have to refer to the main log file to be sure to see everything.

Problems usually start with tags [ERROR] or [WARN ] in vsphere_client_virgo.log (although not all of those should be considered serious). To spot issues with your own plugin search your package name or bundle SymbolicName.

To increase the log level to DEBUG for a particular package add this logger (change "com.vmware" to your package) and make sure to start the server in Debug mode:

<logger level="DEBUG" additivity="false" name="com.vmware">
   <appender-ref ref="SIFTED_LOG_FILE" />
   <appender-ref ref="LOG_FILE" />
</logger>

Here is a tip to make log lines shorter and easier to read without losing too much info, use this pattern in configuration/serviceability.xml:

<Pattern>[%d{HH:mm:ss}] [%-5level] %msg %ex%n</Pattern>
That pattern removes the day, thread name and session id from the normal log, which is fine for a development environment where you are the only one testing.

Error deploying a vSphere bundle: "Destination path already exists."

If the Virgo log shows an error like: [ERROR] ...org.eclipse.virgo.kernel.deployer.core.DeploymentException: Cannot move path '...mixed-service-5.1.0.jar' to '...mixed-service-5.1.0.jar-past'. Destination path already exists., it is likely because the server wasn't restarted with the Clean option which clears its local cache. Make sure you checked that box in the server editor.

Can I use Virgo's pickup directory instead of deploying in the Server view?

Virgo's pickup directory allows hot-deployment of artifacts, i.e. any bundle copied to that directory while the server is running will automatically get deployed.

They are no clear advantages of using the pickup directory vs. adding your bundles in Eclipse's Server view, except may be when a build script is doing it for you. The drawbacks are the following:

Note that the pickup directory is still useful for deploying 3rd parties libraries in development mode.

Why is my plugin bundle missing in Virgo's Add and Remove dialog?

The Add and Remove dialog is used to deploy a UI or java plugin in Eclipse: right-click on Virgo in the Server view and select Add and Remove..., then drag your project to the right-hand side as shown below.

If your project doesn't appear on the left-hand side it must be because it doesn't have the right "facet" and no deployment descriptor is defined. You can fix this in several ways: in the project's Properties wizard (see Project Facets), or with the context menu item Virgo > Add OSGI Bundle Project Nature (see picture below), or by editing the project files .project and .settings/org.eclipse.wst.common.project.facet.core.xml:

How can I tell which bundles are active and what packages they export?

The Eclipse server console will show each bundle being deployed or undeployed. It should also show deployment errors although you can refer to the full logs for more details. Another way to check the bundles status is through the Bundle Overview tab of the Virgo editor. Refresh the bundles list and select the bundle of your choice: the right-hand side displays its MANIFEST information and let you search exported and imported packages.

If you can't find the 3rd party library you added and were hoping to see in the Bundle Overview tab it is either because you didn't put it in the right place or it is not OSGI-compliant, see the section How to use 3rd party libraries?. If you can't find your own plugin bundle in the Virgo list, or don't see the expected Imported or Exported packages for that bundle, first check that your latest changes have been saved to the server, then check that were there were no deployment error in the log.

How can I check that all my changes have been saved to the server?

As you are testing changes to a UI or Java plugin you may wonder why things are not working as expected. One thing to check if that the running code is the one you last touched in your editor! First of all, each time your Flex or Java project is rebuilt (or a resource is updated) the corresponding bundle should be updated on the Virgo server. This doesn't necessarily mean that the bundle is redeployed but the correct files should be there (i).

For instance, if myPlugin and myService are currently deployed you can verify the content of the server/stage directory as shown below, where the "exploded" bundle resources are copied by the Virgo tooling. The modification dates of the files should match your changes. If they don't you need to rebuild your project (copying files manually to server/stage won't work!).

Note the difference between Flex and Java (i.e war and jar bundles): building a Java project forces the bundle to be hot-redeployed because the code is running within the server, building a Flex project usually doesn't trigger hot-redeployement because the web bundle configuration hasn't changed, only its .swf resource files (The new .swf code will be loaded when your start a browser session). However changes to the configuration (bundle-context.xml, web.xml, MANIFEST.MF) must force a redeployment, as well as changes to plugin.xml where extensions are defined.

Here are additional tips that can help:

Where is the dump file generated by Virgo?

After a severe errors you may see a message in the Virgo console that a dump file was generated but the corresponding dump folder is empty. This is because dump generation is disabled by default as those files tend to be very large. You can restore dump generation by commenting out the dump.exclusions flags in server/configuration/org.eclipse.virgo.medic.properties, i.e. adding # in front of each line and restarting Virgo.

4. Building and running a Flex UI plugin

What to do when I get this dialog: Choose Flex SDK Version?

You may get this dialog when opening SDK sample projects or after creating a new Flex plugin project. It is because projects were created to be compatible with earlier versions of Flash Builder. What matters is that the default SDK says "Flex 4.6.0". You should select the option Remember my decision and click OK. The project itself won't be affected.

Why do I get an error "Creating output directory" when opening a Flex project?

You may get this error if you have selected the menu option Project > Build Automatically. It is annoying but harmless: for some reason Flash Builder cannot find the right output directory (usually war\target\myPlugin-war). Close the dialog and build the project again.

Why do some of the plugin.xml editor views fail?

Double-clicking on plugin.xml in the project tree opens Eclipse's Plugin Manifest Editor by default. You can edit the content of plugin.xml in the last tab, however most of the other views cannot be used for VWC plugins because this editor was designed explicitly for Eclipse plugins. Another option is to right-click on plugin.xml and use the menu Open With > Text Editor.

How can I test another language than English?

The easiest is to append the query parameter locale=xx_XX in the URL, for instance https://localhost:9443/vsphere-client/?locale=fr_FR to run the client in French. The 6 locales supported by VWC are: en_US, de_DE, fr_FR, ja_JP, ko_KR and zh_CN. If resources are not available for a particular locale the english version is used by default.

See the helloworld-i18n sample for more details on localization.

Can I use the Flex Design view to create new UIs?

It won't work very well because the Design mode of the Flex mxml editor is geared towards static content without localized resources. In most cases your plugin views contain dynamic elements and the labels are pulled from resource files.

How to use a 3rd party Flex library?

The easiest way to include a 3rd party Flex library with your plugin is to add the .swc library to your project with the Link type set to Merged into code.

When should I explicitly redeploy my UI plugin bundle?

In theory you should never have to. During a normal UI development cycle the Virgo Tools take care of updating the bundle's war content on the server. A change in .as or .mxml files does not trigger a bundle refresh because the compiled module .swf file is updated directly on the server (see the Server Overview tab, the *.swf pattern is listed under Redeploy Behavior. Only a change to plugin.xml will trigger a redeployment because extensions need to be reloaded by the server). You can also check that your plugin's war content was updated in server/stage/your-plugin-name.war.

If you suspect that something wasn't built correctly, or notice that server/stage doesn't contain the latest files for your plugin, you can use the menu Project > Clean... to rebuild your project from scratch. At that time the Console view should show the bundle being redeployed.

If you are still having problems, go to the Servers view and try the Redeploy command, in the right-click menu over your plugin. But redeploy will only pick up the war files generated by the build, so the first thing to check is that the build was correct.

Runtime Error #2036: Load Never Completed.

If you only see Error #2036 and no other message in your view you should restart the client with a Debug Configuration and it will provide more details on the file that could not be loaded. Usually the problem comes either from a missing resource module, or from a missing main module as described below.

Load Never Completed URL: /myplugin/locales/MyPlugin-en_US.swf

This error means that the resource file MyPlugin-en_US.swf was not built or deployed properly on the server.

If running from Eclipse, make sure that war/target/locales contains the various resource files as shown below.
If it doesn't you need to run the Ant script build-flex.xml to compile the resource files at least once.

To verify that the resource files were deployed correctly with the rest of the plugin check the server's stage directory, in vmware-vsphere-client/server/stage/myplugin.war/locales. If the files are still missing, redeploy your plugin with the right-click menu command in the Server view.

Note that you should not have to recompile the resource files again until you make some changes there. While you are only touching the code the module MyPlugin.swf is built directly by the Flex compiler and the Ant script is not necessary in Eclipse.

Load Never Completed URL: /myplugin/MyPlugin.swf

In this case the module .swf itself is missing from server/stage/myplugin.war. This should not happen if you have built the project in Eclipse, i.e. the file MyPlugin.swf generated in myPlugin/war/target/MyPlugin-war should be copied automatically to the server's stage directory. But it does happen sometimes for some unclear reasons. The solution is to force a clean build and refresh the project. What matters is that server/stage/myplugin.war gets updated with the latest files, but of course you cannot copy files manually in the stage directory!

Runtime Error #1034: Type Coercion failed: cannot convert ...

It usually means that you are not using the right libraries. Check the following:

Error #1034: Type Coercion failed: cannot convert [classname] to mx.core.UIComponent

This more specific error happens if you are extending a view extension point and don't use a view class in the <componentClass className="..."> declaration in plugin.xml. A typical mistake is to use the Mediator class instead of the View class there!

5. Building and running a Java service plugin

Bundle installation fails because "An Import-Package could not be resolved"

This means that Virgo cannot find any installed bundle exporting the missing package:

How to solve most ClassNotFoundException or similar errors?

In most cases a ClassNotFoundException, or similar "not found" error, is caused by incorrect or missing packages in your bundle manifest's Import-Packages. For instance if your java service uses any API from the SDK package com.vmware.vise.data.query, that package must be listed in its manifest (this is how Virgo handles dynamic dependencies between libraries). We recommend to use a tool like bundlor to generate the manifest with your build, this will avoid many errors!

If the "not found" error still happens when calling a remote web service from your java plugin, another thing to try is to add the missing package in the MANIFEST of the UI plugin making the initial call to your java plugin. For instance if you get a popup with the error Provider com.ctc.wstx.stax.WstxInputFactory not found you should add com.ctc.wstx.stax to the Import-Packages of your UI plugin's MANIFEST (in addition to your Java plugin).

How to use 3rd party java libraries?

Your java plugin can use 3rd party jars if they are packaged as OSGI bundles (i.e. contain the correct OSGI metadata in order to be installed by the Virgo server) or are nested inside the plugin's bundle (see Note 1. below). The OSGI metadata is defined in MANIFEST.MF and includes the package names exported by the library, under Export-Packages. In turn your java plugin's manifest must list the 3rd party's packages it uses in Import-Packages, so that Virgo can establish dependencies between your bundle and the 3rd party jars.

Libraries packaged as OSGI bundles should be in a location known to the server:

For instance the vsphere-views sample uses two external libraries: gson-2.0.jar and vim25.jar. Its plugin-package.xml lists those two libraries at the top of bundlesOrder:

...
   <bundlesOrder>
      <!-- vim25 and gson are loaded first to satisfy dependencies -->
      <bundle id="com.vmware.wsvim25" />
      <bundle id="com.google.gson" />
      <bundle id="com.vmware.samples.custompropertyprovider" />
      <bundle id="com.vmware.samples.custompropertyui" />
      <bundle id="com.vmware.samples.viewspropertiesui" />
      <bundle id="com.vmware.samples.wssdkprovider" />
      <bundle id="com.vmware.samples.wssdkui" />
   </bundlesOrder>

In some cases a library that you need is already available in server/repository/usr as part of Virgo standard installation (you will get a deployment error if you try to deploy it a second time with your plugin package). In other cases you may want to use a different version than the one installed with Virgo. For instance you'd like to use httpclient-4.2 and Virgo contains only httpclient-4.0.1. This is not a problem: package httpclient-4.2.jar with your plugin and make sure to include the correct version number next to the package names in your Import-Packages. The correct library will be loaded by your plugin's class loader, it won't interfere with other bundles that may be using a different version, this is one of the advantages of OSGI :-)

Notes:

  1. Here is how you can nest a 3rd party java library inside your own bundle in order to avoid conflicts with other bundles deployed on the server (i.e. this is a way to package your own dependencies):
  2. The server/pickup option is little tricky because, when the server starts, these libraries won't be hot-deployed until all other bundles are deployed. So any plugin added to the server that relies on a library located in server/pickup will fail to deploy initially and you will need to redeploy it manually.

How to package a library as an OGSI bundle?

For 3rd party libraries the first step is to search the web in case an OSGI version already exists.
Otherwise the easiest is to use a tool like bundlor, the documentation is available in the Virgo Guides under Help > Help Contents.

The recommended way is to integrate bundlor with your Ant or Maven build as explained in the documentation. However if you want to transform quickly a 3rd party library (e.g. foo.jar) follow these 2 steps:

Note: bundlor is integrated with the Virgo tooling in Eclipse. You can run the generation of MANIFEST.MF for any java project.

Bundlor can also be used for Flex plugins (.war bundles) but it is more limited because it doesn't generate the Import-Packages list (it can't parse the configuration files to find out which java services are being called). You must add Import-Packages with the list of packages directly in template.mf.

Why isn't my Java service working?

If an error occurs when calling a Java service from your Flex code the first thing to check is your configuration, there are very specific steps to follow: please see the section Calling a Java service from the client in the SDK Tutorial, or follow the GlobalView sample. In particular check the content of web.xml, bundle-context.xml and MANIFEST.MF. Make sure the service name, interface names, etc., are correct. Verify also that your configuration changes have been saved to the server.

The next step is to use the Flex and Java debugger to check that 1) the call is made correctly from the client, and 2) it is received correctly in your java service class.

Finally, if you expect a result from the Java call, verify that you are handling the right type of result object in the Flex code receiving the MethodReturnEvent. Here again the debugger can help you figure out how the java object is serialized back to Flex. See also Adobe's doc on ActionScript-Java serialization.

If none of the tips above seem to help turn on BlazeDS logs to see exactly what is happening during the java-remoting call.

How to return a Java exception to Flex?

When a Java service throws an exception BlazeDS returns a generic "server processing" error. In order to convert the java exception to a meaningful Flex error you can use an ExceptionTranslatorService as demonstrated in the globalview sample.

In case of a DataProviderAdapter the correct way to return an exception is with the DataException API as shown in the custom-property-provider sample.

How to call a service from another service?

The SDK samples provide several examples of a service calling another service, for instance the custom-property-provider calling a GoogleService, or the chassis-app's DataProviderAdapters calling DataService and VimObjectReferenceService. Here are the steps to connect two services from different plugins.

We assume plugin A has a service interface com.vmware.samples.pluginA.MyService1, plugin B has a service interface com.vmware.samples.pluginB.MyService2, and the implementation of MyService1 needs to call MyService2.

1) Add a reference to MyService2 in the implementation constructor for MyService1. MyService2 can then be called anywhere in that class:

   ...
   import com.vmware.samples.pluginB.MyService2;

   /** 
    * Implementation of MyService1.  Uses MyService2 from pluginB.
    */
   class MyService1Impl implements MyService1 {
      // Service from plugin B
      MyService2 _service2;

      public MyService1Impl(MyService2 service) {
         this._service2 = service;
      }
      ...
   }

2) Define the constructor injection in META-INF/spring/bundle-context.xml:

   <!-- Declare pluginA's service bean, using the reference to MyService2 as argument -->

   <bean name="myService1Impl" class="com.vmware.samples.pluginA.MyService1Impl">
      <constructor-arg ref="myService2"/>
   </bean>

3) Define the reference to MyService2 in META-INF/spring/bundle-context-osgi.xml:

   <!-- Declare the OSGI service that follows MyService1 interface -->

   <osgi:service id="myService1" ref="myService1Impl"
         interface="com.vmware.samples.pluginA.MyService1"/>

   <!-- Reference to pluginB's myService2, used in bundle-context.xml above -->

   <osgi:reference id="myService2"
         interface="com.vmware.samples.pluginB.MyService2" />

4) Finally, edit plugin A's MANIFEST.MF (or generate it with bundlor) to include the dependency on package com.vmware.samples.pluginB where MyService2 is defined:

Import-Package: ...
  com.vmware.samples.pluginB,
  ...

Note that you cannot have a circular dependency, i.e. pluginA uses a service from pluginB and vice-versa. If you have common services to be used both in pluginA and pluginB you need to put them in a separate pluginC that can be referenced from both pluginA and pluginB.

6. Debugging and logging

How can I debug my Flex code?

In order to use the Flash Builder debugger you need to setup a Run/Debug Configuration in Eclipse as described in the SDK-Setup. It can be attached to any open Flex project, what matters is the URL https://localhost:9443/vsphere-client.

You can start this debug configuration from multiple places, including the right-click menu on your project (note that you are not launching the plugin as a Web Application)

After you have used your new debug configuration once it will appear in the top menu, under the Debug icon, in the list of recent configurations:

Starting the debug session opens the browser on the vsphere-client URL, the Flex Console shows the various .swf modules being loaded, and you should land on the login page. You can verify that the debug session is running correctly in the Eclipse's Debug tab, right under the Virgo session.

From that point on you can set breakpoints in your Flex code, examine variables, step through methods, etc.

The Flex debug session stops being active when you quit or refresh your browser window. So you will need to start a new debug session for testing code changes, instead of just refreshing the window.

To debug Flex code without the Flash Builder debugger you need to rely entirely on logs, or pop up alerts containing your debugging info.

VerifyError #1014: Class mx.modules::Module could not be found

This error or something similar happens when you launch the Web Client from Eclipse but you forgot to edit the URL of your Run/Debug Configuration to be https://localhost:9443/vsphere-client

Firefox keeps crashing in debug mode

Try to change the configuration as follows:

  1. In the Firefox's address bar type "about:config"
  2. You'll get a warning "This might void your warranty", click "I'll be careful, I promise!"
  3. In the filter type "dom.ipc.plugins.timeoutSecs"
  4. Change the timeout value to -1 to make it infinite

Where are the Flex logs? How to add logs in my Flex code?

The easiest way to see Flex logs is to run a Flex Debug Configuration, they will appear in the Flex console in Eclipse.

See this Adobe article on how to configure the debugger version of Flash Player for enabling logs.

Where are the Java logs? How to add logs in my Java code?

See Virgo logs for the location and configuration of the server logs.

To add logging to your own java code, you can follow what the SDK samples do, i.e. use the standard java logging API:

   import org.apache.commons.logging.LogFactory;
...
   private static final Log _logger = LogFactory.getLog(YourClassName.class);
...
  _logger.info(...)
  _logger.debug(...)
  _logger.error(...)
Your bundle's MANIFEST.MF must also contain a reference to that logging package, i.e.
   Import-Package: org.apache.commons.logging

How can I see the BlazeDS logs to debug Flex-Java remoting?

Serialization problems and non-working proxy calls can be debugged by looking at the BlazeDS logs. They are not included in the Virgo log by default because they are too verbose, but a simple configuration change will turn them on. First add a logger for "System.out" in [VWC]/server/configuration/serviceability.xml

<logger level="DEBUG" additivity="false" name="System.out">
   <appender-ref ref="SIFTED_LOG_FILE" />
   <appender-ref ref="LOG_FILE" />
</logger>

Then edit the BlazeDS log settings in [plugin-ui]/war/src/main/webapp/WEB-INF/flex/services-config.xml to change the level from Error to Debug and turn on some flags:

    <logging>
      <target class="flex.messaging.log.ConsoleTarget" level="Debug">
         <properties>
            <prefix>[BlazeDS]</prefix>
            <includeDate>false</includeDate>
            <includeTime>true</includeTime>
            <includeLevel>true</includeLevel>
            <includeCategory>false</includeCategory>
         </properties>

         <filters>
            <pattern>Endpoint.*</pattern>
            <pattern>Service.*</pattern>
            <pattern>Configuration</pattern>
         </filters>
      </target>
   </logging>

Restart the server and see the BlazeDS traces in vsphere_client_virgo.log once a user logs in. It will be quite verbose, so you may want to turn the logger off in serviceability.xml once you are done debugging your code!

Note that if you only change your plugin's services-config.xml a simple redeployment is enough.

Why isn't my Flex breakpoint being hit?

The first thing to check is that you have an active debug session in the Debug tab. If you don't, see how to debug flex code.

Next, verify that you built your Flex plugin with the correct debug information:

Assuming that your Flex plugin loaded correctly (i.e. the bundle was installed successfully in Virgo), there are several possible reasons for a breakpoint to be ignored:

How to debug my local Java code? why isn't my Java breakpoint being hit?

First, make sure that you started Virgo in debug mode: the Server tab should say [Debugging, Synchronized] as shown below, and you should see the running java session in the Debug tab (with multiple threads).

Then use the standard Java debugger and the various Eclipse debugging views to set breakpoints, examine variables, etc.

If your breakpoint is not being hit, verify that you built your plugin with the correct debug information:

If you still get a message like "Absent line number information", force a clean build (menu Project > Clean) or delete the current target directory.

Assuming that your java plugin loaded correctly (i.e. the bundle was installed successfully in Virgo), there are several scenarios for a breakpoint to be ignored, based on the java code in question:

How to remote debug on a VCVA appliance?

Here is how you can remote debug your java code when the plugin is deployed on a VCVA appliance:

How can I check that the content of a bundle or Flex module is correct?

When things don't work as expected it's a good idea to check the content of your UI or Java bundle, and the content of the Flex .swf module, to verify that the classes and resources you expect are there.

A UI bundle is a WAR file, so you can inspect its content with any ZIP compatible tool: WinZip, 7-zip, WinRAR, etc. The root folder should contain: plugin.xml, META-INF, WEB-INF and your module's' compiled .swf file. To inspect the content of a .swf file you can use a SWF decompiler such as the swfdump tool in your Flex SDK bin directory, or the Flash Decompiler from Trillix (free trial version).

A Java bundle is a JAR file. You can open it also with with any ZIP compatible tool: WinZip, 7-zip, WinRAR, etc. The root folder should contain META-INF (where you can check MANIFEST.MF) and the package hierarchy where you can verify which classes are included.

7. Common issues using the SDK API

UI extension missing or not working

If you don't see the UI extension that you added to plugin.xml, or get an error at runtime (a view, tab, list, menu, etc.), the following check-list can help:

  1. Check that your changes to plugin.xml have been saved to the server.
  2. Verify that the extendedPoint is used correctly (id, object class, etc.). A typo will go undetected at compile time and may produce strange errors at runtime! See the current list of extension points.
  3. Check that the component class used for the view is being compiled. For instance in the extension declaration below the view class MyPluginView will be loaded dynamically at runtime (the compiler doesn't have any references on that class to compile it). The solution is either to add MyPluginView to your plugin's ModuleClasses.as listing all classes that are loaded dynamically in order to force their compilation, or better, to add its mediator class MyPluginViewMediator to ModuleClasses (MyPluginViewMediator references MyPluginView).
       <extension id="com.acme.myPlugin.MyPlugin.vmSummaryView">
          <extendedPoint>vsphere.core.vm.summarySectionViews</extendedPoint>
          <object>
             <name>#{summary.label}</name>
             <componentClass className="com.acme.myPlugin.views.MyPluginView"/>
          </object>
       </extension>
    ModuleClasses.as looks like this and is referenced in the main module MyPlugin.mxml:
    package {
    import com.acme.myPlugin.views.*;
    /**
     * Include the classes instantiated dynamically, otherwise they won't be added by the compiler.
     */
    internal class ModuleClasses {
       MyPluginMediator
    }
    
  4. In case the extension is using a metadata filter, check that it is not being filtered out: for instance based on object type, on property conditions, or user privileges.
  5. Compare with other plugins or SDK samples using the same extension.

Why do I get an error for metadata tag values (in Event, RequestHandler, ResponseHandler)?

Compile-time errors like the one below (also for Event and ResponseHandler tags) happen when the metadata checker tool is enabled: it checks for valid ids against an internal white list to avoid mistakes that would be harder to find at runtime. You can expand the white list with your own ids, follow the link to learn more about this SDK tool.

Why isn't my RequestHandler or ResponseHandler getting called?

As the sample code shows below RequestHandlers are typically used to implement the behavior of an action and ResponseHandlers are used to process the response from a data request.

   [RequestHandler("com.vmware.samples.actions.myVmAction1")]
   public function onVmAction1Invocation(event:ActionInvocationEvent):void {
   ...

   [ResponseHandler(name="{com.vmware.data.query.events.PropertyRequest.RESPONSE_ID}")]
   public function onDataRetrieved(request:PropertyRequest, result:StringDataObject, error:Error):void {
   ...
There are 3 main reasons which may explain why it is not working:

See other possible data request errors below.

Things that may be wrong with your data request or data adapter

First case: data request on vSphere objects

(i.e. no custom PropertyProviderAdapter or DataProviderAdapter is involved)

Verify this check-list:

  1. Your DataRequest event may be ignored:
  2. Your ResponseHandler may be incorrect:
  3. You may have multiple DataRequest events of the same type:

Second case: data request that involves a custom PropertyProviderAdapter or DataProviderAdapter

In addition to the check list above, please verify the following:

  1. Your DataRequest event may be ignored
  2. The data adapter may not be registered correctly
  3. The data adapter implementation may be incorrect
  4. If the result received in Flex contains null or incorrect data

What object types and properties can be used in data models and data requests?

Note: This answer applies to data models and data requests defined in your UI code, but also <metadata> filters in plugin.xml (where you can specify object types and property conditions).

For vSphere objects you can use the types and properties from the vSphere Web Service SDK (see this vsphere-50 API reference for instance) or you can define custom properties handled by your own PropertyProviderAdapter (see the vsphere-wssdk-provider sample). For custom objects, you define your own types and properties. It is important to add a namespace like mycompany:mytype to avoid collision with other types.

For vSphere object properties, it is only possible to use the values returned by the VWC built-in adapters if they are primitive types (string, boolean, etc.) Values of any complex object type cannot be used as-is because the SDK doesn't provide the corresponding Flex or Java type. You should not make any assumption on these objects either if you want your code to remain compatible in future versions. For instance the runtime property of a VirtualMachine returns an object that the vSphere API calls RuntimeInfo, but the SDK doesn't provide that type for you to use it safely in Java or Flex.

There are 2 solutions for this use case:

  1. You can implement your own PropertyProviderAdapter to return complex types that you define yourself. See the vsphere-wssdk-ui and vsphere-wssdk-provider samples.
  2. Another approach is to use a "path traversal" syntax to reach primitive values in each object: it is simpler because no java code is required, but may become more tedious if you are dealing with lots of properties. For instance the property name runtime.powerState returns the powerState field of the VM's RuntimeInfo object. Please note that this syntax works only if the path doesn't contain a managed entity, i.e. another server object. In that case you can use the relational syntax to continue the traversal. For instance the model [Model(relation="runtime.host", property="name")] lets you access the name of the host related to the VM. You can also retrieve properties over multi-hop relationships like this [Model(relation=”runtime.host,parent”, property=”name”)].

How can my plugin detect a user logout or session timeout?

If your plugin needs to detect the end of a user client session, for instance to clean-up server resources or perform a logout from your own back-end server, use the ClientSessionEndListener API. See how it is done in the vsphere-wssdk-provider sample. Once your service or data adapter implements a sessionEnded method, it will be called when the user logs out manually, or when the session ends because of inactivity (for instance if the browser window is closed):

   /**
    * @param clientId  A unique id representing the user session,
    *             it can be accessed from UserSession using UserSessionService.getUserSession().
    *
    * @see com.vmware.vise.security.ClientSessionEndListener#sessionEnded(java.lang.String)
    */
   @Override
   public void sessionEnded(String clientId) {
      _logger.info("Logging out client session - " + clientId);
      // Clean up all session specific resources.
      // Logout from any session specific services.
   }
   

The session timeout is set to 120 minutes by default. This can be changed in the configuration file webclient.properties located in C:\ProgramData\VMware\vSphere Web Client\ (Windows) or /var/lib/vmware/vsphere-client/ (Linux and Mac).

Note that there is no need for plugin-specific clean up on the Flex side since VWC is the container app, everything is cleaned up automatically when the user logs out.

8. Plugin packaging and installation

For general information on packaging see Package and register your solution in the SDK Tutorial.

How to debug plugin package problems?

See Testing your plugin-package.

What are the differences between a plugin package and the same bundles in a dev environment?

A plugin package is made of one or several bundles (Flex or Java), plus the plugin-package.xml manifest describing that solution. It must be installed one way or another in order to run. In a dev environment the bundles are added directly to the Virgo server (i.e. the manifest is not used and there is no installation per se). Once the bundles are deployed successfully to the server, either from a plugin package or from a dev environment, there should not be any difference since it is the same code. However pay attention to the following:

Can multiple plugin package versions run at the same time?

No, only one version of a particular plugin package id can be active at a time. Registering a newer version will automatically undeploy the older version during the next user login.

Why do I see bundles being deployed that are not mine?

If you see bundles being deployed in your dev environment, which are neither com.vmware core bundles (from vsphere-web-client/plugin-packages), nor ones that you added manually to your server, the only explanation is that you logged into a vCenter Server where a plugin-package was already registered as an extension. The bundles of this registered extension are deployed automatically on your local server. If this creates a problem you should find another vCenter Server to test your plugin, or uninstall the existing extension. If this is not possible or practical see also the tip below.

Tip for your dev environment: to ignore a plugin package without unregistering the extension from vCenter you can empty the directory C:\ProgramData\VMware\vSphere Web Client\vc-packages\<your-plugin-package-version>, the plugin files won't be downloaded again when you login to vCenter.

How to uninstall a plugin?

To remove a plugin package you need to unregister the corresponding extension from vCenter Server. During the next user login the plugin package will be undeployed and the plugin UI won't be available anymore.

Please note that in the current release java services are still active after you unregister an extension. The work-around is to restart the server.

Can a plugin package built with SDK 5.5 be installed on a 5.0 or 5.1 vCenter?
Will it work in a 5.0 or 5.1 Web Client?

Web Client 5.5 works with vCenter 5.5 and 5.1 but not with vCenter 5.0. You can install your plugin package as a vCenter 5.1 extension and it will be loaded by Web Client 5.5 connected to that vCenter. However it will not be deployed with Web Client 5.0 or 5.1. See Versions Compatibility in the README doc.

See also: SDK Tutorial - SDK samples - Flex API docs - Java API docs