Clone
2
Java Property Agent.de
Patrick Gniza edited this page 2026-08-22 15:46:50 +02:00

Deutsch | English

Java Property Agent

Zweck

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 ausgewählte Kompatibilitätskorrekturen vor dem Definieren der betroffenen Klassen angewendet werden müssen.


Warum der Agent existiert

Beim Start von RomexisServer.jar unter Linux wählte Romexis intern ein Verhalten aus, das dem macOS-Runtime-Pfad entsprach.

Dieses macOS-spezifische Verhalten war mit der Linux-Docker-Umgebung nicht kompatibel.

Die entscheidende Eigenschaft war:

KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES

Damit Romexis Server im Linux-Container korrekt startet, musste diese Eigenschaft gesetzt werden auf:

true

Dadurch verhält sich Romexis in diesem Bereich wie die Windows-Server-Runtime und verwendet den erwarteten, auf Server-Properties basierenden Speicherort des Key-Vault-Passworts.

Ohne dieses Override konnte der Start von Romexis Server unter Linux fehlschlagen, weil die falsche plattformspezifische Property-Verarbeitung ausgewählt wurde.


Erforderliche Docker-Einstellung

Die wichtigste derzeit vom Docker-Image verwendete Umgebungsvariable ist:

PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true

Diese wird vom Java-Agent übersetzt in:

RxProperties.setProperty(
    RxProperties.KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES,
    true
);

Dieses Override ist einer der Gründe, warum Romexis Server zuverlässig im Linux-basierten Container betrieben werden kann.


Warum ein Java-Agent statt Datei-Patches?

Der Java-Agent-Ansatz vermeidet:

  • das Patchen von Romexis-Anwendungsdateien
  • das Ändern proprietärer Romexis-JARs
  • das Bearbeiten von Konfigurationsdateien, nachdem der Start bereits begonnen hat
  • die Pflege benutzerdefinierter Binär-Patches
  • das erneute Bauen von Romexis selbst

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.


Funktionsweise

Der Agent wird von der JVM geladen, bevor die Romexis-Anwendung startet.

Er durchsucht alle Umgebungsvariablen mit dem Präfix:

PROPERTY_AGENT_SET_

Der Teil nach dem Präfix wird als Feldname aus folgender Klasse interpretiert:

romexis_lib_base.types.RxProperties

Beispiel:

PROPERTY_AGENT_SET_KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true

Der Agent entfernt das Präfix:

KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES

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.

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:

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:

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:

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:

ROMEXIS_AGENT_OPTIONPANE_PATCH=true
-Dromexis.agent.optionpane.patch=true

Unterstützte Werttypen

Der Agent konvertiert Werte automatisch in einen der folgenden Typen:

Umgebungswert Java-Typ
true / false Boolean
Ganzzahlwerte Integer
alle anderen Werte String

Unbekannte Properties

Referenziert eine Umgebungsvariable ein Feld, das in RxProperties nicht existiert, lässt der Agent den Start nicht fehlschlagen.

Stattdessen protokolliert er eine Warnung:

JavaAgent WARN: RxProperties field not found: <field>

Damit ist der Mechanismus für optionale oder versionsabhängige Properties sicher.


Vorgesehene Anwendungsfälle

Der Java Property Agent ist vorgesehen für:

  • Docker-Deployments
  • Kubernetes-Deployments
  • automatisiertes Konfigurationsmanagement
  • Runtime-Anpassungen
  • Korrekturen der Plattformkompatibilität
  • kontrollierte Overrides des Romexis-Runtime-Verhaltens

Build-Integration

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:

agent-build

Das erzeugte JAR liegt abhängig von der Runtime unter folgenden Pfaden:

/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:

Premain-Class: RomexisPropertyAgent

Dadurch kann die JVM es laden über:

-javaagent:/opt/romexis/server/RomexisPropertyAgent.jar

Runtime-Integration

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.

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

Erfolgreiche Anwendung der Eigenschaft:

JavaAgent: set KEY_B_KEYVAULT_PWD_LOCATION_SERVER_PROPERTIES=true
JavaAgent: 1 properties applied

Unbekannte Eigenschaft:

JavaAgent WARN: RxProperties field not found: SOME_UNKNOWN_FIELD

Erfolgreiche Installation und Anwendung des Swing-Patches:

JavaAgent: RomexisOptionPaneUI MyPCListener null-guard transformer installed
JavaAgent: RomexisOptionPaneUI MyPCListener patched successfully; inserted null guards=<count>

Wichtige Hinweise

  • 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.

Aktuell entscheidende Eigenschaft

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