2016年7月

Introduction to the Build Lifecycle(Maven运行周期)

翻译自:Introduction to the Build Lifecycle

Table Of Contents

Build Lifecycle Basics
Setting Up Your Project to Use the Build Lifecycle
    Packaging
    Plugins
Lifecycle Reference
Built-in Lifecycle Bindings

大纲
基本概念
如何配置工程
打包
插件
详细内容
运行周期包含步骤

Build Lifecycle Basics

Maven is based around the central concept of a build lifecycle. What this means is that the process for building and distributing a particular artifact (project) is clearly defined.

For the person building a project, this means that it is only necessary to learn a small set of commands to build any Maven project, and the POM will ensure they get the results they desired.

There are three built-in build lifecycles: default, clean and site. The default lifecycle handles your project deployment, the clean lifecycle handles project cleaning, while the site lifecycle handles the creation of your project's site documentation.

基本概念
Maven是围绕运行周期来工作的,这样做的意义就是要明确界定出项目的生产和部署等不同处理过程。
我们只需要了解其中几个简单的Maven命令就可以通过POM文件去构建需要的工程了。
运行周期包含了三个基本步骤:缺省(default)、清理(clean)和站点(site)。缺省步骤负责部署项目,清理步骤用于项目的清理过程,使用站点步骤可以产生项目的文档和一些后续任务。

A Build Lifecycle is Made Up of Phases
一个构建周期包含的阶段

Each of these build lifecycles is defined by a different list of build phases, wherein a build phase represents a stage in the lifecycle.
每个构建周期是包含了不同的构建步骤序列,序列中的每一个构建步骤就是生命周期中的一个过程。

For example, the default lifecycle comprises of the following phases (for a complete list of the lifecycle phases, refer to the Lifecycle Reference):

validate - validate the project is correct and all necessary information is available
compile - compile the source code of the project
test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
package - take the compiled code and package it in its distributable format, such as a JAR.
verify - run any checks on results of integration tests to ensure quality criteria are met
install - install the package into the local repository, for use as a dependency in other projects locally
deploy - done in the build environment, copies the final package to the remote repository for sharing with other developers and projects.

例如缺省模式就包含如下几个步骤(点击查看完整的构建步骤生命周期
确认-
编译 -
测试 -
打包 -
验证 -
安装 -
部署 -

These lifecycle phases (plus the other lifecycle phases not shown here) are executed sequentially to complete the default lifecycle. Given the lifecycle phases above, this means that when the default lifecycle is used, Maven will first validate the project, then will try to compile the sources, run those against the tests, package the binaries (e.g. jar), run integration tests against that package, verify the integration tests, install the verified package to the local repository, then deploy the installed package to a remote repository.

第1章 绪论 (1.3 研究目的与内容)

1.3 研究目的与内容
1.3.1 研究目的
论文主要研究目的是设计并实现具有多维度数据分析展现功能的日志分析软件平台,其中中间媒介数据载体(Intermediate Database)使用的是基于Hadoop的分布式文件系统(Hadoop Distributed File System,简称HDFS),使用HDFS目的主要是用来提高日志分析中日志记录分组的计算效率,解决对大量日志数据的查询与管理问题。该日志分析软件平台可以满足对日常大量日志数据进行的模糊匹配分析工作,可实现文本日志数据导入;日志数据分析、归类;分析结果报表可视化的功能。
在需求分析阶段,主要分析了当前业务中使用的开源数据质量产品的主要功能点、用途,充分了解各个工具的工作的运行原理,提取重要功能进行梳理,并对数据处理的性能进行了分析。在当前业务处理过程中数据集成系统会产生大量日志文件,日志分析人员需要对不同类型日志进行分类处理,并需要提取日志中有用信息制作数据分析报表。
目前工作中对日志文件的管理和查询管理工作目前主要依赖开源数据分析软件完成,有诸多不便之处,本次开发的日志分析平台目标主要用于解决以下在日常数据处理过程中遇到的几个方面的问题:
(1) 将开源数据分析技术集成到同一平台完成日志数据分析
(2) 实现基于Map/Reduce的分组算法,提高对日志数据的分析效率
(3) 提高历史日志数据查询速度
(4) 将通用分组算法做成可配置模式,在数据分析过程中可配置不同分组算法
(5) 解决历史日志数据管理与存储问题
论文中设计的日志分析平台主要用于对日常日志数据进行高效处理,其中包括:使用模糊分组算法按关键词对日志文本数据进行分组、可视化展现分析结果。

1.3.2 主要研究内容
论文的研究内容主要包含在以下三个方面:基于RAP技术的日志分析平台用户界面设计与开发;对数据进行数据抽取、过滤、导入,完成基于常用数据匹配算法的Map/Reduce框架实现,以针对HDFS中数据的通用查询与分析功能;并实现以图表形式展现日志分析挖掘结果。具体技术方案如下:
(1) 基于Eclipse RAP(Remote Application Platform)框架开发日志分析软件前端界面
Eclipse RAP框架提供了丰富的网页前端控件,并集成OSGi(Open Service Gateway Initiative)与Java EE(Java Platform Enterprise Edition),本次开发的日志分析平台框架部分主要采用RAP开源技术结合Eclipse Plug-ins插件技术开发应用程序界面,利用插件开发技术将业务应用组件模块化,分别开发前端用户界面与后台数据处理功能模块,再通过RAP平台中的OSGi将系统整合起来,从而降低数据处理功能与前端用户界面的耦合性。前端用户界面主要功能包括:数据库连接控制视图,数据集成视图,数据检索视图,算法配置页面等。
(2) 研究HDFS分布式文件系统作为日志分析软件中间媒介数据载体的数据存储方式
Hadoop实现了一个分布式文件系统,简称HDFS。HDFS有着高容错性的数据处理优势,并且其设计架构允许将其部署在配置较低的硬件平台上。而且它提供高传输率来访问应用程序的数据。Hadoop的功能特点适合本次论文中所需的对于大量日志数据进行高效分析的需求,所以论文中设计到的数据处理技术采用基于Hadoop 分布式系统基础架构作为中间媒介数据载体并利用Map/Reduce框架实现数据分组功能(图1-2)。

ddd.png
图1-2 通过Map/Reduce框架处理HDFS
Figure 1-2 Map/Reduce in HDFS

(3) 多维数据可视化技术
基于联机分析处理技术设计多维数据模型用于存储日志分析结果,使用SpagoBI、JProvit等开源数据可视化技术组件实现对日志分析结果的可视化展现。

第1章 绪论 (1.2 研究现状)

(1) 业务现状

当前数据处理业务(以ICCPRINT类型数据处理为例说明数据集成中日志数据的生成过程)数据集成过程如下图1-1所示:
hh.png
图1-1 ICCPRINT类型数据处理过程[5]

Figure 1-1 ICCPRINT Data Processing Steps [5]
如上图在不同数据集成软件运行过程中会产生大量数据处理日志文本文件(Log File),如下为日志文件片段:
INFO (2012-09-25) 17:53.07:943 [core.runnable] (Unknown-URI) Unknown-thread/DefaultRunnableManager: ThreadPool named "default" created with maximum queue-size=2147483647,max-pool-size=5,min-pool-size=5,
priority=5,isDaemon=false,keep-alive-time-ms=60000,block-policy="RUN",shutdown-wait-time-ms=-1

INFO (2012-09-25) 17:53.07:946 [core.runnable] (Unknown-URI) Unknown-thread/DefaultRunnableManager: ThreadPool named "daemon" created with no queue,max-pool-size=2147483647,min-pool-size=1,priority=5,
isDaemon=true,keep-alive-time-ms=60000,block-policy=ABORT,shutdown-wait-time-ms=-1

WARN (2012-09-25) 17:53.08:576 [core.language.java] (Unknown-URI) Unknown-thread/JavaLanguage: Attempted to retrieve directory listing of non-directory C:\Windows\Sun\Java\lib\ext

其中包含如日志等级(INFO、WARN、ERROR),具体位置(core.runnable、core.language.java)以及相应描述信息中的具体问题等。在分析过程中,工程师需要对不同类型日志进行分类处理,如在第一第二两条日志中的描述部分可以看出,其中只有部分关键词不同,但是日志可以归为同一类型,这就需要在开发日志数据分析算法时设计模糊匹配算法,并通过可调节的阈值动态实现对不同日志数据进行正确分组。用于数据模糊匹配分组的算法主要包括Soundex,Jaro ,Jaro-Winkler,Q-gram等。
目前正在使用中的日志分析、集成工具主要包括Talend,Excel,MySQL等以及相关客户端开发工具如HeidiSQL,Eclipse,Sharp Developer, MySQL Administrator,在Linux端查询数据主要使用DBeaver和Oracle SQL Developer。在数据分析阶段手动处理Excel的过程非常繁琐,相应的日志数据分组程序也只能单机运行,在处理大文件时效率很低,对于历史日志数据也没有健全的管理机制,对于客户提供的数据在数据集成过程中不能在日志分析报告中完全体现出数据缺陷,容易造成数据结果丢失,报表统计不准确等问题。
(2) 用于日志分析的数据分析技术发展现状
国外数据分析产品主要包括开源产品和商业产品两大类,以IBM InfoSphere、Informatica、SAS DataFlux等为代表的商业智能数据分析产品以其功能丰富,定制性强等优势被广泛应用于企业级数据分析处理中。与此同时,随着大数据时代的到来,越来越多的创新型开源数据分析产品也逐渐占据一定市场。
市场对于高活性的商务智能(BI)和主数据管理(MDM)产品的需求很大,信息治理方法数量在迅速增加。大型软件供应商通过收购较小的专业软件供应商不断进入数据质量软件产品市场(例如,甲骨文公司最近收购了Datanomic),不断涌现的新的软件机构(例如在本次魔力四象限中,新的竞争对手,如Talend和Ataccama)。各种新的数据集成工具和MDM(Master Data Management)产品不断汇聚到数据质量工具软件的市场,今后该领域的发展趋势是向着更广泛的数据管理和综合治理能力方向跨越,这种技术发展路线也反映了供应商的愿景。
分析师Ted Friedman(Gartner)认为:DataFlux的看点并不多,倒是新加入的一些公司吸引力客户的眼球,比如Oracle。Friedman向我们介绍,Oracle公司的数据质量产品完全源自其收购的技术,18个月之前,他们收购了Silver Creek,之后又在今年收购了Datanomic。因此目前Oracle无论是从软件技术还是从市场份额方面都已经有资格在魔力象限中占据一席之地。来自法国的Talend公司是报告中唯一一家纯开源软件厂商,而捷克软件公司Ataccama还在不断向客户普及他们免费的数据剖析(data profiling)工具。Friedman表示:“我们希望看到在数据质量、数据集成市场中出现更多的竞争者和不同的解决方案,最好的价格低廉或者干脆是免费的工具。从全球角度来看,我们应该注意到数据质量市场中的竞争者有很多不是来自于美国,Ataccama ,Talend这样来自欧洲的厂商已经证明了自己的能力。”在领导者象限中,除了DataFlux之外还有Informatica、Trillium Software、IBM和SAP四家公司。Pitney Bowes Business Insight和Oracle两家处在挑战者象限,DataLever、Uniserv、DataMentors、Human Inference、Datactics 和Innovative Systems处在特定领域象限,而Talend 和 Ataccama则处在有远见者象限[16]。
随着大数据热在国内的兴起,少数金融,电子商务企业开始大量应用大数据处理理论完成业务分析与战略决策,基于国外开源数据处理框架也逐渐积累开发出了一些自己的产品,大多是在数据仓库、决策支持、数据挖掘研究中,对其作一些比较简单的阐述。银行、保险和证券等对客户数据的准确性要求很高的行业,都在做各自的客户数据的清洗工作,针对各自具体应用而开发软件,有越来越多的理论性的成果见诸于报道。

Understanding how Eclipse plug-ins work with OSGi

Eclipse and OSGi from A to Z, or in this case, plugin.xml to manifest.mf

The core of the Eclipse integrated development environment (IDE) and Eclipse Rich Client Platform (RCP) applications is driven by an implementation of the Open Services Gateway Initiative (OSGi) specification. This article illustrates Eclipse's relationship with OSGi by describing what a plug-in is in terms of the Eclipse platform and traces the evolution of plug-ins from Eclipse V2.1 through today's OSGi-based implementation. It also explains the OSGi manifest.mf file options, along with the additions provided through Eclipse.

Most Java™ programming language developers are introduced to Eclipse through its function as an IDE. The Eclipse IDE actually consists of a collection of interacting components called plug-ins. These plug-ins, which make up the base of the IDE, can also be used to create other desktop applications. The minimal set of plug-ins needed to create an Eclipse-based application is referred to as the Eclipse Rich Client Platform (RCP). Plug-ins don't just start themselves, however. They require an environment in which to start and operate. Eclipse provides this environment with an implementation of the OSGi R4 specification.

Because Eclipse is at its core driven by OSGi, it's important to understand how the concept of an Eclipse plug-in relates to the OSGi framework. In this article, I will explain this relationship in detail by describing what a plug-in is in terms of the Eclipse platform. Then I'll describe the evolution of plug-ins in the Eclipse V2.1 platform through today's OSGi-based implementation. Finally, the OSGi-provided manifest.mf options that apply to Eclipse plug-ins will be covered in detail.

What is a plug-in?

The Eclipse online help defines a plug-in as follows:

"Plug-ins are structured bundles of code and/or data that contribute function to the system. Function can be contributed in the form of code libraries (Java classes with public [application program interfaces] APIs), platform extensions, or even documentation. Plug-ins can define extension points, well-defined places where other plug-ins can add functionality."

The key point to focus on is that plug-ins contribute function in a structured manner. They may provide a service such as logging or piece functionality available in the user interface (UI), such as an editor. Regardless of their function, all plug-ins are defined in the same structured way.

The evolution to OSGi

As mentioned, Eclipse uses OSGi as the basis for its plug-in system. This wasn't always the case, however. Early versions of Eclipse were also designed as a collection of plug-ins, and Eclipse included its own propriety plug-in system to manage the interaction. However, as the requirements of the Eclipse IDE grew, it became apparent that a more robust solution was required. Basic requirements of this new system included the ability to dynamically handle the addition of new plug-ins and stopping existing plug-ins. After considerable research, the Eclipse creators decided to replace the proprietary plug-in framework by implementing the OSGi framework specification.

OSGi is a specification of a service platform. Eclipse provides one of many available implementations of this specification and serves as the reference implementation of the latest OSGi R4 specification. OSGi is a Java-based framework targeted for use by systems that require long running times, dynamic updates, and minimal disruptions to the running environment. Initially, OSGi was targeted at home automation and residential gateway devices. More recently, it has found use in everything from mobile phones to cars.

At its core, OSGi is a component and service model, as illustrated in Figure 1. The OSGi specification defines a unit of modularization called a bundle. (Unless explicitly noted during the rest of this article, the Eclipse term plug-in and the OSGi term bundle are used interchangeably because all Eclipse plug-ins are now OSGi bundles.) OSGi also provides a Java Virtual Machine (JVM)-level service registry that bundles can use to publish, discover, and bind to services.

Figure 1. The interaction of the layers in the host operating system, Java, and OSGi
The OSGi specification defines an infrastructure for a bundle's life cycle and how bundles interact. These rules are enforced through the use of special Java class loaders. In an average Java application, all classes in the CLASSPATH are visible to all other classes. In contrast, the OSGi class loaders restrict class interaction among bundles based on the OSGi specification and the options specified (covered in detail later in this article) in the manifest.mf file for each bundle.

The Eclipse IDE uses a subset of OSGi centered around modularization and bundle life cycle. However, it makes minimal use of the service support OSGi provides. Instead, Eclipse provides its own extension point system to enable bundle interaction. Bundles expose functionality as contributions to other extensions. Bundles also define their own extension points, to which other bundles may contribute. An example of using extension points in Eclipse is the Preferences window. A core Eclipse plug-in provides the central window and exposes an extension point to allow the contribution of additional preference pages. As new plug-ins are added to Eclipse, they can contribute their own pages. The model of extension points in Eclipse is different from basic OSGi services. Bundle extension points are owned by the defining bundle; other bundles simply contribute to them. In comparison, any bundle can implement and use an OSGi service.

Implementing Eclipse using OSGi

In versions of Eclipse before 3.1, you defined plug-in dependencies, as well as extensions and extension points, in each plug-in's plugin.xml file. In the newer versions of Eclipse that use OSGi, dependency information has been broken out into the manifest.mf file, leaving the plugin.xml file containing only XML definitions of extensions and extension points. It is useful to look at a live, working example of this evolution. Listing 1 shows an excerpt from the org.eclipse.pde.ui plug-in from Eclipse V3.0.

Listing 1. Excerpt from the org.eclipse.pde plug-in

































#### The declaration exposes all packages in the plug-in for use in other plug-ins. The plug-in dependency imports section lists the prerequisite plug-ins the org.eclipse.pde.ui plug-in requires.

The next two sections define the extension points org.eclipse.pde.ui makes available to other plug-ins, as well as the contributions it makes to them. In this case, you can see the definition of a custom Eclipse Plug-in Development Environment (PDE) perspective.

Let's look at the same plug-in definition in Eclipse V3.1. Listing 2 shows the plugin.xml file.

Listing 2. Plugin.xml

#### Notice that the export and import information is gone. This information now resides in the manifest.mf file shown in Listing 3. *Listing 3. Manifest.mf* #### Manifest-Version: 1.0 Bundle-Name: %name Bundle-SymbolicName: org.eclipse.pde.ui; singleton:=true Bundle-Version: 3.1.0 Bundle-ClassPath: org.eclipse.pde.ui_3.1.0.jar Bundle-Activator: org.eclipse.pde.internal.ui.PDEPlugin Bundle-Vendor: %provider-name Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.ui.ide, org.eclipse.ui.views, org.eclipse.jface.text, org.eclipse.ui.workbench.texteditor, org.eclipse.ui.editors, org.eclipse.ant.core, org.eclipse.core.resources, org.eclipse.debug.core, org.eclipse.debug.ui, org.eclipse.jdt.core, org.eclipse.jdt.debug.ui, org.eclipse.jdt.launching, org.eclipse.jdt.ui, org.eclipse.pde, org.eclipse.pde.build, org.eclipse.search, org.eclipse.team.core, org.eclipse.ui, org.eclipse.update.core, org.eclipse.ui.forms, org.eclipse.ant.ui, org.eclipse.jdt.junit, org.eclipse.ui.intro, org.eclipse.ui.cheatsheets, org.eclipse.update.configurator, org.eclipse.help.base Bundle-ManifestVersion: 2 Eclipse-AutoStart: true Export-Package: org.eclipse.pde.internal.ui;x-internal:=true, org.eclipse.pde.internal.ui.build;x-internal:=true,

. . .

org.eclipse.pde.ui,
org.eclipse.pde.ui.internal.samples;x-internal:=true,
org.eclipse.pde.ui.templates

The various plug-in imports are now specified as required bundles, and the * package export has been replaced with a list of explicitly exported packages.

The move away from plug-in-level dependencies to dependencies that required the explicit exporting and importing of packages generated a lot of commotion when Eclipse announced the news. The primary complaint was the lack of an equivalent of , which had existed in earlier versions of Eclipse. There are many reasons for this omission, however. The most important reason is the speed gains from having explicit import and exports. Previous versions of Eclipse had to open and scan each plug-in jar file to determine which classes it contained. Not including a * export also provides a level of protection against plug-ins exposing unwanted classes. Plug-in developers must make a conscious choice to make functionality in a plug-in available for outside use. This restriction allows internal packages to stay internal.

OSGi manifest options

The current draft specification for the OSGi R4 framework core is almost 300 pages in PDF form. Covering every portion of this specification is outside the scope of this article, but I do discuss the OSGi manifest.mf options of particular interest to Eclipse plug-in developers:

Bundle-Activator

This class is used to start and stop the bundle. In the example plug-in above, the org.eclipse.pde.internal.ui.PDEPlugin class is specified. This class extends org.eclipse.core.runtime.Plugin, which implements the BundleActivator interface.

Bundle-ClassPath

This property specifies the CLASSPATH to use for the bundle. The property may contain references to directories or jar files inside the bundle jar file. You can use the period to indicate the bundle's root. In the case of the example Eclipse PDE bundle, org.eclipse.pde.ui_3.1.0.jar in the bundle jar file is specified. If you import the source version of the plug-in into your workspace, the import process changes the bundle CLASSPATH to appear as Bundle-ClassPath:, which allows the development version of the plug-in to pick up the compiled bundle classes.

Bundle-Version

This property specifies the version number of the bundle. Package imports and required bundle specifications may include a bundle version number.

Export-Package

This property specifies all the packages to publicly expose to other plug-ins.

Import-Package

This property specifies all the packages to explicitly import from required plug-ins. By default, all packages must be resolved for a bundle to start. You can also specify package imports as optional to support cases in which a package may not exist. Explicitly imported classes are resolved before packages from Require-Bundle plug-ins.

Require-Bundle

This property specifies which bundles and their exported packages to import for use in the given bundle. Specified bundles are evaluated after explicit package imports.

Additional manifest options provided by Eclipse

The manifest.mf configuration options that the OSGi specification includes don't provide all the functionality that the Eclipse platform requires. As a result, the Eclipse creators have added several extensions (and also proposed them for inclusion in future versions of the OSGi specification):

Export-Package Header Extensions
Eclipse has two OSGi resolver methods -- default and strict -- that the osgi.resolver property can specify. Eclipse also includes two extensions to the Export-Package property -- x-internal and x-friends -- both of which are enforced when you enable Strict mode.

x-internal
The default value for this property is false. When internal packages are specified as true using this option, the Eclipse PDE discourages their use.

x-friends
This option is similar to x-internal, but allows certain bundles to use the exported packages that have this option. Others bundles are discouraged. The x-internal option takes precedence over x-friends.

Eclipse-AutoStart
By default, Eclipse loads bundles on demand. Therefore, bundles are loaded when the first class they contain is required by a bundle that imports it. Specifying this value as ?? causes Eclipse to load the bundle at startup. You can also specify a list of exceptions, which are classes, and resources, and which may be loaded without starting their containing bundle.

Eclipse-PlatformFilter
This property allows you to specify conditions that must evaluate to true for a bundle to start. You can include the following information in the expression you specify:

    osgi.nl for language
    osgi.os for operating system
    osgi.arch for architecture
    osgi.ws for windowing system

An example of how to use this property is to verify whether the operating system is not Mac OS X before starting a plug-in that uses the SWT_AWT bridge. (The Mac OS X implementation of the Standard Widget Toolkit (SWT) doesn't currently support this feature.)

Eclipse-BuddyPolicy
This option specifies the class loading policy of the bundle. Typically, bundles only have visibility in their internal classes and those imported from dependent bundles. The popular example that has been used in the Eclipse newsgroups to explain buddy class loading is Hibernate. The Hibernate framework must see classes and resources that are user-created and not part of Hibernate itself. One such case is when you use a project to dynamically fill a class from a Hibernate Query Language (HQL) query. By default, Hibernate won't be able to see classes outside the plug-in containing the Hibernate jar files, and requiring modification of the Hibernate plug-in for the creation of each plug-in containing classes that Hibernate maps is not acceptable. Fortunately, you can solve this using the buddy class loader options explained in the Buddy class loader options section.

Buddy class loader options

Begin by creating a plug-in for Hibernate. Then create a plug-in containing the domain-specific classes with a dependency on Hibernate. Add the following line to the Hibernate plug-in manifest: Eclipse-BuddyPolicy: registered.

Add the following manifest property to the manifest of the plug-in containing the domain-specific classes or resources: Eclipse-RegisterBuddy: hibernate.

This line allows plug-ins to declaratively expose themselves to the Hibernate plug-in without it knowing about them beforehand. Now the Hibernate plug-in can see the needed classes even though it did not specifically import them.

Future directions of Eclipse and OSGi

Eclipse has benefited greatly in its use of OSGi, gaining a robust system managing the life cycle of components in a dynamic manner. New uses, such as dynamic Web Archive (WAR) files on the server tier featuring servlets, JavaServer Pages, and other HTTP resources in Eclipse-style plug-ins are being explored every day.

The Eclipse Foundation has positioned itself to play a key role in driving the OSGi specification forward, both for its own uses and for those of other parties leveraging OSGi. During the transition from the propriety Eclipse plug-in framework to OSGi, many additions were made to the OSGi specification that became part of the OSGi R4 specification release. The Eclipse Equinox project has, as a result, become the OSGi reference implementation moving forward. This involvement, as well as the creation of Java Specification Request (JSR) 291 to manage the evolution OSGi, guarantees that the Eclipse/OSGi partnership will continue to be successful in the years ahead.

[Understanding how Eclipse plug-ins work with OSGi][1]
[1]: http://www.ibm.com/developerworks/library/os-ecl-osgi/index.html