Repository navigation
v1.2.0-RC3
Pre-release
Pre-release
This is the third release candidate for Milo 1.2.0.
The 1.2.0 feature and migration guide describes the new features and the changes that may require code changes in your application. 1.2.0 includes source and binary compatibility breaks, so recompile applications and extensions against one consistent Milo version.
Changes since RC2
DiagnosticInfo support
- Servers and clients now work with DiagnosticInfo as resolved
Diagnosticvalues instead of string-table indexes. A server returns operation and ServiceFault diagnostics only when a request'sreturnDiagnosticsmask asks for them, andUaExceptioncarries aDiagnosticon both sides. - A client asks for diagnostics with
OpcUaClientConfigBuilder.setReturnDiagnostics(...). The default isReturnDiagnostics.NONE, so existing clients send the same requests as before. AbstractMethodInvocationHandler.invokeResultnow returns aMethodResult, which can carry aDiagnosticthat explains its status.- Code changes may be required:
InvalidArgumentExceptiontakes resolved diagnostics through a builder. Its(StatusCode[], DiagnosticInfo[])constructor andgetInputArgumentDiagnosticInfos()are removed.UaMethodException.getInputArgumentDiagnostics()returnsList<@Nullable Diagnostic>.DiagnosticsContextand the RC-only Call string-table API (InvocationContext.getCallDiagnostics()) are removed.
Server access checks and operation limits
- AddNodes, HistoryRead, and HistoryUpdate now ask the
AccessControllerbefore the AddressSpace, and TranslateBrowsePathsToNodeIds returns only Nodes the Session may browse. An applicationAccessControllermust implement the newcheckAddNodesAccess,checkHistoryReadAccess, andcheckHistoryUpdateAccessmethods. ReturningAccessResult.ALLOWEDfor every item keeps the previous behavior. - The monitored item services enforce
MaxMonitoredItemsPerCall, and HistoryRead and HistoryUpdate enforce the history operation limits they publish (250 by default) instead of the Read and Write limits. Requests over a limit fail withBad_TooManyOperations. The Milo client already splits its requests by the server's limits. - Each session queues at most
OpcUaServerConfigLimits.getMaxPublishRequestsPerSession()Publish requests (100 by default, and always at least one more than the session's Subscriptions). The server answers the oldest waiting request withBad_TooManyPublishRequestswhen the queue is full.
Other fixes
- The binary decoder checks array, ByteString, and String lengths against the bytes left in the message before it allocates storage (#2155).
- XML fragment parsing disables DTDs and external entities.
- MonitoredItem queues allocate storage as values arrive, and ModifyMonitoredItems no longer replaces a queue whose revised size is unchanged.
LifecycleManager.shutdown()finishes cleaning up the remaining children when one of them fails.- The client discards a subscription watchdog notification that was queued before its subscription was reset or recreated.
- The server stops session timeout work after the session closes, so normal closure no longer increments
SessionTimeoutCount. NodeIds0-NodeIds5andStatusCodes0are public again, so Scala code can import them directly (discussion #2165).- Guava is updated to 33.8.0 and Netty to 4.1.140.Final.
What's Changed
- Pin google-java-format in the formatting check by @kevinherron in #2151
- Remove the Call diagnostics string-table API before 1.2.0 by @kevinherron in #2145
- Add resolved Diagnostic types and carry them on UaException by @kevinherron in #2146
- Return operation and ServiceFault diagnostics from the server by @kevinherron in #2147
- Return Method results and argument diagnostics as resolved values by @kevinherron in #2148
- Request diagnostics from the client and resolve them in exceptions by @kevinherron in #2149
- Maven dependency updates 2026-11-02 by @kevinherron in #2154
- Restore public constant holders for Scala callers by @kevinherron in #2166
- Size decoded arrays by the data present in the message by @kevinherron in #2167
- Harden XML fragment parsing by @kevinherron in #2168
- Complete lifecycle shutdown after child failures by @kevinherron in #2169
- Discard stale subscription watchdog notifications by @kevinherron in #2170
- Stop timeout work after session closure by @kevinherron in #2171
- Maven dependency updates 2026-11-09 by @kevinherron in #2172
- Enforce MaxMonitoredItemsPerCall by @kevinherron in #2173
- Enforce the history operation limits by @kevinherron in #2175
- Limit queued PublishRequests per session by @kevinherron in #2174
- Allocate MonitoredItem queue storage as values arrive by @kevinherron in #2181
- Check access in HistoryRead by @kevinherron in #2178
- Keep the MonitoredItem queue when its revised size is unchanged by @kevinherron in #2183
- Check access in HistoryUpdate by @kevinherron in #2180
- Check browse access in TranslateBrowsePathsToNodeIds by @kevinherron in #2177
- Check access in AddNodes by @kevinherron in #2176
Full Changelog: v1.2.0-RC2...v1.2.0-RC3