Monday, December 26, 2011

OSGi Tracing in Equinox

The Equinox implementation of OSGi provides the tracing APIs in org.eclipse.osgi plug-in since Eclipse 3.5. The tracing options are generally Boolean flags stored in a .options file as key-value pair. A typical .options file would look like this

org.my.plugin/ui=true
org.my.plugin/ui/editor=true
org.my.plugin/ui/prefs=true
org.my.plugin/debug=false
org.my.plugin/debug/data=true

The hierarchy is defined using the slashes. But this is only a general practice. The tracing does not understand this.

-osgi.debug
To load the values from the .options file, provide the file name as command line parameter (or program parameter in launch config)

command line arg example
eclipse.exe -debug C:\tracing\.options

program argument (in launch config) example
-Dosgi.debug=C:\tracing\.options

Using -debug is same as setting the osgi.debug system property.

Accessing the option values at runtime
1. In RCP application
If the RCP application has access to the org.eclipse.core,runtime.Platform object and thus they can access it directly like this

String value = Platform.getDebugOption("org.my.plugin/ui");

User can validate if the program is running in debug mode using Platform.inDebugMode() API.

2. In pure OSGi application
An OSGi application can access these options using the DebugOptions service


ServiceTracker debugTracker = new ServiceTracker(bundleContext, DebugOptions.class.getName(), null);
debugTracker.open();
DebugOptions debugOptions = (DebugOptions) debugTracker.getService()
boolean uiOption = debugOptions.getBooleanOption("org.my.plugin/ui", false);

Using the API has the advantage that user does not have to check for nullness.

More Tracing API
org.eclipse.osgi provides more APIs which are very helpful in logging the trace.

1. Registering a debug option listener
The listener can be registered as service using the BundleContext (that you receive in the activator class when the bundle is started)


final Hashtable<String, String> properties = new Hashtable<String, String>(4);
properties.put(DebugOptions.LISTENER_SYMBOLICNAME, TracingConstants.BUNDLE_ID);
bundleContext.registerService(DebugOptionsListener.class.getName(), new MyDebugOptionsListener(), properties );

2. Listening to the debug option change events
Once the listener is registered, a callback will happen each time a debug option is changed. The callback does not tells you the delta and instead throws the whole lot. So we can use this place to read and init from the DebugOptions


/* (non-Javadoc)
* @see org.eclipse.osgi.service.debug.DebugOptionsListener#optionsChanged(org.eclipse.osgi.service.debug.DebugOptions)
*/
public void optionsChanged(final DebugOptions options) {
//DebugTrace trace;
trace = options.newDebugTrace("org.my.plugin");
// boolean field
DEBUG = options.getBooleanOption("org.my.plugin/debug", false);
}

this is just an indicative code. You don't have to necessarily do it this way.

3. Writing to trace
This is the easiest part. Afterall the reason we did the whole exercise was to make the tracing simple. A handle to trace object can be obtained from the debug options.


/** Trace object for this bundle */
private final static DebugTrace TRACE = MyPluginActivator.getDefault().getTrace();  // returns the trace object obtained using options.newDebugTrace("org.my.plugin");




@Override
protected Control createContents(final Composite parent) {
if (MyPluginActivator.DEBUG) {
TRACE.traceEntry("/debug", parent);
}
...
...
}

Checking MyPluginActivator.DEBUG is optional. TRACE.traceEntry will check for the flag "/debug" anyway. This is to improve of the performance. We store the the flag values to boolean fields and update them through the listener.



4. Where is the log file?
 The log is stored in the file as set in the debug options. By default, it tends to store them to workspace\.metadata\trace.log

options.setFile(new File("/path/to/trace/file"));

5. Controlling the trace logs
The logs are conntolled by two system properties

eclipse.trace.size.max : The system property used to specify size a trace file can grow before it is rotated
eclipse.trace.backup.max : The system property used to specify the maximum number of backup trace files to use

Easier way to manager the logs?
PDE will be providing UI for managing the logs and make them dynamic. See Bug 296631. This is mostly like to make it to Juno M5 release.

What do you mean by dynamic?
If you notice, the debug options can be loaded at the launch time (using -osgi.debug) or programatically when running. However, if you wish to turn the tracing on/off in a running product, its tricky. PDE will be providing an extension using which a plug-in can expose its debug option flags. The UI will display these flags in preferences where they can be turned on/off for a running application. Cool! isn't it?


* If you find any discrepancies in the above post, please bring it to my notice so that they can be updated.

Update: Tracing UI is now available in latest Integration builds and will be there from Juno M5.

Sunday, July 24, 2011

PDE Good Practices: #8 Set correct EE and Java compliance levels

The Execution Environment that is set on the plug-in manifest governs the lowest JRE version the plug-in can work with. If the OSGi runtime (equinox) is running with a lower JRE than the plug-in will not be loaded.

So marked the EE carefully to the lowest JRE you wish to support.


Similarly, ensure the Java compliance level matches the EE.

For example, assume the EE is set to J2SE-1.4 and the Java compliance to 1.5. Now, if you use annotations, the code would still compile in your workspace. However, when deploying, the plug-in would fail it will tell OSGi that it can run with 1.4 but actually it can not.


Saturday, July 23, 2011

Extension Point Schema Builder

The name says it all. This builder is responsible for compiling the extension point schema files. But they are  exsd (xml format) files. What would one compile them in to. HTML of course :)

So the name does not really says it all. Before we proceed, we need to see the Schema compiler preferences.

This page gives the the preference to generate the documentation for the extension point schema. When checked, a reference document is generated for each schema. The document (in HTML format) is generated in the folder name as provided in the preference page. As you can see, the default value is 'doc'. The extension point schema builder is responsible for creating this document. If the check-box is not checked, then this builder will not do anything. 

Friday, July 22, 2011

Plug-in Manifest Builder

Plug-in Manifest Builder or in short, manifest builder is contributed by PDE through org.eclipse.pde.core plug-in. This is the builder that would compile your plug-in each you change plug-in dependencies, modify build.properties, change classpath, add or remove libraries, save your code/classes. It compiles the plug-in and validate that required files (plugin.xml, etc) are in place and in correct shape.

You may have a look at org.eclipse.pde.internal.core.builders.ManifestConsistencyChecker for the exact details.

It is one of the two builder that any plug-in/fragment or equinox bundle project will have by default. It is a bit paranoid builder. If it can not understand any change (resource delta) it will go for full build of the project.

The Plug-in Manifest Compiler preference page has a bunch of options that control the problem severity generated by the builder.


Sunday, June 12, 2011

Using SWTBot as script while developing RCP app

SWTBot is a great tool for writing UI tests. However, you can also use it as script to automate your clicks while developing UI.

Use Case
Suppose we are developing a wizard and we are designing the UI on third page. Now each time we will have to launch our application and then invoke the wizard. Provide template info for first two pages to reach the page where we are actually working currently. While designing UI we do these steps a number of times.

You can use SWTBot to automate these clicks. The idea is simple. Write an SWTBot script for the clicks to be automated, invoke it using Startup extension.

How to do it?

1. Add SWTBot to Target Platform
i) Edit the target platform and add a new 'Software Site' location.
ii) Provide the URL http://download.eclipse.org/technology/swtbot/helios/dev-build/update-site  (see http://www.eclipse.org/swtbot/downloads.php for relevant url for your Eclipse version).
iii) Select 'SWTBot Eclipse features'.

2) Add the SWTBot script using Startup extension
i) Create a dummy plug-in.
ii) Add the 'org.eclipse.ui.startup' extension and create the class that will get invoked by it
iii) Add your SWTBot script to this class created above.
iv) You will have to add the dependency to 'org.eclipse.swtbot.eclipse.finder' for the SWTBot to compile.
v) Include this plug-in and the SWTBot plug-ins from the target to your launch configuration.

How this works?

The 'startup' extension makes the SWTBot script run when your application is launched. Adding the SWTBot to launch configuration will ensure it will be able to run when launched.

Tuesday, April 19, 2011

Eclipse Day India 2011


Eclipse Day India 2011 will be hosted in Bangalore on Friday, May 6, 2011. The registrations are now open. Pick up your free ticket from http://eclipsedayindia.eventbrite.com/

Eclipse Day India is a non-profit annual event organized by Eclipse enthusiasts. It is one day event with talks about Eclipse. This year's edition will have two tracks which will consists of workshops, tutorials and technical talks. A tentative agenda is available at http://www.eclipseday.in/p/schedule.html


Thank you SAP Labs for hosting the event and Progress Software for co-sponsoring.

See you at Eclipse Day!

Friday, February 4, 2011

Self help with API Tooling Reports (Part II): Generating the API Use report using Ant Task

The API Use report can also be generated using Ant tasks. See Eclipse help documentation for it here. If you already know how to run ant tasks in Eclipse, skip the rest of it.

1. Writing Ant script
I assume you know a bit of Ant already. If not, stop and step over to Ant Tutorial.
Create a new File and lets call it GenerateApiUseReport.xml. It will open in default text editor. Close it and Open it with Ant Editor (use right click on file and select 'Open With' -> 'Other...')
Now write this in the file.



The parameters match to the UI we discussed before.
Ant Parameters                UI
location                       <=> Analyze
scopepattern              <=> Bundles matching
referencepattern      <=> References to
report                           <=> Report Output Location
considerinternal       <=> Internal references
considerapi                 <=> API references
considerillegaluse    <=> Illegal API Use

These two are not in UI
archivepatterns - Its exclude filter. It will be a comma-separated list with the format <bundle-id>:<relative-path-to-jar>

debug - Supplying a "true" will make the apitooling.apiuse ant task give out all the debug trace information. This might be helpful if for some reason the results are not expected and you need to investigate. Since default value is false, I would recommend leaving it out until you need it and know what you are doing.

2. Running the script
This is simple. You have to create a new Ant Build launch config from the External Tools Configuration wizard. But why do it when there is a shortcut. Just right-click in the ant editor and select 'Run As' -> '2. ant Build...'. This will automatically create an Ant Build launch config for you and open it. It will look like this


Hit the Run to execute the script. You can open this again from External Tools configuration wizard.

3. Generating HTML reports
The apitooling.apiuse ant task only generating the XML report. For generating the HTML reports we need to invoke the apitooling.apiuse_reportconversion task. The parameters are very simple. See the documentation here.

Since we would want to do this along with the report generation only. We can add this to same Ant script and
make it look like this


 
  
  
 

Thursday, February 3, 2011

Self help with API Tooling Reports (Part I): Generating the API Use report

API Tools is part of Plug-in Development Environment. It provides tooling support for tracking and managing your APIs and dependencies and can generate various reports. The Eclipse help discusses here about how to set it up.

What we will discuss here is how to generate various reports and making sense out of them.

Generating the API Use report

API Use report is the simplest of the report. It tells what APIs are referenced (used) by a given profile. A profile can be an API Baseline, a Target Definition or a directory containing an Eclipse product or just some plug-ins.

PDE provides an External Tools configuration wizard to run this report. The wizards can be launched from the Run menu -> External Tools -> External Tools Configurations...

This will open the External Tools Configurations wizard. Select 'API Use Report' from the left pane and press the 'New' launch configuration button.

The snapshot below shows the settings for an RCP product.


Analyze
You can choose an API Baseline, a Target Definition or a directory to run the report on. The report is a set of XML files. To make it human readable, there is an option to generate HTML report out of any existing API Use report.

Search For
Here you control what to look out for. The 'References to' takes a regular expression which will be used to match the APIs source. In this example the report will lookout only for the API originating out of bundles whose name starts with 'org.eclipse.'
API references: The APIs used in your product
Internal references: Marks the non-API - one coming from internal packages.
Illegal API Use: Usage that breaks the restrictions marked using JavaDoc tags.

Search In
This controls the search scope. The APIs references will be searched only in the plug-ins that match the regex provided here,

Reporting
This is self explanatory. The report will be churned out as a hierarchy of.folders and XMLs in the output location. And if checked for 'Create HTML reports', they will be generated too. The report is saved inside the folder 'XML' in the report output location. While the HTML reports are inside the folder named 'HTML'.

Wednesday, February 2, 2011

Self help with API Tooling Reports (Part III): Understanding the API Use Report

API Tooling reports are collection of XML files. A typical API Use Scan report will look is like this

XML
│   meta.xml
│   not_searched.xml

├───plugin.a.b.c (1.0.0.201101280335)
│   └───com.example.myrcpproduct (1.0.0.201101280335)
│       ├───API
│       │       method_references.xml
│       │       type_references.xml
│       │
│       ├───ILLEGAL_API
│       │       type_references.xml
│       │
│       └───PRIVATE_PERMISSIBLE
│               method_references.xml
│               type_references.xml

├───plugin.x.y.x (1.3.0.v20100512)
│   └───com.example.myrcpproduct (1.0.0.201101280335)
│       ├───API
│       │       method_references.xml
│       │       type_references.xml
...       ...
...

XML folder is where the report is generated

meta.xml contains the report parameters - the regex filters and locations, etc

not_searched.xml is the list of plug-in not looked into and why.

The XML folder will also contain a bunch of folders whose names are plug-in id (with version) whose API are referenced (used). These folders will again have sub-folder named as the plug-id id (with version) which references those APIs. The usage (or violation) is stored  is XML files under their respective folders.

This structure is very technical and for sparing you the trouble of understanding it, the report can be converted to HTML files. So it will be more useful to understand them.

Example API Use HTML report


The report has three sections

Scan Details will show the parameters used for generating the report. This information comes from meta.xml mentioned above.


Additional Bundle Information gives the link to the bundles that were not searched. The color legends are self-explanatory

References section is a table detailing the bundles who are referenced (used) along with the number of references of different types. A reference is a usage of a type, method or field.

  • API - any public reference
  • Internal - any reference from an internal package
  • Internal-Permissible - any reference from an internal package but visible to the consuming (or referencing) bundle due to x-friends marking in manifest.
  • Fragment-Permissible - same as Internal-Permissible but from fragment bundles
  • Illegal - references which violates the API restrictions placed using JavaDoc tags.
Each bundle name is a hyper-link that would open the details for than bundle. The details for org.eclipse.apitest would look like this


Opening the details shows the list of the Referenced Types (types being used). Each type can be opened (follow the hyper-link) to see each member and visibility details.


This way you can find of each usage - valid or otherwise.

The other API Tooling reports too are structured in similar hierarchy. However, with API Use Scans you can do more ... so stay tuned for more.