君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

Using Aperture in OSGI requires a certain environment to be set. You need to include RDF2Go, a triple store implementation with it's driver and dependencies, the SLF4J Logging API and some logging implementation. It is all summarized on a diagram below.

The aperture bundles are generated automatically by the build.xml ant script. Just invoke it and in the directory build/dist/bundles - you will get three jar files whose names begin with: org.semanticdesktop.aperture, org.semanticdesktop.aperture.impl and org.semanticdesktop.aperture.example.

org.semanticdesktop.aperture

This is the bundle that contains all the core interfaces, services, vocabularies and utility classes. It doesn't contain any implementations. If you'd like to extend aperture, write your own crawler, accessor or extractor - this is the bundle you will have to depend on. Also every client application will only need this single dependency. Simple and convenient.

Activating this bundle in an osgi environment makes following services available:

  1. org.semanticdesktop.aperture.accessor.DataAccessorRegistry
  2. org.semanticdesktop.aperture.crawler.CrawlerRegistry
  3. org.semanticdesktop.aperture.datasource.DataSourceRegistry
  4. org.semanticdesktop.aperture.extractor.ExtractorRegistry
  5. org.semanticdesktop.aperture.opener.DataOpenerRegistry
  6. org.semanticdesktop.aperture.hypertext.linkextractor.ExtractorRegistry
  7. org.semanticdesktop.aperture.mime.identifier.MimeTypeIdentifierRegistry
  8. org.semanticdesktop.aperture.security.trustdecider.TrustDeciderRegistry
  9. org.semanticdesktop.aperture.security.trustmanager.TrustManagerRegistry

These registries will listen for appropriate factories appearing in the environment and will automatically include them.

org.semanticdesktop.aperture.impl

This bundle contains all implementations. Every implementation depends on core. The activator of this bundle registers services under appropriate names, so that registries can detect them. Every factory is treated as a separate service. It is registered under the name of the generic interface it implements (e.g. a FileSystemCrawlerFactory is registered under the name of a CrawlerFactory). This enables automatic detection.

org.semanticdesktop.aperture

This bundle contains a quick example how Aperture can be used in OSGI environment. It can be used as a test to determine if you set up your environment correctly. When you start this bundle, it will begin crawling your home directory and extracting all information it can. It won't dig into subdirectories so it shouldn't last too long. After the crawler has finished, you should see the RDF information printed on your screen.

Build infrastructure

This part of this document is a bit technical. You may skip it if you only want to use Aperture. Nevertheless, It may be of some interest to all that need to include aperture in their own projects and would like to influence the packaging.

The OSGi packaging had to be as unobtrusive as possible. It has been decided that the structure of the source tree must not be altered, and that the former packaging method (as a plain jar) must remain available.

build.xml script

Classes that should fall within a bundle are chosen one-by-one. A sophisticated system of selectors has been introduced in the ant build script. Those selectors have been extracted into the selectors.xml file. Aperture has been conceptually divided into ca. 40 'elementary' bundles. In this division the vocabulary and utility classes are in separate bundles. Every Registry service and every implementation has it's own bundle. Every 'elementary' bundle has:

  • It's own selector in the build script. This selector covers:
    • Source files
    • Class files
    • Activator source
    • Activator files
    • Non-java resources (like xml, dtd or icons)
    • Library jars (that are to be included in the bundle
  • It's own activator class.

In order for this to work - every selector is applied to five directories:

  • src/java
  • src/activators
  • build/classes
  • build/classes-activators
  • lib

Additional measures have been taken to prevent non-java resources from being copied twice (from the source and from the classes directory.

Activators

The activators have been kept separate from the 'normal' source code. They are stored in the src/activators subdirectory. Every 'elementary' bundle has it's own Activator. There are basically two kinds of activators: registry activators and implementation activators.

The registry activators are responsible for running the the registries. They are also equipped with osgi ServiceTrackers that listen for implementations appearing and disappearing. There were two reasons why this approach has been chosen.

  • It is much cleaner and simpler. Only the registry Activators need to be aware of other services appearing and disappearing. It is enough for them to use a 15-line service tracker. The implementations can be completely unaware of the registries. The client application can even bypass the registries altogether and search for implementations by itself (by looking for services under the name of the factory interface - see aperture-impl)
  • It makes it possible to have multiple registries in a system.

The coarsegrained bundles are built out of 'elementary' bundles. Every coarsegrained bundle (that is core and impl) has an activator that simply calls the activators of all 'elementary' bundles.

middle-grained bundles

Some attempt has been made to implement a more detailed packaging scheme. It would consist of six bundles:

  • vocabulary (Vocabulary classes)
  • util (Utility classes)
  • Core services:
    • Registries and interfaces for:
      1. DataAccessors
      2. Crawlers
      3. Extractors
      4. DataSources
      5. DataOpeners
    • Core rdf interfaces and classes (RDFContainer, RDF2GoRDFContainer etc.)
  • Supporting services:
    • Registries and interfaces for:
      1. LinkExtractors
      2. MimeTypeIdentifiers
      3. TrustManagers
      4. TrustDeciders
    • Core rdf interfaces and classes (RDFContainer, RDF2GoRDFContainer etc.)
  • Core implementations - implementations of the all mentioned interfaces.
  • Supporting implementations.

Following things have been prepared for this:

  1. There are 'middlegrained' selectors that combine appropriate elementary selectors
  2. There are targets that create jar files with bundles
  3. Those jar files contain manifests that have also been prepared

Unfortunately the 'middle-grained' approach has been abandoned. It prooved too time-consuming to maintain the manifest files for six bundles. It could potentially be done by adopting one of following approaches:

  1. Use eclipse plugin development environment. Create separate projects for every bundle, import the source from external directory (that is from the main aperture directory), use the include/exclude feature to have every bundle include the appropriate set of files and libraries. This approach has the disadvantage, that the build process would not be automated.
  2. Find some tool that would generate manifest files automatically it should provide following functionality
    • Generate the Bundle-Classpath list - a list of all jar files that are included in the bundle
    • Create a set of imports
    • Exclude imports from bundles that are on the Required-bundle list
    • Exclude imports from jars, that are included in the Bundle-Classpath
    • Exclude other imports - defined by some rules
    • Create a set of exports - all packages in the bundle
    • Exclude exports defined by a set of rules
    A tool called mangen has been evaluated but with no success.
posted on 2013-07-17 05:27  刺猬的温驯  阅读(182)  评论(0编辑  收藏  举报