RTC Plain Java API实现同仓库双流同步 新建流无组件问题
RTC基于Plain Java API创建子流未加载组件问题
问题背景
- 开发环境:Eclipse + RTC Plain Java API
- 现有资源:RTC仓库内已部署主流Sample_ROOT
- 需求:基于主流创建业务流Sample_Client_Application,要求完整继承主流所有组件,后续主流的变更自动同步到该业务流
- 异常现象:业务流创建成功,但流内无任何组件加载
现有实现代码
/* parentStream : 代表Sample_ROOT appStream : 代表Sample_Client_Application的DTO对象 projectStreams : 存储项目与对应工作空间映射的HashMap,结构为HashMap<String, List<IWorkspaceHandle>> */ public IWorkspaceConnection createAppInTeamAreas(String parentStream, StreamDTO appStream) throws TeamRepositoryException { monitor.println("Getting Workspace"); IWorkspaceManager workspaceManager = SCMPlatform.getWorkspaceManager(repository); IWorkspaceConnection workspaceConnection = null; Optional<IWorkspaceHandle> handle = projectStreams.get(appStream.getProjectName()).stream().filter(xHandle -> { IWorkspace workspace = null; try { workspace = (IWorkspace) repository.itemManager().fetchCompleteItem(xHandle, IItemManager.DEFAULT, null); } catch (TeamRepositoryException e) { e.printStackTrace(); } return workspace != null && workspace.getName() == parentStream; }).findFirst(); if (handle.isPresent()) { IWorkspace parentWorkSpace = null; try { parentWorkSpace = (IWorkspace) repository.itemManager().fetchCompleteItem(handle.get(), IItemManager.DEFAULT, null); } catch (TeamRepositoryException e) { e.printStackTrace(); return null; } IWorkspaceConnection parentConn = workspaceManager.getWorkspaceConnection(handle.get(), monitor); List<IComponentHandle> parentComps = (List<IComponentHandle>) parentConn.getComponents(); IWorkspaceConnection childConn = null; IItemManager itemManager = repository.itemManager(); for (IComponentHandle parentCompHandle : parentComps) { IItemHandle itemHandle = (IItemHandle) parentCompHandle; IComponent parentComp = (IComponent) itemManager.fetchCompleteItem(itemHandle, IItemManager.DEFAULT, monitor); monitor.println(String.format("Component name : %s", parentComp.getName())); childConn = createAndAddSycrhronizedComponents(parentWorkSpace, parentComp, parentConn, appStream, childConn); } workspaceConnection = childConn; } return workspaceConnection; } private IWorkspaceConnection createAndAddSycrhronizedComponents(IWorkspace parentStream, IComponent parentComp, IWorkspaceConnection parentConnection, StreamDTO childStream, IWorkspaceConnection childConnection) { IWorkspaceManager workspaceManager = SCMPlatform.getWorkspaceManager(repository); IWorkspaceConnection workspaceConnection = null; try { if (childConnection == null) { workspaceConnection = workspaceManager.createWorkspace(repository.loggedInContributor(), childStream.getName(), childStream.getDescription(), monitor); } else { workspaceConnection = childConnection; // 为新创建的仓库设置流目标 IFlowTable flowTarget=workspaceConnection.getFlowTable().getWorkingCopy(); flowTarget.addDeliverFlow(parentStream, repository.getId(), repository.getRepositoryURI(), parentConnection.getComponents(), "Scoped"); flowTarget.addAcceptFlow(parentStream, repository.getId(), repository.getRepositoryURI(), parentConnection.getComponents(), "Scoped"); flowTarget.setCurrent(flowTarget.getDeliverFlow(parentStream)); flowTarget.setCurrent(flowTarget.getAcceptFlow(parentStream)); flowTarget.setDefault(flowTarget.getDeliverFlow(parentStream)); flowTarget.setDefault(flowTarget.getAcceptFlow(parentStream)); workspaceConnection.setFlowTable(flowTarget, monitor); // 向工作空间添加组件 List<Object> componentsToBeAdded=new ArrayList<>(); componentsToBeAdded.add(workspaceConnection.componentOpFactory().addComponent(parentComp, true)); workspaceConnection.applyComponentOperations(componentsToBeAdded, monitor); // 接受流变更到本地仓库 IChangeHistorySyncReport streamChangeHistorySyncReport=workspaceConnection.compareTo(parentConnection, WorkspaceComparisonFlags.INCLUDE_BASELINE_INFO, Collections.EMPTY_LIST, null); workspaceConnection.accept(AcceptFlags.DEFAULT, parentConnection, streamChangeHistorySyncReport, streamChangeHistorySyncReport.incomingBaselines(parentComp), streamChangeHistorySyncReport.incomingChangeSets(parentComp), monitor); } } catch (TeamRepositoryException e) { e.printStackTrace(); } return workspaceConnection; }
问题根因及修复方案
代码存在4个核心问题导致组件未正常加载:
- 流类型创建错误:
workspaceManager.createWorkspace默认创建的是个人仓库工作空间,不是公共流(Stream)。要创建业务流需要调用IWorkspaceManager#createStream方法,传入对应项目区域/团队区域的上下文,否则创建出的资源不属于目标项目流范畴,组件配置不会正常生效。 - 组件添加逻辑执行时机错误:循环处理第一个组件时
childConnection为null,仅创建了工作空间/流,没有执行任何组件添加、流配置逻辑;从第二个组件开始才进入else分支执行组件添加,且每次循环都会重复设置流表、重复对比变更历史,第一个组件完全被遗漏。需要把创建子流、初始化流表的逻辑挪到循环外,循环内只做单组件的添加、基线/变更集同步操作。 - 字符串比较错误:筛选父流时用
==比较字符串名称,Java中==比较的是对象引用不是内容,大概率会导致筛选不到正确的父流handle,后续逻辑直接走空返回。需要改成workspace.getName().equals(parentStream)做内容比较。 - 流作用域配置错误:
addDeliverFlow和addAcceptFlow传入的组件列表是父流的全量组件列表,但此时子流还没添加任何组件,Scoped作用域下空组件列表的流目标不会同步任何内容。应该在所有组件都添加完成后,再统一配置流表的交付、接受规则,或者传空组件列表表示全量组件同步。
修复后的核心逻辑调整点:
- 先筛选到正确的父流连接,提前校验父流是否存在,避免空指针
- 循环外调用
createStream创建目标业务流,初始化流表的基础配置 - 循环内逐个添加父流组件,每添加一个组件就同步该组件对应最新基线
- 所有组件添加、同步完成后,再配置流的默认交付/接受目标,设置自动同步规则
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

