安装和升级 > 升级 ThingWorx > 将 Java 扩展从 8.x 迁移至 9.x
将 Java 扩展从 8.x 迁移至 9.x
仅受 Java 支持的扩展需要迁移。仅当您从 ThingWorx 8.x 升级至 9.x (而非 9.x 升级至 9.x) 且具有如下内容时才需要迁移 Java 扩展:
已实现的生命周期事件,如 initializeEntitycleanupEntity
维护实施中的本地状态
具有其他实体的本地副本 (或硬参考)
在 ThingWorx 高可用性群集中,实体存在于多台服务器上。其信息必须在多台服务器之间保持同步。在发生更改的服务器 (更改服务器) 和同步更改的服务器 (同步服务器) 上,它们的生命周期稍有不同。群集中只有一台服务器是更改服务器,而其他所有服务器都是同步服务器,这样就会重新加载脏实体。更改服务器只是请求所在的服务器;它没有任何特殊的配置或状况。
新增了扩展元数据属性 haCompatible,用于标识扩展是否与 ThingWorx 高可用性群集兼容。有关详细信息,请参阅打包和部署 ThingWorx 解决方案的最佳做法ThingWorx HA 的平台设置
生命周期 API 更改 
利用 ThingWorx 高可用性群集后,下列生命周期 API 方法现需要一个附加参数。更改的原因是更改服务器与同步服务器上的生命周期行为存在差异。在更改服务器上,必须针对生命周期事件执行所有逻辑。而在同步服务器上,您可能只需执行此逻辑的子集。例如,在初始化过程中,不必设置同步服务器上的所有状态,因为状态是共享的。
使用 ContextType 参数,您可以决定是否应执行某些逻辑。NONEContextType 指示它不是次要操作,且所有逻辑都应执行。ContextType 也可区分会触发不同行为的 STARTUPSHUTDOWNINSERTUPDATEDELETE
这些更改会创建编译时错误。对于单一服务器修复,您可以将此参数添加到多个方法中,而不需要进行任何其他更改。为兼容活动-活动群集,请进行以下更改:
initializeEntity()initializeEntity(contextType)
cleanupEntity()cleanupEntity(contextType)
initializeThing()initializeThing(contextType)
startThing()startThing(contextType)
processStartNotification()processStartNotification(contextType)
stopThing()stopThing(contextType)
cleanupThing()cleanupThing(contextType)
在以下事物实体示例中,在初始化更改服务器时,将完成从其层次结构中进行的完整配置表更新,并保留所做更改。在同步服务器上初始化实体时,配置表也会随之发生更新。由于配置表已保存到数据库,因此可以对其进行加载。无需遍历层次结构或执行其他逻辑。
public void initializeEntity(ContextType contextType) throws Exception {
_logger.trace("initializeEntity called on Thing {} with patch operation {} ", getName(), contextType);
if (!contextType.isSecondaryOperation()) {
updateConfigurationTableStructure(contextType, null,
ThingShapeUtilities.getConfigurationTableDataForInheritance(getThingTemplate(), getImplementedThingShapes()));
} else {
updateConfigurationTableStructure(contextType);
}
super.initializeEntity(contextType);
}
在清理操作中,生命周期的行为是相似的。更改服务器上的缓存信息会遭到清除,而同步服务器上的缓存信息则不会,因为该状态是共享的。通常情况下,更改服务器会执行所有工作,而同步服务器执行的工作却比较少。
public void cleanupEntity(ContextType contextType) throws Exception {
super.cleanupEntity(contextType);
getInstanceShape().cleanup(contextType);
// reset cache
if (!contextType.isSecondaryOperation()) {
clearNonPersistentPropertiesFromCache();
clearLastPropertyValueCache();
}
if (isEnabled()) {
cleanupThing(contextType);
}
}
维护状态 
本地状态是指不在属性、配置表或数据表中的任何状态。要使本地状态在服务器之间可用,需将其更改为共享状态。共享状态是通过 Ignite 缓存层来实现的。对于扩展,我们建议应将所有状态均存储在属性或配置表中:
配置表
配置表存储在数据库中,并在服务器之间同步。因此,跨服务器的更新会略有延迟。由于配置表是模型同步的一部分,因此,在同步时,同步服务器上的实体会遭到破坏并重新创建,同时模型会发生更改。因此,与整个模型更新相比,使用属性可能更清晰、更高效。此外,持久化属性可用于在两次重新启动间隔之间存储状态值。
属性
所有属性值现已存储为共享状态。通过写入缓存,对这些值进行的更新会立即在服务器上进行。如果属性是持久化的,则系统仍会对其进行缓存以改善性能,并将其写入数据库以在两次重新启动间隔之间保留状态。您可以创建数据事物,如需在多个事物实例中共用数据事物,则可使用数据事物来保存状态属性。
本地属性
在某些情况下,不应使用属性的共享状态。例如,ConnectableThing 具有属性 isConnected,系统会针对每台服务器跟踪此属性的连接状况。isConnected 属性的 ConnectableThings 连接状况发生更改时,让每台服务器都改写此属性有点不合理。可通过将特性 isLocalProperty 添加到此属性中来实现此本地状态。此特性仅适用于非持久化属性;具有此特性的持久化属性将共享为常规属性。
@ThingworxPropertyDefinition(
name ="isConnected",
description ="Flag indicating if connected or not",
baseType ="BOOLEAN",
aspects = {"isPersistent:false","isReadOnly:false","defaultValue:false","isLocalProperty:true"})
检查硬参考 
分离操作会移除对其他实体的硬参考。对于 ThingWorx 高可用性群集中模型同步中的修补进程,系统需要交换已更改的实体;因此,不能有实体封装对其他实体的硬参考。例如,如果已在事物级别缓存了事物模板,并且该模板已更改,则必须在所有服务器上对其进行修补。只要事物具有对此模板的硬参考,那么这些事物就会断开。因此,必须将所有实体从硬参考更改为软参考。因此,在需要参考时,平台会遍历树来获取这些参考。
例如,以下是 ThingTemplate 类,此类具有对基本事物模板的参考。
具有硬参考
// Parent thing template
privateThingTemplate _baseThingTemplate =null
...
@ThingworxExtensionApiMethod(since = {6,6})
publicThingTemplate getBaseThingTemplate() {
if(_baseThingTemplate ==null&& StringUtilities.isNonEmpty(getBaseThingTemplateName())) {
_baseThingTemplate = ThingTemplateManager.getInstance().getEntityDirect(getBaseThingTemplateName());
}
return_baseThingTemplate;
}
由于我们要将硬参考存储在 _baseThingTemplate 中,因此这将导致同步进程修补出现问题。在下面的示例中,硬参考与软参考保持分离,同时仅存储名称并在需要时检索模板。
//Note the hard reference is removed (local stored template _baseThingTemplate)
@ThingworxExtensionApiMethod(since = {6,6})
publicThingTemplate getBaseThingTemplate() {
ThingTemplate baseThingTemplate =null
if(StringUtilities.isNonEmpty(getBaseThingTemplateName())) {
baseThingTemplate = ThingTemplateManager.getInstance().getEntityDirect(getBaseThingTemplateName());
}
returnbaseThingTemplate;
}
这对您有帮助吗?