Private
Public Access
Update Wiki for 1.4.0
+7
-2
@@ -24,7 +24,7 @@ romexis-common/
|
||||
- Firebird-Clientbibliotheken und -Werkzeuge
|
||||
- gemeinsame Betriebssystempakete
|
||||
- native Chilkat-Bibliothek und JAR
|
||||
- `RomexisPropertyAgent.jar`
|
||||
- `RomexisPropertyAgent.jar` mit eingebetteten RxCr2- und OptionPane-Transformern
|
||||
- Sicherheitsaktualisierungen
|
||||
|
||||
Die aufwendigen Native-/Java-Artefakte werden dadurch einmal pro Architektur statt einmal pro Romexis-Version gebaut.
|
||||
@@ -39,11 +39,16 @@ Die aufwendigen Native-/Java-Artefakte werden dadurch einmal pro Architektur sta
|
||||
- Xvfb, Openbox und xcompmgr
|
||||
- x11vnc und noVNC/websockify
|
||||
- GTK-/Mesa-/OpenGL-Abhängigkeiten
|
||||
- Chilkat und `RomexisPropertyAgent.jar`
|
||||
- Chilkat und `RomexisPropertyAgent.jar` einschließlich Java-17-Swing-Lifecycle-Null-Guard
|
||||
- die aus `romexis-common/dxservice_dummy.c` gebaute DxService-Kompatibilitätsbibliothek
|
||||
|
||||
Admin und Client installieren bzw. kompilieren diese Abhängigkeiten daher nicht erneut für jede Romexis-Version.
|
||||
|
||||
Das Agent-JAR enthält ASM und `RomexisOptionPaneUIPatch.class`; in den finalen
|
||||
Containern ist kein separates ASM-Artefakt erforderlich. Der Patch transformiert
|
||||
nur die betroffene In-Memory-Listenerklasse und schreibt das proprietäre
|
||||
Romexis-JAR auf dem Datenträger nicht um.
|
||||
|
||||
---
|
||||
|
||||
## Architekturspezifische Tags
|
||||
|
||||
+7
-2
@@ -24,7 +24,7 @@ romexis-common/
|
||||
- Firebird client libraries and tools
|
||||
- common OS packages
|
||||
- Chilkat native library and JAR
|
||||
- `RomexisPropertyAgent.jar`
|
||||
- `RomexisPropertyAgent.jar` with embedded RxCr2 and OptionPane transformers
|
||||
- security updates
|
||||
|
||||
The expensive native/Java artifacts are therefore built once per architecture instead of once per Romexis version.
|
||||
@@ -39,11 +39,16 @@ The expensive native/Java artifacts are therefore built once per architecture in
|
||||
- Xvfb, Openbox and xcompmgr
|
||||
- x11vnc and noVNC/websockify
|
||||
- GTK/Mesa/OpenGL dependencies
|
||||
- Chilkat and `RomexisPropertyAgent.jar`
|
||||
- Chilkat and `RomexisPropertyAgent.jar`, including the Java 17 Swing lifecycle null guard
|
||||
- the DxService compatibility library built from `romexis-common/dxservice_dummy.c`
|
||||
|
||||
Admin and Client therefore do not repeatedly install or compile these dependencies for every Romexis version.
|
||||
|
||||
The agent JAR embeds ASM and `RomexisOptionPaneUIPatch.class`; no separate ASM
|
||||
artifact is required in the final containers. The patch transforms only the
|
||||
affected in-memory listener class and does not rewrite the proprietary Romexis
|
||||
JAR on disk.
|
||||
|
||||
---
|
||||
|
||||
## Architecture-Specific Tags
|
||||
|
||||
+3
-3
@@ -66,15 +66,15 @@ Er erzeugt:
|
||||
- Firebird-Clientbibliotheken und -Werkzeuge
|
||||
- Betriebssystemabhängigkeiten
|
||||
- Chilkat
|
||||
- Java Property Agent
|
||||
- Java Property Agent mit eingebetteten RxCr2- und RomexisOptionPaneUI-Runtime-Patches
|
||||
|
||||
### GUI-Runtime-Build
|
||||
|
||||
`romexis-gui-runtime` enthält den von Admin und Client gemeinsam verwendeten architekturspezifischen Grafik-Stack: Java 17/OpenJFX, X11/noVNC, Mesa/GTK, Chilkat, PropertyAgent und die DxService-Kompatibilitätsbibliothek.
|
||||
`romexis-gui-runtime` enthält den von Admin und Client gemeinsam verwendeten architekturspezifischen Grafik-Stack: Java 17/OpenJFX, X11/noVNC, Mesa/GTK, Chilkat, PropertyAgent mit Java-17-OptionPane-Null-Guard und die DxService-Kompatibilitätsbibliothek.
|
||||
|
||||
### Gemeinsame Runtime-Quellen
|
||||
|
||||
`romexis-common/` ist der zentrale Quellort für `RomexisPropertyAgent.java`, die Chilkat-Patch-Quelle und `dxservice_dummy.c`. Diese Quellen werden in die passenden Runtime-Images kompiliert, statt in Verzeichnissen finaler Images dupliziert zu werden.
|
||||
`romexis-common/` ist der zentrale Quellort für `RomexisPropertyAgent.java`, `RomexisOptionPaneUIPatch.java`, den RxCr2-Ersatz und `dxservice_dummy.c`. Der Agent-Build bettet ASM und beide gezielten Runtime-Patches in `RomexisPropertyAgent.jar` ein. Diese Quellen werden in die passenden Runtime-Images kompiliert, statt in Verzeichnissen finaler Images dupliziert zu werden.
|
||||
|
||||
### Server-Image-Build
|
||||
|
||||
|
||||
+3
-3
@@ -66,15 +66,15 @@ It produces:
|
||||
- Firebird client libraries and tools
|
||||
- OS dependencies
|
||||
- Chilkat
|
||||
- Java property agent
|
||||
- Java property agent with embedded RxCr2 and RomexisOptionPaneUI runtime patches
|
||||
|
||||
### GUI runtime build
|
||||
|
||||
`romexis-gui-runtime` contains the architecture-specific graphical stack shared by Admin and Client: Java 17/OpenJFX, X11/noVNC, Mesa/GTK, Chilkat, PropertyAgent and the DxService compatibility library.
|
||||
`romexis-gui-runtime` contains the architecture-specific graphical stack shared by Admin and Client: Java 17/OpenJFX, X11/noVNC, Mesa/GTK, Chilkat, PropertyAgent with the Java 17 OptionPane null guard, and the DxService compatibility library.
|
||||
|
||||
### Shared runtime sources
|
||||
|
||||
`romexis-common/` is the single source location for `RomexisPropertyAgent.java`, the Chilkat patch source and `dxservice_dummy.c`. These sources are compiled into the appropriate runtime images instead of being duplicated in final image directories.
|
||||
`romexis-common/` is the single source location for `RomexisPropertyAgent.java`, `RomexisOptionPaneUIPatch.java`, the RxCr2 replacement and `dxservice_dummy.c`. The agent build embeds ASM and both targeted runtime patches into `RomexisPropertyAgent.jar`. These sources are compiled into the appropriate runtime images instead of being duplicated in final image directories.
|
||||
|
||||
### Server image build
|
||||
|
||||
|
||||
+11
-2
@@ -148,7 +148,7 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=de
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
Wichtiges Verhalten:
|
||||
@@ -217,4 +217,13 @@ Syntax:
|
||||
PROPERTY_AGENT_SET_<RXPROPERTY_NAME>=<value>
|
||||
```
|
||||
|
||||
Dies ist vor allem für die Romexis-Server-Runtime relevant. Im Admin-Container ist der PropertyAgent standardmäßig deaktiviert.
|
||||
Der Server verwendet den Agenten für Runtime-Properties und den RxCr2-Ersatz.
|
||||
Admin aktiviert ihn standardmäßig für die Service-INI-Integration und den
|
||||
Java-17-`RomexisOptionPaneUI`-Null-Guard. Der Client lädt denselben Agenten aus
|
||||
der GUI-Runtime, deaktiviert RxCr2 und aktiviert standardmäßig den
|
||||
OptionPane-Patch.
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_RXCR2_PATCH=true
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=true
|
||||
```
|
||||
|
||||
+10
-2
@@ -148,7 +148,7 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=de
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
Important behavior:
|
||||
@@ -217,4 +217,12 @@ Syntax:
|
||||
PROPERTY_AGENT_SET_<RXPROPERTY_NAME>=<value>
|
||||
```
|
||||
|
||||
This is primarily relevant for the Romexis server runtime. In the Admin container the PropertyAgent is disabled by default.
|
||||
The server uses the agent for runtime properties and the RxCr2 replacement.
|
||||
Admin enables the agent by default for its service-INI integration and the Java
|
||||
17 `RomexisOptionPaneUI` null guard. The Client loads the same GUI-runtime agent,
|
||||
disables RxCr2 and enables the OptionPane patch by default.
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_RXCR2_PATCH=true
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=true
|
||||
```
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ romexis-firebird-payload/
|
||||
Builds a Firebird SQL payload from the official macOS installer.
|
||||
|
||||
romexis-common/
|
||||
Contains shared PropertyAgent, Chilkat patch and DxService compatibility sources.
|
||||
Enthält die gemeinsamen PropertyAgent-, RomexisOptionPaneUI-, RxCr2-Patch- und DxService-Kompatibilitätsquellen.
|
||||
|
||||
romexis-base/
|
||||
Builds the reusable Java 11 server runtime image.
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ romexis-firebird-payload/
|
||||
Builds a Firebird SQL payload from the official macOS installer.
|
||||
|
||||
romexis-common/
|
||||
Contains shared PropertyAgent, Chilkat patch and DxService compatibility sources.
|
||||
Contains the shared PropertyAgent, RomexisOptionPaneUI and RxCr2 patch sources, and DxService compatibility source.
|
||||
|
||||
romexis-base/
|
||||
Builds the reusable Java 11 server runtime image.
|
||||
|
||||
+117
-10
@@ -4,11 +4,11 @@
|
||||
|
||||
## Zweck
|
||||
|
||||
Der `RomexisPropertyAgent` ist ein kleiner Java-Instrumentation-Agent, den das Romexis-Docker-Projekt verwendet, um Romexis-`RxProperties` während des JVM-Starts zu konfigurieren.
|
||||
Der `RomexisPropertyAgent` ist ein Java-Instrumentation-Agent, den das Romexis-Docker-Projekt verwendet, um Romexis-`RxProperties` zu konfigurieren und eng begrenzte Runtime-Kompatibilitätspatches während des JVM-Starts anzuwenden.
|
||||
|
||||
Er ermöglicht es, ausgewählte Romexis-Runtime-Eigenschaften durch Umgebungsvariablen zu setzen, bevor die Romexis-Server-Anwendung vollständig startet.
|
||||
|
||||
Dies ist erforderlich, da bestimmtes Romexis-Verhalten sehr früh während des JVM-Starts festgelegt wird und später nicht zuverlässig durch Bearbeiten von Dateien im Container geändert werden kann.
|
||||
Dies ist erforderlich, da bestimmtes Romexis-Verhalten sehr früh während des JVM-Starts festgelegt wird und ausgewählte Kompatibilitätskorrekturen vor dem Definieren der betroffenen Klassen angewendet werden müssen.
|
||||
|
||||
---
|
||||
|
||||
@@ -67,7 +67,7 @@ Der Java-Agent-Ansatz vermeidet:
|
||||
- die Pflege benutzerdefinierter Binär-Patches
|
||||
- das erneute Bauen von Romexis selbst
|
||||
|
||||
Stattdessen kann die Docker-Runtime diese Einstellungen mit gewöhnlichen Umgebungsvariablen steuern.
|
||||
Stattdessen kann die Docker-Runtime diese Einstellungen und gezielte Transformationen beim Laden von Klassen mit gewöhnlichen Umgebungsvariablen steuern. Proprietäre Romexis-JAR-Dateien bleiben auf dem Datenträger unverändert.
|
||||
|
||||
Dies ist sicherer, einfacher zu pflegen und besser für automatisierte Deployments geeignet.
|
||||
|
||||
@@ -105,6 +105,81 @@ Danach sucht er das passende öffentliche Feld in `RxProperties`.
|
||||
|
||||
Existiert das Feld, liest der Agent den tatsächlichen Romexis-Property-Schlüssel und ruft die passende Methode `RxProperties.setProperty(...)` auf.
|
||||
|
||||
Der gleiche `premain`-Einstiegspunkt registriert außerdem Java-Instrumentation-
|
||||
Transformer, bevor Romexis die betroffenen Klassen lädt. Jeder Transformer
|
||||
gleicht genau einen Klassennamen ab und liefert die ursprünglichen Bytes
|
||||
unverändert zurück, wenn der Patch deaktiviert, nicht anwendbar oder nicht sicher
|
||||
ausführbar ist.
|
||||
|
||||
---
|
||||
|
||||
## Runtime-Kompatibilitätspatches
|
||||
|
||||
### RxCr2-Ersatz
|
||||
|
||||
Die Server-Runtime kann `romexis_lib_resource.RxCr2` durch die eingebettete
|
||||
Java-Standard-PBKDF2-Implementierung ersetzen. Dadurch entfällt die
|
||||
serverseitige Abhängigkeit vom ursprünglichen Chilkat-basierten Passwort-Hashing,
|
||||
ohne `RomexisServer.jar` zu verändern.
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_RXCR2_PATCH=true
|
||||
ROMEXIS_AGENT_RXCR2_SALT_MODE=base64
|
||||
ROMEXIS_AGENT_RXCR2_DEBUG=false
|
||||
```
|
||||
|
||||
Admin und Client deaktivieren diesen serverspezifischen Ersatz.
|
||||
|
||||
### RomexisOptionPaneUI-Null-Guard
|
||||
|
||||
Admin und Client laufen unter Java 17. Ein konkretes Swing-Lifecycle-Rennen
|
||||
wurde in folgender Methode beobachtet:
|
||||
|
||||
```text
|
||||
romexis_laf.RomexisOptionPaneUI$MyPCListener.propertyChange(...)
|
||||
```
|
||||
|
||||
Unter neueren Java-Versionen, insbesondere Java 17, kann sich das Timing der
|
||||
`PropertyChange`-Events im AWT-Event-Thread leicht unterscheiden. In diesem Fall
|
||||
feuert das Event einen Sekundenbruchteil zu früh, bevor die Planmeca-Klasse ihre
|
||||
UI-Komponente `m_MessageArea` initialisiert hat. Wenn Romexis anschließend die
|
||||
bevorzugte Dialoggröße berechnet, führt der ursprüngliche Listener Folgendes aus:
|
||||
|
||||
```java
|
||||
m_MessageArea.getPreferredSize()
|
||||
```
|
||||
|
||||
auf einer `null`-Referenz. Die resultierende `NullPointerException` tritt im
|
||||
AWT-Event-Thread auf und kann die gesamte Anwendung beenden, statt nur das
|
||||
Pop-up zu zeichnen.
|
||||
|
||||
`RomexisOptionPaneUIPatch` verwendet die eingebettete ASM-Bibliothek und
|
||||
transformiert ausschließlich die Methode
|
||||
`propertyChange(PropertyChangeEvent)` des Listeners. Unmittelbar vor jedem
|
||||
passenden `Container.getPreferredSize()`-Aufruf fügt er das Bytecode-Äquivalent
|
||||
zu Folgendem ein:
|
||||
|
||||
```java
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
Alle anderen ursprünglichen Klassenbytes und das proprietäre Romexis-JAR bleiben
|
||||
unverändert. Enthält eine künftige Romexis-Version das erwartete Bytecode-Muster
|
||||
nicht mehr, protokolliert der Transformer einen Fehler und liefert die
|
||||
unveränderten Klassenbytes zurück, statt den Anwendungsstart zu verhindern.
|
||||
|
||||
Der Patch ist standardmäßig aktiv und kann in beiden Formen gesteuert werden:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=true
|
||||
```
|
||||
|
||||
```text
|
||||
-Dromexis.agent.optionpane.patch=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Unterstützte Werttypen
|
||||
@@ -142,13 +217,15 @@ Der Java Property Agent ist vorgesehen für:
|
||||
- automatisiertes Konfigurationsmanagement
|
||||
- Runtime-Anpassungen
|
||||
- Korrekturen der Plattformkompatibilität
|
||||
- kontrollierte Overrides des Romexis-Serververhaltens
|
||||
- kontrollierte Overrides des Romexis-Runtime-Verhaltens
|
||||
|
||||
---
|
||||
|
||||
## Build-Integration
|
||||
|
||||
Der Quellcode des Agents wird beim Build des Romexis-Server-Images kompiliert.
|
||||
Die kanonischen Quellen liegen unter `romexis-common/`. Der Agent wird sowohl in
|
||||
die Java-11-Server-Runtime als auch in die von Admin und Client gemeinsam
|
||||
verwendete Java-17-GUI-Runtime eingebaut.
|
||||
|
||||
Das Dockerfile verwendet eine dedizierte Build-Stage:
|
||||
|
||||
@@ -156,12 +233,18 @@ Das Dockerfile verwendet eine dedizierte Build-Stage:
|
||||
agent-build
|
||||
```
|
||||
|
||||
Das Ergebnis wird in das finale Image kopiert als:
|
||||
Das erzeugte JAR liegt abhängig von der Runtime unter folgenden Pfaden:
|
||||
|
||||
```text
|
||||
/opt/romexis/server/RomexisPropertyAgent.jar
|
||||
/opt/romexis/admin/RomexisPropertyAgent.jar
|
||||
/opt/romexis-runtime/RomexisPropertyAgent.jar
|
||||
```
|
||||
|
||||
Das Agent-JAR enthält `RomexisOptionPaneUIPatch.class`, den eingebetteten
|
||||
RxCr2-Ersatz und ASM selbst. Zur Laufzeit ist deshalb keine zusätzliche
|
||||
Java-Abhängigkeit erforderlich.
|
||||
|
||||
Das JAR-Manifest enthält:
|
||||
|
||||
```text
|
||||
@@ -178,7 +261,9 @@ Dadurch kann die JVM es laden über:
|
||||
|
||||
## Runtime-Integration
|
||||
|
||||
Der Romexis-Entrypoint fügt den Java-Agent dem JVM-Startbefehl von Romexis Server hinzu.
|
||||
Server-Entrypoint, Admin-Launcher und Client-Launcher fügen den Java-Agenten ihrem
|
||||
jeweiligen JVM-Startbefehl hinzu. Compose aktiviert ihn für Admin, und der Client
|
||||
aktiviert ihn, wenn das JAR aus der gemeinsamen Runtime vorhanden ist.
|
||||
|
||||
Das Property-Override wird damit angewendet, bevor `RomexisServer.jar` seine normale Startsequenz fortsetzt.
|
||||
|
||||
@@ -188,6 +273,9 @@ Typische Runtime-Konfiguration:
|
||||
PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true
|
||||
```
|
||||
|
||||
Beim Client deaktiviert der Launcher den RxCr2-Ersatz explizit und aktiviert den
|
||||
OptionPane-Patch. Auch Admin verwendet den OptionPane-Patch standardmäßig.
|
||||
|
||||
---
|
||||
|
||||
## Beispielhafte Log-Ausgabe
|
||||
@@ -205,13 +293,21 @@ Unbekannte Eigenschaft:
|
||||
JavaAgent WARN: RxProperties field not found: SOME_UNKNOWN_FIELD
|
||||
```
|
||||
|
||||
Erfolgreiche Installation und Anwendung des Swing-Patches:
|
||||
|
||||
```text
|
||||
JavaAgent: RomexisOptionPaneUI MyPCListener null-guard transformer installed
|
||||
JavaAgent: RomexisOptionPaneUI MyPCListener patched successfully; inserted null guards=<count>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Hinweise
|
||||
|
||||
- Der Agent verändert keine Romexis-Binärdateien.
|
||||
- Der Agent patcht keine Klassendateien.
|
||||
- Der Agent ruft ausschließlich öffentliche `RxProperties`-Felder und Setter-Methoden auf.
|
||||
- Der Agent verändert keine proprietären Romexis-JAR-Dateien auf dem Datenträger.
|
||||
- Aktivierte Transformer können die In-Memory-Bytes ausdrücklich ausgewählter Klassen beim Laden verändern.
|
||||
- Property-Overrides rufen öffentliche `RxProperties`-Felder und Setter-Methoden auf.
|
||||
- Der OptionPane-Transformer ist auf eine Listener-Methode und ein fehlerhaftes Dereferenzierungsmuster begrenzt.
|
||||
- Unbekannte Felder werden mit einer Warnung ignoriert.
|
||||
- Dieser Mechanismus sollte nur für Eigenschaften verwendet werden, die verstanden und bewusst überschrieben werden.
|
||||
|
||||
@@ -222,3 +318,14 @@ JavaAgent WARN: RxProperties field not found: SOME_UNKNOWN_FIELD
|
||||
| Eigenschaft | Wert | Grund |
|
||||
|---|---|---|
|
||||
| `KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES` | `true` | Zwingt Romexis Server zu dem auf Server-Properties basierenden Verhalten, das für den Linux-Docker-Start erforderlich ist |
|
||||
|
||||
---
|
||||
|
||||
## Runtime-Patch-Steuerung
|
||||
|
||||
| Einstellung | Standard | Geltungsbereich |
|
||||
|---|---|---|
|
||||
| `ROMEXIS_AGENT_RXCR2_PATCH` | `true` | Serverseitiger RxCr2-Ersatz; von Admin und Client explizit deaktiviert |
|
||||
| `ROMEXIS_AGENT_RXCR2_SALT_MODE` | `base64` | Salt-Interpretation der RxCr2-PBKDF2-Implementierung |
|
||||
| `ROMEXIS_AGENT_RXCR2_DEBUG` | `false` | Zusätzliche nicht geheime RxCr2-Diagnoseausgaben |
|
||||
| `ROMEXIS_AGENT_OPTIONPANE_PATCH` | `true` | Java-17-Swing-Lifecycle-Null-Guard für Admin und Client |
|
||||
|
||||
+114
-10
@@ -4,11 +4,11 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
The `RomexisPropertyAgent` is a small Java Instrumentation Agent used by the Romexis Docker project to configure Romexis `RxProperties` during JVM startup.
|
||||
The `RomexisPropertyAgent` is a Java Instrumentation Agent used by the Romexis Docker project to configure Romexis `RxProperties` and apply narrowly scoped runtime compatibility patches during JVM startup.
|
||||
|
||||
It allows selected Romexis runtime properties to be set through environment variables before the Romexis Server application fully starts.
|
||||
|
||||
This is required because some Romexis behavior is decided very early during JVM startup and cannot reliably be changed later by editing files inside the container.
|
||||
This is required because some Romexis behavior is decided very early during JVM startup and because selected compatibility fixes must be applied before the affected classes are defined.
|
||||
|
||||
---
|
||||
|
||||
@@ -67,7 +67,7 @@ The Java agent approach avoids:
|
||||
- maintaining custom binary patches
|
||||
- rebuilding Romexis itself
|
||||
|
||||
Instead, the Docker runtime can control these settings using ordinary environment variables.
|
||||
Instead, the Docker runtime can control these settings and targeted class-load-time transformations using ordinary environment variables. Proprietary Romexis JAR files remain unchanged on disk.
|
||||
|
||||
This is safer, easier to maintain and better suited for automated deployments.
|
||||
|
||||
@@ -105,6 +105,78 @@ Then it looks up the matching public field in `RxProperties`.
|
||||
|
||||
If the field exists, the agent reads the actual Romexis property key and calls the matching `RxProperties.setProperty(...)` method.
|
||||
|
||||
The same `premain` entry point also registers Java instrumentation transformers
|
||||
before Romexis loads the affected classes. Each transformer matches one exact
|
||||
class name and returns the original bytes unchanged when the patch is disabled,
|
||||
not applicable or cannot be applied safely.
|
||||
|
||||
---
|
||||
|
||||
## Runtime Compatibility Patches
|
||||
|
||||
### RxCr2 Replacement
|
||||
|
||||
The server runtime can replace `romexis_lib_resource.RxCr2` with the embedded
|
||||
Java-standard PBKDF2 implementation. This removes the server-side dependency on
|
||||
the original Chilkat-based password hashing path without modifying
|
||||
`RomexisServer.jar`.
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_RXCR2_PATCH=true
|
||||
ROMEXIS_AGENT_RXCR2_SALT_MODE=base64
|
||||
ROMEXIS_AGENT_RXCR2_DEBUG=false
|
||||
```
|
||||
|
||||
Admin and Client disable this server-specific replacement.
|
||||
|
||||
### RomexisOptionPaneUI Null Guard
|
||||
|
||||
Admin and Client run on Java 17. A concrete Swing lifecycle race was observed in:
|
||||
|
||||
```text
|
||||
romexis_laf.RomexisOptionPaneUI$MyPCListener.propertyChange(...)
|
||||
```
|
||||
|
||||
On newer Java versions, especially Java 17, the timing of `PropertyChange`
|
||||
events on the AWT event thread can differ slightly. In this case the event can
|
||||
fire a fraction too early, before the Planmeca class has initialized its
|
||||
`m_MessageArea` UI component. When Romexis then calculates the preferred dialog
|
||||
size, the original listener executes:
|
||||
|
||||
```java
|
||||
m_MessageArea.getPreferredSize()
|
||||
```
|
||||
|
||||
against a `null` reference. The resulting `NullPointerException` occurs on the
|
||||
AWT event thread and can terminate the complete application instead of merely
|
||||
drawing the popup.
|
||||
|
||||
`RomexisOptionPaneUIPatch` uses the bundled ASM library to transform only the
|
||||
listener's `propertyChange(PropertyChangeEvent)` method. Immediately before each
|
||||
matching `Container.getPreferredSize()` invocation, it inserts the bytecode
|
||||
equivalent of:
|
||||
|
||||
```java
|
||||
if (container == null) {
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
All other original class bytes and the proprietary Romexis JAR are preserved.
|
||||
If a future Romexis version no longer contains the expected bytecode pattern,
|
||||
the transformer logs an error and returns the unmodified class bytes instead of
|
||||
making application startup fail.
|
||||
|
||||
The patch is enabled by default and can be controlled with either form:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=true
|
||||
```
|
||||
|
||||
```text
|
||||
-Dromexis.agent.optionpane.patch=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Supported Value Types
|
||||
@@ -142,13 +214,15 @@ The Java Property Agent is intended for:
|
||||
- automated configuration management
|
||||
- runtime customization
|
||||
- platform compatibility fixes
|
||||
- controlled Romexis server behavior overrides
|
||||
- controlled Romexis runtime behavior overrides
|
||||
|
||||
---
|
||||
|
||||
## Build Integration
|
||||
|
||||
The agent source is compiled during the Romexis Server image build.
|
||||
The canonical sources live in `romexis-common/`. The agent is built into both
|
||||
the Java 11 server runtime and the shared Java 17 GUI runtime used by Admin and
|
||||
Client.
|
||||
|
||||
The Dockerfile uses a dedicated build stage:
|
||||
|
||||
@@ -156,12 +230,18 @@ The Dockerfile uses a dedicated build stage:
|
||||
agent-build
|
||||
```
|
||||
|
||||
The result is copied into the final image as:
|
||||
The resulting JAR is available at these runtime-specific paths:
|
||||
|
||||
```text
|
||||
/opt/romexis/server/RomexisPropertyAgent.jar
|
||||
/opt/romexis/admin/RomexisPropertyAgent.jar
|
||||
/opt/romexis-runtime/RomexisPropertyAgent.jar
|
||||
```
|
||||
|
||||
The agent JAR contains `RomexisOptionPaneUIPatch.class`, the embedded RxCr2
|
||||
replacement and ASM itself, so no external Java dependency is required at
|
||||
runtime.
|
||||
|
||||
The JAR manifest contains:
|
||||
|
||||
```text
|
||||
@@ -178,7 +258,9 @@ This allows the JVM to load it through:
|
||||
|
||||
## Runtime Integration
|
||||
|
||||
The Romexis entrypoint adds the Java agent to the Romexis Server JVM startup command.
|
||||
The Server entrypoint, Admin launcher and Client launcher add the Java agent to
|
||||
their respective JVM startup commands. Compose enables it for Admin, and the
|
||||
Client enables it when the shared runtime JAR is present.
|
||||
|
||||
The property override is then applied before `RomexisServer.jar` continues its normal startup sequence.
|
||||
|
||||
@@ -188,6 +270,9 @@ Typical runtime configuration:
|
||||
PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true
|
||||
```
|
||||
|
||||
For the Client, the launcher explicitly disables the RxCr2 replacement and
|
||||
enables the OptionPane patch. Admin also uses the OptionPane patch by default.
|
||||
|
||||
---
|
||||
|
||||
## Example Log Output
|
||||
@@ -205,13 +290,21 @@ Unknown property:
|
||||
JavaAgent WARN: RxProperties field not found: SOME_UNKNOWN_FIELD
|
||||
```
|
||||
|
||||
Successful Swing patch installation and application:
|
||||
|
||||
```text
|
||||
JavaAgent: RomexisOptionPaneUI MyPCListener null-guard transformer installed
|
||||
JavaAgent: RomexisOptionPaneUI MyPCListener patched successfully; inserted null guards=<count>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The agent does not modify Romexis binaries.
|
||||
- The agent does not patch class files.
|
||||
- The agent only calls public `RxProperties` fields and setter methods.
|
||||
- The agent does not modify proprietary Romexis JAR files on disk.
|
||||
- Enabled transformers can modify the in-memory bytes of explicitly targeted classes while they are loaded.
|
||||
- Property overrides call public `RxProperties` fields and setter methods.
|
||||
- The OptionPane transformer is limited to one listener method and one failing dereference pattern.
|
||||
- Unknown fields are ignored with a warning.
|
||||
- This mechanism should only be used for properties that are understood and intentionally overridden.
|
||||
|
||||
@@ -223,4 +316,15 @@ JavaAgent WARN: RxProperties field not found: SOME_UNKNOWN_FIELD
|
||||
|---|---|---|
|
||||
| `KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES` | `true` | Forces Romexis Server to use the server-properties based behavior required for Linux Docker startup |
|
||||
|
||||
---
|
||||
|
||||
## Runtime Patch Controls
|
||||
|
||||
| Setting | Default | Scope |
|
||||
|---|---|---|
|
||||
| `ROMEXIS_AGENT_RXCR2_PATCH` | `true` | Server-side RxCr2 replacement; explicitly disabled by Admin and Client |
|
||||
| `ROMEXIS_AGENT_RXCR2_SALT_MODE` | `base64` | Salt interpretation for the RxCr2 PBKDF2 implementation |
|
||||
| `ROMEXIS_AGENT_RXCR2_DEBUG` | `false` | Additional non-secret RxCr2 diagnostics |
|
||||
| `ROMEXIS_AGENT_OPTIONPANE_PATCH` | `true` | Java 17 Swing lifecycle null guard for Admin and Client |
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
│ └── ci-publish-manifests.sh
|
||||
├── romexis-common/
|
||||
│ ├── RomexisPropertyAgent.java
|
||||
│ ├── RomexisOptionPaneUIPatch.java
|
||||
│ ├── dxservice_dummy.c
|
||||
│ └── patches-src/
|
||||
├── romexis-base/
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
│ └── ci-publish-manifests.sh
|
||||
├── romexis-common/
|
||||
│ ├── RomexisPropertyAgent.java
|
||||
│ ├── RomexisOptionPaneUIPatch.java
|
||||
│ ├── dxservice_dummy.c
|
||||
│ └── patches-src/
|
||||
├── romexis-base/
|
||||
|
||||
+6
-2
@@ -265,7 +265,7 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=de
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
`ADMIN_LANGUAGE` unterstützt:
|
||||
@@ -544,7 +544,11 @@ Beispiel:
|
||||
PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true
|
||||
```
|
||||
|
||||
Dies ist hauptsächlich für die Romexis-Server-Laufzeit relevant. Im Admin-Container ist der PropertyAgent standardmäßig deaktiviert.
|
||||
Der Server verwendet den Agenten hauptsächlich für Runtime-Properties. Admin
|
||||
aktiviert ihn standardmäßig, und Admin sowie Client verwenden seinen
|
||||
Java-17-`RomexisOptionPaneUI`-Null-Guard gegen die Swing-Lifecycle-
|
||||
`NullPointerException`, die durch ein frühes `PropertyChange`-Event vor der
|
||||
Initialisierung von `m_MessageArea` entsteht.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+5
-2
@@ -267,7 +267,7 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=en
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
`ADMIN_LANGUAGE` supports:
|
||||
@@ -546,7 +546,10 @@ Example:
|
||||
PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true
|
||||
```
|
||||
|
||||
This is primarily relevant for the Romexis server runtime. In the Admin container the PropertyAgent is disabled by default.
|
||||
The server uses the agent primarily for runtime properties. Admin enables the
|
||||
agent by default, and Admin and Client use its Java 17 `RomexisOptionPaneUI`
|
||||
null guard to prevent the Swing lifecycle `NullPointerException` caused by an
|
||||
early `PropertyChange` event before `m_MessageArea` is initialized.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+16
-4
@@ -123,20 +123,32 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=de
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PropertyAgent im Admin
|
||||
|
||||
Der Romexis PropertyAgent ist für den Admin-Container standardmäßig deaktiviert:
|
||||
Der Romexis PropertyAgent ist für den Admin-Container standardmäßig aktiviert:
|
||||
|
||||
```env
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
Grund: `RxProperties` ist während der Java-Agent-Phase `premain` beim Start von RomexisConfig nicht immer sichtbar. Der Server-Container verwendet den PropertyAgent weiterhin für die serverseitige Injektion von Laufzeiteigenschaften.
|
||||
Der Agent setzt den Linux-spezifischen Admin-Service-INI-Pfad und stellt den für
|
||||
den zuverlässigen Betrieb unter Java 17 erforderlichen `RomexisOptionPaneUI`-
|
||||
Null-Guard bereit. Der Guard verhindert eine Swing-Lifecycle-
|
||||
`NullPointerException`, wenn ein `PropertyChange`-Event den Planmeca-Listener
|
||||
erreicht, bevor `m_MessageArea` initialisiert wurde. Der serverspezifische
|
||||
RxCr2-Ersatz bleibt in Admin über `ROMEXIS_AGENT_RXCR2_PATCH=false` deaktiviert.
|
||||
|
||||
Der Patch ist im Agenten standardmäßig aktiv. Nur für einen kontrollierten
|
||||
Vergleich kann er folgendermaßen deaktiviert werden:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
+16
-4
@@ -123,20 +123,32 @@ ADMIN_JAVA_OPTS=-Xms256m -Xmx1024m
|
||||
ADMIN_LANGUAGE=de
|
||||
DEBUG_XTERM=false
|
||||
ADMIN_VNC_LIFECYCLE=true
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PropertyAgent in Admin
|
||||
|
||||
The Romexis PropertyAgent is disabled by default for the Admin container:
|
||||
The Romexis PropertyAgent is enabled by default for the Admin container:
|
||||
|
||||
```env
|
||||
ENABLE_PROPERTY_AGENT=false
|
||||
ENABLE_PROPERTY_AGENT=true
|
||||
```
|
||||
|
||||
Reason: `RxProperties` is not always visible during the Java agent `premain` phase when RomexisConfig is started. The server container still uses the PropertyAgent for server-side runtime property injection.
|
||||
The agent sets the Linux-specific Admin service INI path and supplies the
|
||||
`RomexisOptionPaneUI` null guard required for reliable operation on Java 17.
|
||||
The guard prevents a Swing lifecycle `NullPointerException` when a
|
||||
`PropertyChange` event reaches the Planmeca listener before `m_MessageArea` has
|
||||
been initialized. The server-specific RxCr2 replacement remains disabled in
|
||||
Admin through `ROMEXIS_AGENT_RXCR2_PATCH=false`.
|
||||
|
||||
The patch is enabled by default inside the agent. It can be disabled only for a
|
||||
controlled comparison with:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
+111
@@ -74,3 +74,114 @@ romexis-client:latest
|
||||
```
|
||||
|
||||
Zuerst werden die Architektur-Tags erstellt. Die öffentlichen Multi-Architektur-Tags werden erst veröffentlicht, wenn beide Architekturen erfolgreich abgeschlossen wurden.
|
||||
|
||||
---
|
||||
|
||||
## Laufzeitverhalten
|
||||
|
||||
Der Container startet Xvfb, Openbox, idesk, x11vnc und noVNC. Romexis selbst
|
||||
startet nicht automatisch. Öffne den noVNC-Desktop und doppelklicke auf das
|
||||
Symbol **Romexis Client**. Dadurch belegt eine ungenutzte Client-Sitzung keinen
|
||||
großen Java-Heap, und der Anwendungsstart bleibt für den Bediener sichtbar.
|
||||
|
||||
Der Launcher verhindert über eine Sperrdatei doppelte Romexis-Prozesse und
|
||||
schreibt das Client-Protokoll nach:
|
||||
|
||||
```text
|
||||
/tmp/romexis-client.log
|
||||
```
|
||||
|
||||
Das optionale Debug-Terminal wird über `CLIENT_DEBUG_XTERM` gesteuert.
|
||||
|
||||
---
|
||||
|
||||
## Browser- und Runtime-Konfiguration
|
||||
|
||||
Die Standardadresse im Browser lautet:
|
||||
|
||||
```text
|
||||
http://localhost:6081/vnc.html?autoconnect=true
|
||||
```
|
||||
|
||||
| Variable | Standard | Zweck |
|
||||
|---|---|---|
|
||||
| `CLIENT_NOVNC_PORT` | `6081` | Veröffentlichter noVNC-Hostport |
|
||||
| `CLIENT_VNC_PASSWORD` | `promax` | Passwort des internen VNC-Servers |
|
||||
| `CLIENT_RESOLUTION` | `1280x900x24` | Auflösung des virtuellen Desktops |
|
||||
| `CLIENT_JAVA_OPTS` | `-Xss500k -Xmx16G` | JVM-Optionen des Clients |
|
||||
| `CLIENT_LANGUAGE` | `de` | Romexis-Sprache |
|
||||
| `CLIENT_COUNTRY` | `DE` | Land der Java-Locale |
|
||||
| `CLIENT_DEBUG_XTERM` | `false` | Aktiviert ein zusätzliches Debug-Terminal |
|
||||
| `ROMEXIS_AGENT_OPTIONPANE_PATCH` | `true` | Aktiviert die Java-17-Swing-Lifecycle-Korrektur |
|
||||
|
||||
Compose veröffentlicht nur noVNC. x11vnc lauscht innerhalb des Containers auf
|
||||
Port `5900`, wird standardmäßig aber nicht als Hostport veröffentlicht.
|
||||
|
||||
---
|
||||
|
||||
## RMI-Auflösung und Identität
|
||||
|
||||
Der Client verwendet den öffentlichen `SERVER_RMI_HOSTNAME` als Server- und
|
||||
Zertifikatsidentität. Beim Containerstart wird dieser Hostname auf die interne
|
||||
Adresse des Compose-Dienstes `romexis` abgebildet. Der Client-Launcher verbindet
|
||||
sich auch bei übersetzten öffentlichen Hostports mit den festen Containerports
|
||||
`1099` und `2099`.
|
||||
|
||||
Bei einer Portübersetzung sollte ein DNS-Name statt einer IP-Adresse verwendet
|
||||
werden. Eine IP-Adresse kann nicht über `/etc/hosts` auf den internen Dienst
|
||||
umgebogen werden.
|
||||
|
||||
---
|
||||
|
||||
## RomexisOptionPaneUI-Patch
|
||||
|
||||
Beim Start des Clients wird der gemeinsame `RomexisPropertyAgent` geladen. Sein
|
||||
serverspezifischer RxCr2-Ersatz ist deaktiviert, der OptionPane-Patch dagegen
|
||||
standardmäßig aktiv.
|
||||
|
||||
Unter Java 17 kann ein AWT-Property-Change-Event einen Sekundenbruchteil zu früh
|
||||
ausgeführt werden, bevor die Planmeca-Klasse `m_MessageArea` initialisiert hat.
|
||||
Wenn der ursprüngliche Listener danach die Dialoggröße berechnet, ruft er
|
||||
`getPreferredSize()` auf dieser `null`-Referenz auf. Die resultierende
|
||||
`NullPointerException` tritt im AWT-Event-Thread auf und kann die gesamte
|
||||
Anwendung beenden, statt nur das Pop-up zu zeichnen.
|
||||
|
||||
`RomexisOptionPaneUIPatch` transformiert ausschließlich
|
||||
`romexis_laf.RomexisOptionPaneUI$MyPCListener.propertyChange()` und ergänzt
|
||||
unmittelbar vor dem fehlerhaften Aufruf einen Null-Guard. Das ursprüngliche
|
||||
Romexis-JAR bleibt auf dem Datenträger unverändert. Der Patch sollte nur für
|
||||
einen kontrollierten Vergleich deaktiviert werden:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persistente Daten und Healthcheck
|
||||
|
||||
Die Client-ProgramData liegen getrennt vom Server- und Admin-Zustand:
|
||||
|
||||
```text
|
||||
${ROMEXIS_DATA_ROOT}/docker/client/programdata
|
||||
-> /ProgramData/Planmeca/Romexis
|
||||
```
|
||||
|
||||
Der Healthcheck prüft X-Display, laufenden `Romexis.jar`-Prozess und noVNC-Port.
|
||||
Da Romexis bedarfsgesteuert startet, kann der Dienst bis zum Doppelklick auf das
|
||||
Desktop-Symbol im Zustand `starting` bleiben oder `unhealthy` werden.
|
||||
|
||||
---
|
||||
|
||||
## Betrieb und Fehleranalyse
|
||||
|
||||
```bash
|
||||
docker compose up -d romexis-client
|
||||
docker compose logs -f romexis-client
|
||||
docker compose exec romexis-client tail -f /tmp/romexis-client.log
|
||||
```
|
||||
|
||||
Wenn kein Desktop erscheint, prüfe die Meldungen von Xvfb, Openbox, x11vnc und
|
||||
websockify im Containerprotokoll. Beendet sich Romexis nach dem Aktivieren des
|
||||
Symbols, prüfe `/tmp/romexis-client.log` und stelle sicher, dass
|
||||
`SERVER_RMI_HOSTNAME` auf den internen Dienst `romexis` aufgelöst wird.
|
||||
|
||||
+109
@@ -74,3 +74,112 @@ romexis-client:latest
|
||||
```
|
||||
|
||||
The architecture tags are created first. The public multi-architecture tags are published only after both architectures completed successfully.
|
||||
|
||||
---
|
||||
|
||||
## Runtime Behavior
|
||||
|
||||
The container starts Xvfb, Openbox, idesk, x11vnc and noVNC. Romexis itself is
|
||||
not started automatically. Open the noVNC desktop and double-click the
|
||||
**Romexis Client** icon. This keeps an unused Client session from consuming a
|
||||
large Java heap and makes application startup visible to the operator.
|
||||
|
||||
The launcher uses a lock file to prevent duplicate Romexis processes and writes
|
||||
the Client log to:
|
||||
|
||||
```text
|
||||
/tmp/romexis-client.log
|
||||
```
|
||||
|
||||
The optional debug terminal is controlled by `CLIENT_DEBUG_XTERM`.
|
||||
|
||||
---
|
||||
|
||||
## Browser and Runtime Configuration
|
||||
|
||||
The default browser URL is:
|
||||
|
||||
```text
|
||||
http://localhost:6081/vnc.html?autoconnect=true
|
||||
```
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `CLIENT_NOVNC_PORT` | `6081` | Published noVNC host port |
|
||||
| `CLIENT_VNC_PASSWORD` | `promax` | Password for the internal VNC server |
|
||||
| `CLIENT_RESOLUTION` | `1280x900x24` | Virtual desktop resolution |
|
||||
| `CLIENT_JAVA_OPTS` | `-Xss500k -Xmx16G` | Client JVM options |
|
||||
| `CLIENT_LANGUAGE` | `de` | Romexis language |
|
||||
| `CLIENT_COUNTRY` | `DE` | Java locale country |
|
||||
| `CLIENT_DEBUG_XTERM` | `false` | Enables an additional debug terminal |
|
||||
| `ROMEXIS_AGENT_OPTIONPANE_PATCH` | `true` | Enables the Java 17 Swing lifecycle fix |
|
||||
|
||||
Compose publishes noVNC only. x11vnc listens on port `5900` inside the
|
||||
container but is not exposed as a host port by default.
|
||||
|
||||
---
|
||||
|
||||
## RMI Resolution and Identity
|
||||
|
||||
The Client uses the public `SERVER_RMI_HOSTNAME` as the server and certificate
|
||||
identity. During container startup, that hostname is mapped to the internal
|
||||
address of the Compose service `romexis`. The Client launcher connects to the
|
||||
fixed container ports `1099` and `2099`, even when the corresponding public host
|
||||
ports are translated.
|
||||
|
||||
Use a DNS hostname rather than an IP address when port translation is required.
|
||||
An IP address cannot be remapped to the internal service through `/etc/hosts`.
|
||||
|
||||
---
|
||||
|
||||
## RomexisOptionPaneUI Patch
|
||||
|
||||
The shared `RomexisPropertyAgent` is loaded when the Client starts. Its
|
||||
server-specific RxCr2 replacement is disabled, while the OptionPane patch is
|
||||
enabled by default.
|
||||
|
||||
Under Java 17, an AWT property-change event can run a fraction too early,
|
||||
before the Planmeca class has initialized `m_MessageArea`. When the original
|
||||
listener subsequently calculates the dialog size, it calls
|
||||
`getPreferredSize()` on this `null` reference. The resulting
|
||||
`NullPointerException` occurs on the AWT event thread and can terminate the
|
||||
complete application instead of merely drawing the popup.
|
||||
|
||||
`RomexisOptionPaneUIPatch` transforms only
|
||||
`romexis_laf.RomexisOptionPaneUI$MyPCListener.propertyChange()` and inserts a
|
||||
null guard immediately before the failing call. The original Romexis JAR stays
|
||||
unchanged on disk. Disable the patch only for a controlled comparison:
|
||||
|
||||
```env
|
||||
ROMEXIS_AGENT_OPTIONPANE_PATCH=false
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Persistent Data and Healthcheck
|
||||
|
||||
Client ProgramData is stored separately from Server and Admin state:
|
||||
|
||||
```text
|
||||
${ROMEXIS_DATA_ROOT}/docker/client/programdata
|
||||
-> /ProgramData/Planmeca/Romexis
|
||||
```
|
||||
|
||||
The healthcheck validates the X display, the running `Romexis.jar` process and
|
||||
the noVNC port. Because Romexis starts on demand, the service can remain in
|
||||
`starting` or become `unhealthy` until the desktop icon has been used.
|
||||
|
||||
---
|
||||
|
||||
## Operations and Troubleshooting
|
||||
|
||||
```bash
|
||||
docker compose up -d romexis-client
|
||||
docker compose logs -f romexis-client
|
||||
docker compose exec romexis-client tail -f /tmp/romexis-client.log
|
||||
```
|
||||
|
||||
If no desktop appears, check the Xvfb, Openbox, x11vnc and websockify messages in
|
||||
the container log. If Romexis exits after the icon is activated, inspect
|
||||
`/tmp/romexis-client.log` and confirm that `SERVER_RMI_HOSTNAME` resolves to the
|
||||
internal `romexis` service.
|
||||
|
||||
Reference in New Issue
Block a user