Full manual diffs (L15, C20, E30, L25, J40, C10 §2, L10, P10, P11, J20, C30, P20, R40, E10) and read-only checks on the shared R1.05 test server. Skills and summaries moved to R1.05; new skill pytools (IM 36K10P40) from docs (no Python on the test server). Issues ISS-132..181; corrections to version-differences (E10, E30, P11, dss_ath_grp_u0104); C10 summary lists the 3 new authorization actions; r105-verification V10-V17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 KiB
manual: IM 36K10P11-01EN title: Class Description Language - Java edition: 4th Edition, Feb. 2026 (first summarized from the 3rd Edition, Sep. 2023) version: R1.05 (first written for R1.03) status: R1.05 re-check 2026-10-09: full word diff (only §10.2 reworded, see below); public API of fasttools.processfast compared with javap (identical to R1.03); JDK version read; CIENG_JFLOW compiled and ran on the R1.05 test server 2026-10-08. From docs; a Java class (attachItemToSignal, createItemForSignal with automatic name, Signal.Trigger.VALUE, signalEvent, systemMessage) compiled on quick load and run on the test system with CI-Eng-Sample class CIENG_JFLOW on 2026-09-30; everything else from docs
Java PROCESS Service language (R1.05)
R1.05 (4th Edition, Feb. 2026): the revision table lists only contact information. The
word diff shows that §10.2 (Methods) was rewritten in plainer English with one real
correction: createSection() is now described with description, block setting and OPC
visibility, without the process areas of the R1.03 text. The examples in §8 (valve,
boiler, §8.6 Create Names) still pass five arguments (ISS-154). No other change; section numbers unchanged.
Installed API (checked 2026-10-09, javap -public on tls\exe\jopcsrv.jar): the
classes and public methods of fasttools.processfast are identical on R1.03 and R1.05.
Facts the manual does not state:
createSection(String path, String description, boolean blocked, boolean opcVisible): four arguments on both versions, so the manual's five-argument calls do not match the API (not compile-tested).- Methods not described in P11 (ISS-159):
getHistory(item, from, to, …)returningValueSample[](five overloads),defineIntegerAttributeForPrompt()anddefineDoubleAttributeForPrompt()(the manual names only the String version),sendAndReceiveMessage(ServerAddress, Request, Reply, timeout)(BUS messages, packagefasttools.processfast.communication),getDssSession()(named in the release notes). Untested. - Java runtime: Eclipse Temurin JDK 11.0.28 on R1.05 (11.0.18 on R1.03) in
tls\jre; the Java compilerOPCJCOMand the executor run on it (Java 11). Class path of the Java processes:jopcsrv.jar,jtoolsclt.jar,jtoolslibclt.jar,tls\exe\*and, on R1.05,tls\exe\lib\*. - New preinstalled Java classes (R1.04+):
UAC_MTD_JBASEandUAS_MTD_JBASE, samples for OPC UA method objects (attributeMTD_KEY, signalsMTD_TRG,MTD_RET,MTD_IN_ARG_n,MTD_OUT_ARG_n). Described in IM 36K10L45 §10.6 and §11.4, not in P11: seeIM36K10L45-01EN.mdand skillclass-object-engineering, taskjava-class.md§4.
Summary in own words; section numbers refer to the manual. Engineering: IM36K10L10-01EN.md,
skill class-object-engineering. The full API reference is only in the Engineering Module
class editor (F1).
1. What Java adds (§1)
Arrays of signals/attributes, loops, inheritance (extends another PROCESS class), any Java
library (TCP/IP, files, web services), and signals that need not be attached. Java and
Traditional classes cannot contain each other. Compiled by OPCJCOM, created by OPCJACT, run
by OPCJEXE (see L10 summary).
2. Class layout (§1.1, §3)
import fasttools.processfast.*; // the framework; import other packages as usual
public class CIENG_JFLOW extends ProcessClass { // name = class name in CLASS_DF, exactly
// definitions: class level only, no public/protected modifiers
Signal sInflow = defineDoubleSignal(Signal.Trigger.VALUE);
Signal sPerMin = defineDoubleSignal();
Attribute aCapacity = defineDoubleAttribute(Attribute.Scope.OBJECT);
Timer tCheck = defineTimer();
public void create() { /* object created: attach or create items */ }
public void destroy() { /* object deleted (items are detached automatically) */ }
public void start() { /* object starts: after create and at every CI Server start */ }
public void stop() { /* CI Server stops (not guaranteed, e.g. HA switch) */ }
public void signalEvent(Signal signal) { }
public void timerEvent(Timer timer) { }
public void triggerGroupEvent(TriggerGroup triggerGroup) { }
}
Naming advice: s… signals, a… attributes, t… timers, c… containments, m… locals;
identifiers max 15 characters. Omit methods you do not need.
Two environments (§3.4, important): create()/destroy() run in the creation
environment (OPCJACT), everything else in the runtime environment (OPCJEXE). Signals have
items only at runtime; timers only at runtime; plain Java fields and objects set in create()
are gone at runtime — only attributes carry values across. Static fields are not shared
between objects of different priorities. Share data through class-scope attributes or items.
3. Signals (§4)
defineIntegerSignal(),defineDoubleSignal(),defineStringSignal()(string max 79 characters);…SignalArray(n)or…SignalArray(trigger, n); max 4095 signals per class.- Triggers:
Signal.Trigger.VALUE | STATUS | OPTION | UPDATE | FIRST | PIT | LIMIT | QUALITYas argument ofdefine…Signal(). Without it the signal never triggers. - In
create():attachItemToSignal(sig, "<item>")— the item must exist, else creation is cancelled and rolled back.createItemForSignal(sig, "<template>[;<station>:<template point>]", "FIELD", value, …)— anyITEM_DFfield;"STORAGE_GROUP", "<group>"followed byITEM_HIS_DFfields (order matters, max 4 groups); with a point, prefix shared names:"ITEM'DESCRIPTION","POINT'DESCRIPTION", and use the station's point dataset fields (STATION,IO_ADDRESS…). Sub-items: template must be a sub-item, main item must exist, name required.- Without
"NAME"the framework names the item<object>.<signal identifier>and creates the sections; the identifier's case is kept (verified:CI-Eng-Sample.TANK1.JFLOW.sPerMin; item names are case-sensitive foritmval). Framework-created items and sections are deleted with the object (verified) unless Leave items is set. createSection(path, description, blocked, opcVisible)creates sections you name yourself (R1.03 manual text and the §8 examples add a process-area argument that the installed API does not have, ISS-154); the framework cannot always undo these — prefer automatic names.- Name helpers:
getTag(),getSectionsPath(),getSections(),getFullIdentifierPath(x),getContainerIdentifierName(),getContainerIdentifierPath(),getNode().
- Unattached signals:
sig.isAttached(); most methods throw on an unattached signal. - Handling: override
signalEvent(Signal signal)and compare with==, or add a named inner class implementingSignalListenerinstart()(addSignalListener); anonymous listeners compile but fail at start (NoClassDefFoundErrorin the log). - The signal passed to the handler holds the attribute values of the moment of the trigger.
- Common methods:
getValueAsDouble/Integer/String(),getOldValueAs…(),setValue(x),setValueAndStatus(x, Signal.Status.MANUAL),setStatusNumber(Signal.Status.FAILED), limitsget/setHighLimit()… (throw when the item has no such limit — catch it),isOffline(),setOffline(),isBlocked(),getQuality(),getUpdateTime(),getValueAsDoubleAndReset()(sub-items),setValueAndTime(). - Control item:
hasControlSignal(),getControlSignal(); blocked control item = triggers ignored.
4. Attributes (§5)
defineIntegerAttribute(scope), defineDoubleAttribute(scope), defineStringAttribute(scope)
(string max 255), …AttributeArray(scope, n); scope Attribute.Scope.OBJECT or .CLASS.
Prompts: defineStringAttributeForPrompt("Question:") (always OBJECT scope; max 100 prompts);
read it in create() and call cancel("message") to refuse the object (rolls back). Attributes
survive restarts and are visible in the Engineering Module, but writing them is heavy (disk,
and for CLASS scope every runtime) — use them for settings, not process values.
5. Timers and trigger groups (§6, §7)
defineTimer()(no arrays; not usable increate()/destroy());t.start(10)orsetTime(10)+start();setRepeat(true);cancel(); resolution 1 s. Handle intimerEvent()or with a namedTimerListener.- Trigger groups are assigned in engineering (class or object), not in code; handled in
triggerGroupEvent(tg)(tg.getName(),tg.getInterval(),TriggerGroup.Interval.…). Use a trigger group for periodic work, a timer for "check again after a while". ONCE groups are unnecessary: usestart().
6. Containment and inheritance (§8, §9)
VALVE cGas = (VALVE)defineContainment("VALVE");— nevernew VALVE(). Prompts of a contained class become normal attributes: set them in the container'screate()(cGas.aStation.setValue(…)).create()/destroy()of contained classes are called automatically after the container's (call(cX).create()to force order);start()/stop()and the…Event()methods are not — call or forward them yourself, or use listeners in the contained class.- Inheritance:
public class BOILER_MIXER extends BOILER; callsuper.create(),super.signalEvent(signal)etc.; prompts of the super class are kept. A shared base class (e.g.BASE_CLASS extends ProcessClass) holds helper methods; each subclass loads its own copy (no shared statics). Plain Java code can go in a jar in%TLS_ROOT_PATH%\tls\exe; its classes must have a package name. R1.05 also putstls\exe\lib\*on the class path of the Java processes (bundled libraries).
7. Runtime behaviour (§10)
- Keep trigger methods short, never sleep: one object holds up all objects of the same priority (one thread per priority). Give slow objects their own priority, or extra executors per priority range.
- Exceptions in
create()cancel the creation; in a trigger method they abort that trigger and are logged. Usetry/catch. systemMessage("text")writes to the message log (umhlog.log, senderOPCJEXE, prefixed with the object name — verified);cancel("text")also stops the current trigger.getStatistics()→ processed/lost/queued events, execution times.- The manual says a changed class must be compiled and reset, and a new class reset before
its first object. On the test system a new class compiled by quick load ran its first object
without a reset (ISS-029); after changing a class with objects, reset it (skill task
change-reset-class.md). - Release notes (IM 36K01A50): Java classes that use datasets must get the session with
getDssSession()and never close it.
8. Examples in the manual (Appendix 1)
Valve, boiler (containment), twin boiler, mixer boiler (inheritance), city temperature.