当被问到“你知道JAZZ,你在使用JAZZ吗”这个问题时,我相信很多人都会不假思索地说“是的”。但如果问题换成“你在JAZZ平台的基础上开发过新工具吗”,大家是否还会给出肯定的回答呢?
在JAZZ平台席卷全球的同时,大家对JAZZ的了解和喜爱越来越深,更多的人开始尝试基于JAZZ的开发,以求对JAZZ更深的了解。我们也是其中的一份子,并且成功实现了基于JAZZ的用于代码检查的插件EasyInspect。这里,我们希望能够跟大家一起分享我们在开发EasyInspect过程中所获得的实践经验,并希望它能为其他JAZZ的热爱者带来一定帮助。
首先简单介绍一下我们的成果EasyInspect。前面已经提过,它是基于JAZZ平台的插件,可以很好的与Rational Team Concert集成,它的目标是方便开发人员进行高效的代码检查,从而提高代码的质量。它主要的特性有:
n 基于上下文的代码评论:自动记录被评论代码段的位置信息;源文件及被评论代码段的智能定位
n 与版本控制系统的集成:保证正确版本的源文件被检查;代码评论与版本信息保持关联
n 高效的通信:借用了JAZZ平台的通信机制,使代码作者可以及时了解到新的评论;方便开发组基于特定的代码评论发起讨论
在开发EasyInspect的具体实践中,我们与JAZZ的多个特性进行了更亲密的接触。在接下来的部分我们将从如下几个方面来介绍我们的实践, 如:开发环境的搭建、工作项(WorkItem)的应用与扩展、版本控制与应用、工作流、与即时交谈工具的集成、插件的部署等。
1. 配置基于Jazz RTC的扩展开发环境
注册Jazz.net帐号
在开始之前,先确保你有一个Jazz.net帐号。Jazz.net帐号不仅是下载代码的必要前提,它还允许你访问Jazz.net网上的各种开发资源,包括WIKI、论坛和整个开发社区。
请访问https://jazz.net/首页注册Jazz.net帐号。
下载Jazz RTC代码
为了配置Jazz RTC开发环境,首先需要下载Jazz RTC的客户端和服务器端代码,我们同时需要可执行代码和源代码。
请访问https://jazz.net/downloads/RationalTeamConcert找到下载页面。到写稿时Jazz RTC的最新版本是1.0.1.1。在”All Downloads”标签下找到下面的下载内容。
l 下载可执行代码
Express-C,Client for Eclipse IDE and Server (Zip版)
l 下载源代码 (在下载页面底部)
- Jazz Team Server
- Rational Team Concert Client
- Jazz JUnit Tests
解压缩成开发环境
将Client for Eclipse IDE and Server (Zip版)解开到文件系统,下文以[InstallDir]指代解压缩的位置。由于Zip中的目录结构非常深,为了确保解压缩后的文件路径不超过文件系统的一些限制,请尽可能在系统根目录(或浅层目录)解压缩。
解开后的内容结构大致如下所示。
[InstallDir]
jazz
buildsystem
client
repotools
scmtools
server
接着解压缩源代码Zip文件。它们应当被解开到[InstallDir]/jazz/client/eclipse的位置。之后,文件系统中应该出现下面的目录结构。
[InstallDir]
jazz
client
eclipse
source
base
eclipse
rtc
server
tests
到此为止,你已经准备好了Jazz RTC插件扩展的开发环境。你可以在在下面的位置找到Rational Team Concert的启动文件:[InstallDir]/jazz/client/eclipse/TeamConcert.exe。这将是你之后的开发环境。
启动RTC和配置Target Platform
启动RTC开发环境([InstallDir]/jazz/client/eclipse/TeamConcert.exe),并在Preference中(Window > Preferences... > Plug-in Development > Target Platform)配置插件开发的Target Platform为Jazz Team Server and Binaries。
然后点击”Load Target”按钮,并在完成后确认。
启动和调试客户端的Jazz插件
到这里,Jazz客户端的开发环境已经配置完成。你可以像开发一般Eclipse插件一样开发Jazz RTC客户端的插件了,因为Jazz RTC插件首先也是一个Eclipse插件。
运行和调试Jazz RTC插件的方法和普通Eclipse插件并无不同,可以在Run/Debug Configuration中(Run > Open Run/Debug Dialog…)配置。例如下图就是一个运行配置,加载了Workspace中一些RTC插件运行和调试。
启动和调试服务器端的Jazz插件
Jazz与传统的IDE最大区别就在于它拥有统一的服务器端,因此开发Jazz RTC扩展的一个重要内容是开发服务器端的扩展插件。为了方便服务器端的开发和调试,有必要配置一个能直接在IDE中启动和调试的Jazz服务器。
之前我们已经下载和安装了Jazz Server的可执行代码,现在需要做的就是在IDE 中建立一个运行配置来启动它。Jazz开发社区中有预先配置好了运行配置,我们可以直接下载使用。
https://jazz.net/wiki/pub/Main/JazzServerRunAndDebug/JazzServer-06-RTC10-Maximal.launch
下载上面的launch文件,并复制到Workspace中的任意项目里(一般launch运行配置被放在项目顶层的launches目录中)。刷新Workspace,就可以在Run/Debug Configuration中(Run > Open Run/Debug Dialog…)找到Jazz Server的运行配置。
勾选Workspace中你开发的服务器端插件,之后启动就可以运行和调试Jazz Server了。
(若遇到“org.apache.commons.logging.LogConfigurationException: Invalid class loader hierarchy. You have more than one version of 'org.apache.commons.logging.Log' visible, which is not allowed.”,请看下面关于org.apache.commons.logging的问题的解决办法。)
注意:已知关于org.apache.commons.logging的问题
有些情况下,会在启动Jazz Server时遇到关于logging的异常“org.apache.commons.logging.LogConfigurationException”。这时打开运行配置,并在Target Platform下寻找org.apache.commons.logging,会看到类似下面,同时存在1.0.4和1.0.5两个不同版本的情况:
由于Eclipse的一个缺陷,如果你禁用其中一个,下次启动时它又会被自动启用。解决的办法是:
1. 在Target Platform下面禁用所有的logging实现。
2. 导入org.apache.commons.logging(1.0.5.jazz)到Workspace中(从菜单选择File > Import... > Plug-ins and Fragments)。
3. 在运行配置的Workspace组中勾选org.apache.commons.logging(1.0.5.jazz)。
然后重新启动运行配置,问题应该解决了。
2.Work Item的应用和扩展
在团队协同工作中,常常需要记录、追踪和管理团队成员的各种工作和任务。这些工作和任务总是具有一些共同的属性,同时又相互有所区别;它们还具有若干种状态信息,进而和流程绑定。Jazz为管理这些工作和任务提供了工作项(Work Item)的概念:
n 每个Work Item都有一个类型属性,它将Work Item按照使用的目的不同分为若干类,如Defect,Task等。如果Jazz中存在的几种Work Item类型不能满足需要,开发者可以通过扩展来加入新的Work Item类型。具有相同类型的Work Item将具有相同的属性集以及相同的状态转换策略。
n Work Item有一组内建的属性,这些属性与它们的类型无关,也就是说每种Work Item都具有这些属性,如ID,摘要,描述,类型,状态,严重程度,优先级,创建时间,创建人等等;除了内建属性外,每个Work Item类型都可以自定义新的属性,这些新的属性被称为定制属性。
n 为了记录Work Item与其它Work Item之间,或与其它实体之间的关系,Jazz使用了Link的概念。已有的Link类型有“Parent”,“Child”, “Duplicate”等,分别表示一个Work Item是另一个的父任务,子任务,及重复项。Link信息并不是存储在Work Item之中,而是通过Link service提供的API进行操作。Link允许扩展,开发者可以自己的需要来定义所需的Link类型。
JAZZ支持对WorkItem的扩展以满足特定的需求,接下来我们结合在开发EasyInspection的过程中的实践,来具体介绍如何对Work Item进行扩展。
在EasyInspection中,我们需要为用户创建一种特殊的、与Code Inspection相关的Work Item;Jazz中已有的类型如Defect、Task等类型都不是很合适;而且我们希望通过该类型可以将这种Work Item与其它的Work Item区分开来;于是我们决定建立一种称之为Inspection的新的Work Item类型。
Jazz为扩展Work Item类型提供的扩展点是“com.ibm.team.workitem.common.workItemType”。我们新建了一个Jazz/Eclipse插件项目,在plugin.xml中声明对它进行扩展,并指定新类型的ID, 名称和分类,如下所示。
point="com.ibm.team.workitem.common.workItemType">
id="com.ibm.team.rtc.inspection.common.workItemType.inspection"
name="Inspection"
category="com.ibm.team.workitem.workItemType"
>
(注意,在运行EasyInspection之前,需要将该插件部署到RTC的server中。)
在运行时,通过所声明的类型ID “com.ibm.team.rtc.inspection.common.workItemType.inspection”找到WorkItem类型实例后,就可以动态的创建属于该类型的Work Item了:
public static final String CodeInspectionWorkItemTypeID =
"com.ibm.team.rtc.inspection.common.workItemType.inspection";
/**
* Create a "Inspection" work item instance, and then use the "workItemOperation" to initialize * it.
* @param projectArea the handle of the project area;
* @param workItemOperation a WorkItemOperation implementation that would initialize and
* save the new work item;
* @param monitor
* @return the handle of the new created work item.
* @throws TeamRepositoryException
*/
public IWorkItemHandle createCodeInspectionWorkItem(IProjectAreaHandle projectArea,
WorkItemOperation workItemOperation, IProgressMonitor monitor) throws TeamRepositoryException {
// find the definition of the work item type
IWorkItemType workItemType = findWorkItemType(projectArea,
CodeInspectionWorkItemTypeID, monitor);
// call workItemOperation to create, initialize and save the work item.
return workItemOperation.run(workItemType, monitor);
}
private IWorkItemType findWorkItemType(IProjectAreaHandle prjArea, String itemTypeId,
IProgressMonitor mon) throws TeamRepositoryException {
// get the repository
ITeamRepository repos = context.teamRepository();
// get the instance of the work item client
IWorkItemClient workItemClient = (IWorkItemClient) repos.getClientLibrary(IWorkItemClient.class);
// find the work item type definition through the type ID.
return workItemClient.findWorkItemType(prjArea, itemTypeId, mon);
}
当用户创建一个Inspection类型的Work Item时,往往需要指定与此Work Item相关联的代码片段或者文件名。例如,用户A发现在文件abc.java的50行处有一个编程错误,需要通知用户B修改,于是他创建一个类型为Inspection的Work Item给B,加入描述,并在Work Item中标注出此位置。为了记录该位置信息并帮助用户快速定位,我们决定扩展并使用Link,以满足此需求。
与扩展Work Item类型一样,需要首先在plugin.xml中声明此扩展。Jazz提供的扩展点是“com.ibm.team.repository.common.linkTypes”,我们指定新的Link类型的ID为“com.ibm.team.rtc.inspection.common.linkType.sourceCode”,它是从一个Work Item指向一个或多个源代码文件。
point="com.ibm.team.repository.common.linkTypes">
id="com.ibm.team.rtc.inspection.common.linkType.sourceCode"
internal="false">
packageURI="com.ibm.team.workitem">
id="sourceCode" icon="/icons/obj16/resolutn_wontdo.gif"
multiplicity="0..n">
有了此声明后,在程序中可以通过此ID来获取到对该Link的描述符,然后通过Link service的API创建Link。
// get the work item
IWorkItem workItem = workingCopy.getWorkItem();
.... ...
// SourceCodeLocator contains the location information of the selected source files.
SourceCodeLocator[] resources;
... ...
// get the definition of the link type, and then get the descriptor
// for it's endpoint
IEndPointDescriptor endPoint = ILinkTypeRegistry.INSTANCE.getLinkType(
“com.ibm.team.rtc.inspection.common.linkType.sourceCode “) .getTargetEndPointDescriptor();
// save the location information one by one
for (int i = 0, n = resources.length; i < n; i++) {
// create a reference to the source code entity
IURIReference uri = IReferenceFactory.INSTANCE.createReferenceFromURI(resources[i].toUri());
// add this reference to the work item;
workingCopy.getReferences().add(endPoint, uri);
}
下图为我们在EasyInspect中创建的LINK的具体实现效果:
3. 版本控制与应用
JAZZ的内嵌版本控制组件提供诸如存储、获取、代码及文档共享等一系列功能来协助项目组的开发。大家对JAZZ中的流以及变更集应该是比较了解了,因此不再对此再多加叙述。这里要跟大家分享的是EasyInspect中与文件版本相关的一些实现。
EasyInspect中将对代码的评论及当前所检查的源代码的版本信息进行了关联,因而保证了开发人员在查看并解决代码评论时可以准确地理解,避免了代码评论显示在不同版本的源代码中引起的误解。
在具体实现当中,我们通过获取源文件对应的UUID来区分版本,并将该UUID信息存储在代码评论相关的工作项当中。
IResource res;
IShareable s = (IShareable) res.getAdapter(IShareable.class)
IVersionableHandle versionHandler = s.getVersionable();
String version = versionHandler.getStateId().getUuidValue();
此外,通过该UUID,我们可以获取与之对应的完整的文件内容。因而如果开发人员本地的代码版本与被检查的代码的版本不一致时,EasyInspect可以自动获取到正确版本的源代码并以只读形式呈现给开发人员,从而使开发人员能够更好的理解对代码的评论。
请大家注意下图标记中末尾处的字符串,这就是被获取到的UUID。
4. 与即时交谈工具的集成
Rational Team Concert现在支持与Lotus Sametime 7.5 和Lotus Sametime 8.0的集成。用户可以很方便地在Rational Team Concert中和团队其他成员进行实时的交流。
配置Rational Team Concert与Sametime的集成
1. 在Sametime的安装目录,在配置文件plugin_customization.ini中,设置以下属性: com.ibm.collaboration.realtime.brokerbridge/startBroker=true
2. 在Rational Team Concert中,选择Windows à Preferences à Instant Messaging, 弹出的新窗口中设置新的即时通讯的账号(如下图)。
图. 在Rational Team Concert中配置即时通讯账号
在EasyInspect中,我们也借用了对Sametime的集成以方便组员之间的交流与协作。
5. WorkItem与工作流
work item可以用来跟踪开发过程中的问题和任务,并且是评估项目健康状况的重要因素。Rational Team Concert预定义了多个work item类型,涵盖了计划、需求、用例、任务、构建和缺陷等方面。你还可以通过定义新的work item类型以满足团队特别的流程需要。每一种work item 类型都会关联一个状态转移模型,在其中定义了该work item类型可能的状态,在某一状态时用户可以采取的行为以及该行为所引起的状态的变迁。
你可以通过以下步骤添加新的work item类型:
1. 在Team Artifacts视图中,右键Project Area,选择Open。选择Process Configuration,展开Project Configuration->Configuration Data->Work Items->Types and Attributes。
2. 在Work item types区域中,点击add,在弹出的窗口中输入Name和ID。然后在Custom Attributes区域中,点击add,在弹出的窗口中输入Name和Type创建该work item类型的属性。
添加新的workflow:
1. 在Team Artifacts视图中,右键Project Area,选择Open。选择Process Configuration,展开Project Configuration->Configuration Data->Work Items->Workflows。
2. 点击Add,添加新的workflow.
3. 在States区域中,添加该workflow所拥有的状态。在Actions区域中,添加用户可以采取的Action。
4. 在Transition矩阵中,对于每一种状态的转移,在新老状态所对应的格子里选择合适的Action.
建立work item类型与workflow的关联,完成状态转移模型的配置。
1. 在Team Artifacts视图中,右键Project Area,选择Open。选择Process Configuration,展开Project Configuration->Configuration Data->Work Items->Workflow bindings。
2. 选择work item类型,选择workflow,点击Save保存配置。
此外,你可以通过编程方式得到work item的状态以及可采取的Action:
IWorkItemClient client= (IWorkItemClient) repository.getClientLibrary(IWorkItemClient.class);
IWorkflowInfo workflowInfo = workflowInfo = client.findWorkflowInfo(workItem, null);
Identifier state= workItem.getState2();
if (state != null) {
Identifier[] actionIds= workflowInfo.getActionIds(state);
if (actionIds.length > 0) {
for (int i= 0; i < actionIds.length; i++) {
Identifier actionId= actionIds[i];
ChangeWorkItemStateAction action= new ChangeWorkItemStateAction(workflowInfo.getActionName(actionId), workItem, actionId,this);
URL url= workflowInfo.getActionIconName(actionId);
if (url != null) {
ImageDescriptor descriptor= WorkItemUI.getImageDescriptor(url);
if (descriptor != null)
action.setImageDescriptor(descriptor);
}
}
}
}
在EasyInspect中,我们便采用了编程的方式来获取可进行的操作。
6. 插件的部署
如果对JAZZ平台进行了扩展,则部署通常会包含客户端及服务器端两部分。 EasyInspect除了在客户端增加了新的视图,而且创建了新的工作项的类型。对于新增加的客户端的视图,其部署相对较为简单,同部署Eclipse插件的步骤是一样的。服务器端的部署相对来说步骤会多一些,如下是EasyInspect采用的服务器端部署方式,:
1. 首先要准备好你拥有的RTC的许可证文件
2. 将服务器端需要部署的JAR包拷贝的JAZZ应用程序的部署目录中的“jazz\WEB-INF\eclipse\plugins”中
3. 编辑“\jazz\WEB-INF\eclipse\configuration\”目录中的config.ini文件,将部署的JAR包信息加入其中,以下示例是EasyInspect添入的信息:
…
com.ibm.team.repository.jndi@start, \
org.apache.naming@start, \
com.ibm.team.rtc.inspection.common@start, \
org.opengroup.arm40-fragment
osgi.bundles.defaultStartLevel=4
…
4. 清除JAZZ应用程序的临时目录中的缓存信息,并重新启动Tomcat或WAS服务器
5. 重新上传许可证
完成这些步骤,你就可以体验你对JAZZ平台的扩展成果了,并可以选择将你的成果与其他的JAZZ用户来分享。
以上是我们在使用和学习JAZZ/RTC过程中的一些具体的实践经验,仅供大家参考,同时我们也欢迎大家一起就在JAZZ平台进行扩展进行探讨。此外如果大家想进一步了解EasyInspect,也可以跟我们联系。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21560959/viewspace-592509/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/21560959/viewspace-592509/