Sunday, October 18, 2009

Section 26.3.  Fragments










26.3. Fragments


Sometimes it is not possible to package a plug-in as one unit. There are two common scenarios where this occurs:


Platform-specific content Some plug-ins need different implementations on different OSs or window systems. You could package the code for all platforms in the plug-in, but this is bulky and cumbersome to manage when you want to add another platform. Splitting the plug-in into one for common code and others for platform-specific code is another possibility. This is problematic since implementation objects often need to access one another's package-visible members. This is not possible across plug-in boundaries.

Locale-specific content Plug-ins often need locale-specific text messages, icons, and other resources. Again, it is possible to package the required resources for all locales together in the plug-in, but this is similarly cumbersome and wasteful. It would be better to package locale content separately and deploy only what is needed.


Eclipse supports these use cases using fragments. Fragments are just like regular plug-ins except their content is seamlessly merged at runtime with a host plug-in rather than being standalone. A fragment's classpath elements are appended to its host's classpath and its registry contributions are made under the host's id. You cannot express dependencies on fragments, just their hosts.


Figure 26-3 shows examples of both platform- and locale-specific fragments. Both fragments have a manifest file that identifies the fragment, its version, and its host id and version range. The following is an example of the markup found in the Runtime's National Language (NL) fragment:


org.eclipse.core.runtime.nl1/MANIFEST.MF
Bundle-SymbolicName: org.eclipse.core.runtime.nl1
Bundle-Version: 3.1.0
Fragment-Host: org.eclipse.core.runtime;bundle-version="[3.1.0,4.0.0)"
Bundle-ClassPath: .



Figure 26-3. Plug-in fragments

[View full size image]




The next snippet is from the Windows SWT fragment's manifest file. Notice the highlighted platform filter line. This is an Eclipse-specific header that identifies the set of environmental conditions that must be met for this bundle to be resolved. In this case, the osgi.os, osgi.ws, and osgi.arch system properties must match the given values. The syntax of the filter is that of standard Lightweight Directory Access Protocol (LDAP) filters and is detailed in the OSGi specification.


org.eclipse.swt.win32.win32.x86/MANIFEST.MF
Bundle-SymbolicName: org.eclipse.swt.win32.win32.x86; singleton:=true
Bundle-Version: 3.1.0
Fragment-Host: org.eclipse.swt; bundle-version="[3.0.0,4.0.0)"
Eclipse-PlatformFilter:
(& (osgi.ws=win32) (osgi.os=win32) (osgi.arch=x86))


In both cases, the fragments directly contain code or resources to be appended to the host's classpath. Adding a fragment's classpath entries, or the fragment itself, to the host is a vital characteristic of fragments. Fragments generally contain implementation detail for the host. Whether it is code or messages, the contents need to be accessed as though they were part of the host. The only way to do this is to put the fragment on the host's classloader. This gives bidirectional access to the classes and resources as well as enables Java package-level visibility. At runtime, the host and fragment behave as if they were a single plug-in.


Fragments are a powerful mechanism, but they are not for every use case. There are several characteristics to consider when you are looking at using fragments:


Fragments are additive Fragments can only add to their host; they cannot override content found in the host. For example, their classpath contributions are appended to those of the host, so if the host has a class or resource, all others are ignored. Their files and resources are similarly added to those of the host plug-in.

Fragments cannot be prerequisites Since they represent implementation detail, their existence should be transparent to other plug-ins. As such, plug-ins cannot depend on fragments.

Fragments are not intended to add API Since you cannot depend on a fragment, they ought not expose additional API since plug-in writers are not able to express a dependency on that API.

Fragments can add exports Normally, fragments are used to supply internal implementation detail. In certain instances such as testing and monitoring fragments, however, they may need to extend the set of packages exported by the host. They do this using normal Export-Package syntax. To support development-time visibility, the host plug-in should be marked with the header Eclipse-ExtensibleAPI: true. This tells PDE to expose the additional fragment exports to plug-ins that depend on the host.


Figure 26-4 shows the OSGi console of a running Eclipse application after typing the short status ("ss") command. Notice that org.eclipse.resources.win32 fragment (#12) is shown as installed (and resolved) and bound to the Resources host plug-in (#13). Notice also that the report for the Resources plug-in also lists plug-in #88 as an attached fragment. It is not shown here, but it is actually the Core Tools Resource Spy fragment. This illustrates that you can have multiple fragments attached to the same host.



Figure 26-4. Fragment resolution status








The OSGi console


It is quite curious that in this day and age of GUIs, a simple command line UI such as the OSGi console should cause such a stir. When people first see that there is a console under the covers, the geek in them comes out and they succumb to the need to manually install, start, stop, and uninstall bundles.


This is good fun, but the console is actually quite powerful and useful for both controlling and introspecting a running system. In addition to controlling bundles, you can investigate specific bundles, diagnose problems with bundles not being resolved, find various contributed services, and so on.


The console is not started by default. To get a console, start Eclipse using the -console command line argument and look for the console's "osgi>" prompt in either the shell you used to launch Eclipse or the new shell created if you launched Eclipse from a desktop icon. Type "help" to get a complete list of available commands.














No comments:

Post a Comment