安裝與升級 > 升級 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 參數決定某些邏輯是否應該發生。若 ContextTypeNONE,表示它不是次要操作,所有邏輯都應執行。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 內容。對於每個伺服器而言,在其 ConnectableThings 連線狀況變更時,覆寫 isConnected 毫無意義。您可以透過將層面 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;
}
這是否有幫助?