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>
5.7 KiB
task: Write and load a Java PROCESS Service class version: R1.05 (first written for R1.03) source: IM 36K10P11-01EN 4th ed. (Feb. 2026) §1–§5, §10; IM 36K10L10-01EN §1; practiced with CI-Eng-Sample class CIENG_JFLOW 2026-09-30 status: verified on R1.03 (2026-09-30); re-tested on R1.05 2026-10-08 (CIENG_JFLOW compiled on load, sPerMin 2 for inflow 120, removed). Public API of fasttools.processfast compared with javap on 2026-10-09: identical to R1.03. systemMessage() output and the reset after a change were not re-tested on R1.05
Java class
Worked example: class CIENG_JFLOW, object CI-Eng-Sample.TANK1.JFLOW
(examples/CI-Eng-Sample/06_class_df.qli, 07_object_df.qli). Language reference:
knowledge/manuals/IM36K10P11-01EN.md. Loading and removing: load-class-object.md.
Choose Java when you need loops, arrays of signals, inheritance, libraries, or signals that may stay unattached; otherwise the Traditional language is simpler.
1. Class record
Same as a Traditional class but PF_LANGUAGE = "Java" (cannot be changed later) and Java
source in METHOD. The Java class name must equal the CLASS_DF name exactly.
@FIELDS
NAME,DESCRIPTION,PF_LANGUAGE,TRIGGER_1,COMPILE,LISTING_WANTED,METHOD
@CLASS_DF
"CIENG_JFLOW","Inflow per minute (Java)","Java","",1,0,@"
import fasttools.processfast.*;
public class CIENG_JFLOW extends ProcessClass {
Signal sInflow = defineDoubleSignal(Signal.Trigger.VALUE);
Signal sPerMin = defineDoubleSignal();
public void create() {
attachItemToSignal(sInflow, getSectionsPath() + ".INFLOW");
createItemForSignal(sPerMin, "CI-Eng-Sample.TEMPLATES.TPL_REAL",
"DESCRIPTION", "Tank inflow (m3/min), class CIENG_JFLOW");
}
public void signalEvent(Signal signal) {
double mInflow = sInflow.getValueAsDouble();
sPerMin.setValue(mInflow / 60.0);
systemMessage("CIENG_JFLOW " + getTag() + ": inflow " + mInflow);
}
}
"@
OPCMAN starts the Java compiler OPCJCOM on demand; allow ~15 s, then export the class and
check VALID_METHOD = 1 (as in load-class-object.md).
2. Object
@FIELDS
NAME,DESCRIPTION,CLASS
@OBJECT_DF
"CI-Eng-Sample.TANK1.JFLOW","Tank 1 inflow per minute (Java)","CIENG_JFLOW"
Prompts: Attribute aX = defineStringAttributeForPrompt("…"); → answer in ATTR_VALUE_n;
refuse bad answers with cancel("text") in create().
3. Results on the test system
- Signals:
sInflow→CI-Eng-Sample.TANK1.INFLOW;sPerMin→ created itemCI-Eng-Sample.TANK1.JFLOW.sPerMin— automatic names keep the identifier's case, anditmvalneeds that exact case (…SPERMINis not found). Give a"NAME"if you want upper-case item names. INFLOW120 →sPerMin2; 90 → 1.5.systemMessage()appears inumhlog.logfromOPCJEXEasUMH-I-INFO, (<object>: <text>).- The first object ran without resetting the new class, although the manual asks for a reset
(ISS-029). After changing a Java class that has objects, compile and reset it
(
change-reset-class.md). - Deleting the object deleted
…JFLOW.sPerMinand section…TANK1.JFLOW;INFLOWstayed.
4. Java on R1.05 (checked 2026-10-09)
- Runtime: the JDK in
%TLS_ROOT_PATH%\tls\jreis Eclipse Temurin 11.0.28 (R1.03: 11.0.18). Same Java 11 language level; write classes for Java 11. - API: the public classes and methods of
fasttools.processfast(intls\exe\jopcsrv.jar) are the same as on R1.03 (javap -public; the jar itself was rebuilt). createSection(path, description, blocked, opcVisible)takes four arguments on both versions. The manual's examples pass a fifth (an empty process-area string) and would not compile as printed; R1.05 §10.2 now describes it correctly (ISS-154; not compile-tested).- The API has methods that P11 does not describe (ISS-159):
getHistory(...)(item history asValueSample[], several overloads),defineIntegerAttributeForPrompt/defineDoubleAttributeForPrompt(P11 only names the String version),sendAndReceiveMessage(...)(BUS request/reply) andgetDssSession()(release notes). Their behaviour is not documented here; test before relying on them. - Extra jars: the Java PROCESS processes (
OPCJCOM,OPCJACT,OPCJEXE) puttls\exe\*and, on R1.05, alsotls\exe\lib\*(bundled third-party jars) on the class path. Your own library jar still goes intls\exe(P11 §9). - OPC UA methods (R1.04+): method objects are Java (or Traditional) objects with the
attribute
MTD_KEYand signalsMTD_TRG,MTD_RET,MTD_IN_ARG_n,MTD_OUT_ARG_n. The installed sample classes are the starting point:UAC_MTD_JBASE(CI Server as OPC UA client; prompts for the method key<station>:<method>and for the input and output argument lists written as/type/description, type f, i, s or b, at most 10 each) andUAS_MTD_JBASE(method offered by the CI Server OPC UA server; your logic runs whenMTD_TRGbecomes 1 and must set the outputs, thenMTD_RETif needed, thenMTD_TRG0 = good or 2 = bad). Use one class with its own name per method object. Procedure: skilldata-access,opcua-client.md§7, and the L45 summary (§10.6, §11.4). Not practiced.
5. Pitfalls (manual)
- Definitions (
define…()) only at class level, withoutpublic/private. create()/destroy()run in a different process than the trigger methods: only attributes keep values between them; no timers or signal values increate().- Never sleep or loop long in a trigger method: it blocks all objects of the same priority.
- No anonymous listener classes (fail at object start with
NoClassDefFoundError). - Dataset access: get the session with
getDssSession()and never close it (release notes).