This document contains release notes for Prosys OPC UA SDK for Java Version 5. The versioning scheme is x.y.z-b
, with the following meanings:
-
x
: Incremented when we start adding support for a newer version of the OPC UA Specification (in which casey
andz
will reset back to 0). SDK versions 5.y.z are tied to OPC UA 1.05, SDK 6.y.z will be for 1.06, etc. assuming OPC UA versioning keeps as-is. Also, it is possible that in the future we decide to break this link). Largest changes are preferably done here. -
y
: Incremented on a bit larger updates (z
is reset back to 0), that do not add support for a newer version of the OPC UA Specification. -
z
: Incremented on not so large updates. Even number ofz
indicate releases, while odd ones are betas. In general only releases have release notes and are public. We may give beta versions as part of support cases. -
b
: Incremented internally when we make builds. Sometimes we reset this number.
The Code Generator tool that comes with the SDK uses similarly named version number. It is tied to the SDK version, except the build number is different. Also, if there are no changes, then SDK ships with the one from previous releases.
Migration Guides
See following documents (you can also find these from the SDK zip) for migrating from older versions to 5.x:
Version 5.1.0
Build: 5.1.0-116
Release date: 23.01.2024
This is a new minor release of the SDK that includes the following main improvements:
-
Support for OPC UA version 1.05.03 and Java 21 (classpath mode).
-
Security improvements: SecureRandom initialization, Bouncy Castle 1.77 and connection handling details
-
New classes and API changes related to Browse Paths.
-
New classes:
UaNodeSet
&UaBinaryFile
. -
One memory leak fix and plenty of other new features and bug fixes.
This release contains important security improvements, so we recommend everyone to update to this version. See the details below.
Changes to Common parts
-
Updated: Using Core OPC UA Information Model version 1.05.03.
-
Updated: Using GDS OPC UA Information Model version 1.05.02.
-
Updated: BouncyCastle dependency is updated to version 1.77.
-
Verified: This version of the SDK is tested to work with Java 21 (in classpath mode).
-
API CHANGE:
com.prosysopc.ua.UaBrowsePath
renamed tocom.prosysopc.ua.UaBrowseNamePath
-
API CHANGE:
com.prosysopc.ua.UaRelativePath
renamed tocom.prosysopc.ua.UaRelativeNamePath
-
API CHANGE:
com.prosysopc.ua.server.BrowsePath
renamed tocom.prosysopc.ua.RelativeNamePath
-
API CHANGE: There are now new classes
com.prosysopc.ua.UaBrowsePath
andcom.prosysopc.ua.UaRelativePath
with additional semantic, they now are equivalent tocom.prosysopc.ua.stack.core.BrowsePath
andcom.prosysopc.ua.stack.core.RelativePath
-
SECURITY IMPROVEMENT:
CryptoUtil.getRandom()
defaults toSecureRandom.getInstance("Windows-PRNG")
on Windows andSecureRandom.getInstance("NativePRNGNonBlocking")
in other operating systems. The previous default ("SHA1PRNG") is still used as the fallback. This is used as the internal random provider in the SDK and requires no change to your application. -
New:
UaNodeSet
, an intermediate format that enables parsing a NodeSet2 XML file before loading it to the server withNodeManagerTable.loadModel
, for example. -
New:
UaBinaryFile
, can be used to read UABinaryFileDataType encoded in a file. -
New:
Attributes.getAttributeId(String)
-
New:
UnsignedByte
,UnsignedShort
,UnsignedInteger
andUnsignedLong
: added methodsincOrWrap
,incOrWrapTo
,decOrWrap
anddecOrWrapTo
-
New:
UaNode.getAttributesMap()
-
New:
UaNode.addOrganizes(UaNode)
-
New overload:
UaNode.addReference(ExpandedNodeId nodeId, NodeId referenceTypeId)
-
New overload:
UaNode.addReference(NodeId nodeId, NodeId referenceTypeId)
-
New overload:
UaNode.addReference(UaNode targetNode, NodeId referenceTypeId)
-
New:
QualifiedName
,UaNodeId
,UaExpandedNodeId
,UaQualifiedName
,UaNamespace
andUaApplicationURI
now implementComparable
. -
New:
UaNode.getBrowsePaths()
andUaNode.getUaBrowsePaths()
-
New:
UaArrayDimensions.parse(String)
-
Changed:
UaArrayDimensions.toString()
format changed to "[x, y, z]", respective to whatparse
expects. -
Changed:
JsonEncoder
to use reversible decoding only when instructed (PubSub uses theJsonDataSetMessageContentMask.Options.ReversibleFieldEncoding
flag that was added in 1.05). -
Fixed:
UaAddress.parse
can now handle FQN addresses ending in a dot (the dot is removed). -
Fixed:
DataValue.clone()
didn’t deep-clone the value. -
Fixed:
com.prosysopc.ua.stack.core.OptionSet.Fields
now implementsFieldSpecification
directly,com.prosysopc.ua.stack.core.OptionSet.Fields.getSpecification()
is now deprecated (and was changed to return 'this'). -
Fixed:
XmlDecoder.getMatrix
worked incorrectly in some cases. -
Fixed:
JsonDecoder
,Variant
decoding to treat the value as raw string if "Type" field is missing (in addition to previous functionality that checked whether "Body" exists).
Changes to Client SDK
-
Improvement: Refresh the NamespaceTable before re-creating failed MonitoredItems for Subscriptions.
-
Fixed: Possible NPE if the server didn’t send (although required) any Certificate, when UserName or Certificate based user authentication was defined.
-
Fixed: Client-side decoding failures of Server-sent messages caused a timeout (instead of failing with
Bad_DecodingError
).
Changes to Server SDK
-
SECURITY IMPROVEMENT: Add more randomness when decryption or signature verification fails to reduce the risk of timing-based attacks.
-
SECURITY IMPROVEMENT: Corrected maximum connection management.
-
Memory leak fix: Non-activated Sessions that were closed due to reaching MaxSessionCount were not cleaned up properly.
-
New:
SessionManager.closeSession
, can be used to close aSession
from the server side. Useful, if you need to distrust an application and close the earlier connections immediately. -
New:
SubscriptionManager.getSubscriptions()
. -
New: ServerCapabilities nodes (/Root/Objects/Server/ServerCapabilities/*): MinSupportedSampleRate, MaxSessions, MaxSubscriptionsPerSession, MaxMonitoredItemsPerSubscription, MaxSubscriptions and MaxMonitoredItems. The MaxSubscriptions/MaxMonitoredItems are calculated based on the SDK limits for Sessions and Subscriptions.
-
New:
com.prosysopc.ua.server.Subscription.beginNotify()
, can be used as a transaction for advanced use cases to prevent automatic notifications of data changes untilendNotify()
is called. -
New: Support
com.prosysopc.ua.stack.core.GenericAttributes
for AddNodes service. -
New:
InstanceDeclarationHierarchy.findFirstMatch(RelativeNamePath, boolean, Predicate<UaNode>)
, for advanced use cases of searchingUaNode
that matches the givenPredicate
. -
New:
NodeManagerTable.loadModel(UaNodeSet…)
-
New:
UaServer.addReverseConnection(String)
-
New:
UaServer.addReverseConnection(ReverseConnectionParameters)
-
Improvement:
UaServer.addReverseConnection(String)
andReverseConnectionParameters.from(String)
now accept "inv+opc.tcp" and "rcp+opc.tcp" URL prefixes, in addition to "opc.tcp", to be used for the Reverse Connection address. -
Changed: SubscriptionIds for
Subscription
now start by default from a value based on the current time, to avoid reusing old SubscriptionIds at startup. This can be changed viaSubscriptionManager.setNextSubscriptionId(UnsignedInteger)
. -
Changed: Protected
IoManager
methodsbeginRead
andendRead
call sequence (same applies forbeginWrite
andendWrite
). Previously they were called in pairs for each Namespace, now beginRead is called first for each Namespace before starting processing, thus enabling better handling in asynchronous implementations. -
Changed: Use
StatusCodes.Bad_SecurityPolicyRejected
overBad_SecurityModeRejected
in CreateSession if theSecurityMode
is not supported. Required by the CTT. -
Fixed: SecureChannel Token lifetime was not revised. New defaults are: minimum 10 minutes, maximum 1 hour. These can be configured via
StackUtils.setSecurityTokenLifetimeMin(UnsignedInteger)
andStackUtils.setSecurityTokenLifetimeMax(UnsignedInteger)
. -
Fixed: Added a (fixed) retry delay for Reverse Connections.
-
Fixed: Clear BrowseContinuationPoints and HistoryContinuationPoints immediately, when a
Session
is closed. -
Fixed: Do not return InverseName Attribute for Symmetric ReferenceTypes. Required by the CTT.
-
Fixed: Do not fail loading NodeSets that contain 'RolePermission' and 'RolePermissions' XML elements (they are ignored, since Roles are not yet supported).
-
Fixed: Incorrect HasTypeDefinition References were created, if an UaNodeBuilderConfiguration instantiated something for PlaceHolder nodes whose TypeDefinition is the same as the one to be instantiated.
-
Fixed: Use
StatusCodes.Bad_MethodInvalid
(instead ofBad_NodeIdUnknown
) when Calling a Method that doesn’t exist. -
Fixed:
SessionManager.getSessions()
didn’t returnSessions
that were not yet activated.
Changes to PubSub SDK
-
New:
PubSubConnectionCommands.PUB_SUB_RESTART_CONNECTION
, allows restarting an enabled connection (mainly useful for UDP-UADP). -
Fixed: Do not send UADP Discovery requests, if receiving messages without a PublisherId.
Changes to Code Generator
-
New: Automatically exclude certain BrowseNames (such as "Description") that would cause generated code to conflict with the SDK core API.
Changes to SampleConsoleClient
No Changes.
Changes to SampleConsoleServer
-
New: Added an option to toggle ServerState between Running and Failed for testing purposes.
-
Changed: Don’t enable engineering units and other semantic properties to be written from client applications, as it is not recommended in general.
Other
-
Javadocs are back in Java 8 format due to issues with some Integrated Development Environments (IDEs).
Plus a number of other small changes.
Version 5.0.2
Build: 5.0.2-105
Release date: 18.10.2023
This is a bug fix release of the SDK. It additionally contains some new features.
The Client side UaClient.historyReadXXX
methods each now have an overload that takes multiple NodeId
.
The Server side localization (LocalizedText
) now handles a "best match" search (based on OPC UA Specification rules) when none of the locales given by the Client is a direct match.
Changes to Common parts
-
New:
LocalizedText.asSingleLocale
, supports "best match" search (mostly used internally in the server side). -
Fixed:
JsonEncoder
now escapes control characters for Strings. -
Fixed:
XmlElement.hashCode
no longer throws NPE. -
Changed:
XmlElement
now stores data internally always as a String. -
Changed:
XmlElement
now allows invalid XML. CallingXmlElement.getNode
for invalid XML throws.
Changes to Client SDK
-
New: Added
NodeId[]
overloads of multipleUaClient.historyReadXXX
methods. -
Fixed:
UaClient.connect
process hang if connecting to a server that had a custom SimpleType whose supertype was a custom SimpleType. -
Fixed: Calling
UaClient.connect
directly after aUaClient.disconnect
caused a race condition, which could result in multiple errors.
Changes to Server SDK
-
Fixed: Reverse Connections didn’t work in 5.0.0.
-
Fixed: Having sampling interval larger than publish interval for a MonitoredItem caused an NPE if DataValue timestamp was before Java Epoch.
-
Fixed: Removed UaNode is no longer cached in the "last operation UaNode" cache.
-
Changed: Allow
Session.INTERNAL_SESSION
to read/Root/Objects/Server/ServerDiagnostics/SessionsDiagnosticsSummary/SessionSecurityDiagnosticsArray
node.
Changes to Code Generator
-
Fixed: Having an UInteger-OptionSet Method argument from a different namespace than the one being generated caused an NPE.
It is recommended to re-generate code using this version of Codegen.
Changes to SampleConsoleClient
No Changes
Changes to SampleConsoleServer
No Changes
Other
Plus a number of other small changes.
Version 5.0.0
Build: 5.0.0-95
Release date: 20.09.2023
This is a new major release of the Prosys OPC UA SDK for Java.
The SDK version 5 is based on the OPC UA specification version 1.05. The 5.0.0 release adds support for the 1.05 information model. Other 1.05-specific functionality will be added later, if needed.
This release for the first time in SDK history changes the minimum required Java version needed to run the SDK from Java 6 to Java 8. Thus now every edition requires Java 8 (in 4.x the PubSub-capable editions already required 8). |
LocalizedText
now handles all localized versions of a String within the same java object. LocalizedTextMap
is removed and most of the API is found now directly in LocalizedText
. Note that this mainly affects the Server side as Clients receive a single localized value based on the locale of the Session.
There is now a "super-concept" for all XXXSpecifications: UaDataTypeSpecification
. Every OPC UA DataType shall now have an UaDataTypeSpecification
within the EncoderContext
. Simple types are represented by the added SimpleTypeSpecification
. OptionSets (both numeric and Structure-based) are represented via added OptionSetSpecification
.
This release adds XmlEncoder
, the long missing counter-part of XmlDecoder
. In addition, this internal encoding system now "keys" on UaNodeId
as the DataTypeId and uses UaDataTypeSpecification
instead of keying and being Java Class-based. The old "Serializer" system and related classes (and Codegen outputs) are removed. This change allows better handling of custom Structures, e.g. now it is possible to load a custom Structure <Value>
from NodeSet2 XML that also has a field that is a custom Structure.
Codegen now generates a CommonInformationModel
, which holds the generated UaDataTypeSpecifications
. This model is automatically registered when ClientInformationModel
or ServerInformationModel
is registered. It is possible to load the CommonInformationModel
manually via EncoderContext.registerModel(CommonCodegenModel model)
if operating outside of UaClient/UaServer. The constructors of EncoderContext
automatically register the core OPC UA information model that is generated by us and used also internally in the SDK.
In addition this release removes some of the internal use of reflection, but it is is not completely removed. As a related change (and future-proofing effort) the constructor of code-generated UaNodes has been changed to take in UaNode.Parameters
.
The samples no longer create private keys with passwords. The functionality is NOT removed in the SDK, it is just not used anymore in the samples. In practice we feel this is better than using a hardcoded password in the sample code. A real application should support user-created certs and offer a way to enter and store the password. Note that due to this change if the new code of samples tries to load a private key made with the previous version samples it will fail.
Finally, the SampleConsoleServer
sample also no longer by default enables the opc.https endpoint. It can be enabled by setting -P httpsPortNumber
with a non-0 free port number, if needed. This is to reduce confusion, as opc.tcp is the endpoint every OPC UA Application supports (and must support) and should use. The SDK technically supports opc.https as well, but some of the security semantics regarding application level authentication work differently to opc.tcp and missing this fact can leave the server more open than desired. See the sample for a larger explanation.
Prosys OPC UA SDK Development Team
Migration Guide
Please see the Migration Guides section for more information on how to accommodate your applications to the new SDK. The tutorials have also been updated to reflect current functionality.
Changes to Common parts
-
New:
com.prosysopc.ua.UaIds
that holds the same constants ascom.prosysopc.ua.types.opcua.Ids
, but asUaNodeId
(vs.ExpandedNodeId
). -
New:
UaDataTypeSpecification
, super-interface for all XXXSpecification interfaces. -
New:
SimpleTypeSpecification
, models types that are either built-in or subtypes of those and not Enumerations, OptionSets or Structures. -
New: In general propely support
OptionSets
, including custom ones. -
New:
OptionSetSpecification
,OptionSpecification
andUaOptionSet
, offer generic handling of OptionSets similar toStructureSpecification
+Structure
-
New:
OptionSetStructureSpecification
, generic description ofOptionSet
-structure subtypes. -
New:
Structure.toFieldsMap
andtoFieldNamesMap
. -
New:
Ids
(andUaIds
) now contains additional identifiers fromIdentifiers
that were not directly related to Types, e.g. theServer
node constant now exist asUaIds.Server
andIds.Server
. -
New:
ByteString.toBitSet
returningjava.util.BitSet
andfromBitSet
static factory method. -
New:
UaAddressSpace.getObjectsFolder()
andgetRoot
helpers. -
New:
StatusCode
now implementscom.prosysopc.ua.BitField
. -
New:
UaNodeId.parse(String)
. -
New:
UaQualifiedName.parse(String)
. -
Changed:
ExpandedNodeId.toString
format now only escapes%
and;
characters for the namespace uri component -
Changed:
LocalizedText
now handles all localizations of the same value within the sameLocalizedText
instance.LocalizedTextMap
is removed and majority of it’s API is now found directly fromLocalizedText
. -
Changed:
LocalizedText
no longer has separate null vs. empty handling (as the binary encoding form for both should be the same "not present"). Null locales and values are instead now interpreted as empty strings. -
Changed:
StructureSpecification
is now an interface instead of a class. AllowsOptionSetStructureSpecification
multiple inherit it andOptionSetSpecification
. -
Changed:
UaType.getJavaClass()
moved toUaDataType.getJavaClass()
. Setter is removed. Getter returns based onEncoderContext
. -
Changed: Undo deprecation of
UaAddressSpace.findNode
. -
Changed: IEncoder and IDecoder are now
UaNodeId
based, methods takingClass
are removed. -
Changed:
AbstractOptionSetDataType.toSet()
(the base for Codegen numeric OptionSet types) now returns aSet
with deterministic iteration order. The order is order in which theOptions
are defined inOptionSetSpecification.getOptions()
. -
Changed:
UaNodeId.toString
now uses the same format asExpandedNodeId.toString
. -
Changed:
UaQualifiedName.toString()
now uses a format "nsu=NAMESPACE_URI;name=NAME_PART". -
Deprecated: All constructors of
DateTime
. Use static factory methods instead. -
Deprecated:
StructureSpecification.toStructureBuilder
, usetoInstanceBuilder
instead (this change allows it to be overridden inOptionSetStructureSpecification
). -
Deprecated:
ObjectUtils
, use methods fromjava.util.Objects
instead. -
Removed:
UnsignedByte.assertValueInRange
(is internal functionality). -
Removed:
Variant.compareTo
. Variant was notComparable
and the implementation did throw for non numeric data. -
Removed:
KeyPairsKeyManager
, not used internally and all methods just returned null. -
Removed:
SnapshotArray
(usejava.util.concurrent.CopyOnWriteArrayList
instead) -
Removed: Old Structure "Serializer system" and related classes that were used in 4.x and older major versions.
-
Removed:
com.prosysopc.ua.stack.builtintypes.DataTypes
(previously deprecated) -
Removed:
com.prosysopc.ua.stack.builtintypes.NodeReference
, not used andcom.prosysopc.ua.UaExpandedNodeId
gives equivalent functionality, if needed.
Changes to Client SDK
-
Fixed: Connections failed to servers that missed the MaxNodesPerRead OperationLimit node.
-
Changed: Removed
throws StatusException
fromUaClient.writeValues(NodeId[] nodeIds, Object[] value)
andwriteValues(NodeId[] nodeIds, Object[] values, NumericRange[] indexRanges)
signatures as the exception is not thrown by the code. -
Changed:
AddressSpace.findNode
is no longer deprecated, functionality was changed to callgetNode
instead of it’sNodeCache.findNode
. Returns null if any exception thrown. -
Deprecated
MonitoredEventItem
constructors that do not take anEventFilter
(use the ones that do).
Changes to Server SDK
-
New: Support larger SamplingInterval(s) than PublishInterval for data-MonitoredItems.
-
Fixed: Nested custom structures in custom structure fields
<Value>
are now supported when loading NodeSets. -
Fixed: Protected
beginXXX
andendXXX
forIoManager
andHistoryManager
contained the whole request data, now it is properly split per namespace and only the relevant operations are given as parameter. -
Changed: Use fully qualified version of the hostname when making the certificate (other samples already did this).
-
Changed: Using core OPC UA NodeSet version 1.05.02.
-
Removed: Previously deprecated
StructureInfo
+StructureInfoCache
. UseStructureSpecification
(s) fromEncoderContext
instead. -
Removed: Internal
BrowseContinuationPoint.getData
andsetData
.
Changes to PubSub SDK
-
Changed:
PubSubEvents
is nowPubSubSystemEvents
. -
Fixed:
PUB_SUB_JSON_DATASET_MESSAGE_RECEIVED
andPUB_SUB_UADP_DATASET_MESSAGE_RECEIVED
are now Reader-level events and contain Reader configuration. -
Fixed: In some cases
PubSubSystemEvents
were sent more than once.
Changes to Code Generator
-
New: Added option to split output packages per NodeClass. This is by default enabled, but not used for the core namespace that SDK embeds. Avoids rare conflicts where the same name exist within the same namespace for different NodeClass.
-
New: Generates a
CommonInformationModel
, which holds the generatedUaDataTypeSpecifications
. -
Removed: internal defaults for the DI, ADI + PLCOpen models. Now the namespace package mappings must always be specified. See the sample
di_adi_plcopen.xml
configuration in the SDK distribution zip.
Changes to SampleConsoleClient
-
Changed: Generated private keys no longer use passwords. Loading of existing private keys made with older version (having a password) will fail.
Changes to SampleConsoleServer
-
Changed: Generated private keys no longer use passwords. Loading of existing private keys made with older version (having a password) will fail.
-
Changed: The opc.https endpoint is no longer by default enabled.
Changes to PubSub samples
-
Changed: Generated private keys no longer use passwords. Loading of existing private keys made with older version (having a password) will fail.
Other
-
The distribution now contains Migration Guides from all earlier major versions i.e. 1→2, 2→3, 3→4 in addition to the new 4→5 guide.
-
Evaluation edition start-up text now only appears in logger, similar to start-up text of other editions. This is part of our internal quality improvement effort, which one part is to ensure via forbidden-apis that e.g. system out/err is not used by the SDK code (outside of samples).
-
Also as a result for quality improvements, we internally run forbidden-apis default checks for "unsafe API". In addition, Some reflection-related code no longer calls
setAccessible(true)
, this has the potential to impact old code regarding reflection. If you encounter an issue, let us know.