topologyWriter.ts puts each installed application of a PC or notebook under its key and gives it the system software, as installApp does, with its settings: a server's switch and port, a client's target, DNS recursion, virtual hosts, the peer count, the personal firewall. The applications follow the files, as in Java's own files: the web server, the peer-to-peer application and the e-mail server make their directories only where the files lack them, and the DNS server reads /dns/hosts when it is installed. E-mail accounts, messages and address books are the next step. The Java oracle now reports a personal firewall's rules in full, not their number (the corpus has none; its result is byte-equal). Checked by Java against Java: every corpus file, read and written again, loads with the same applications as the original. The synthetic topology adds every FILIUS application with settings away from its defaults, a personal firewall with a rule, an own index.html (Java makes no second) and a missing /peer2peer directory, which Java makes at the end. 12 mutation probes, among them files and applications in reverse order, each loaded by Java, were all caught. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
6.4 KiB
Markdown
121 lines
6.4 KiB
Markdown
# Java-Orakel
|
||
|
||
Das Orakel misst Javas **echtes** Verhalten, Fehler eingeschlossen. Der
|
||
TypeScript-Leser folgt Java, übernimmt aber keine Java-Fehler (Datenverlust,
|
||
Absturz, eigene Ausgabe nicht wieder lesbar, Tippfehler, Verstoß gegen den
|
||
Standard); jede solche Abweichung steht in den Tests namentlich mit Grund
|
||
(`JAVA_BUGS`). Was Java selbst schreibt — der Korpus — wird exakt wie in
|
||
Java gelesen.
|
||
|
||
Java-Filius selbst liest den Korpus (`corpus/`) und schreibt, was es gefunden
|
||
hat, nach `corpus/corpus.java.json`. **Java ist der Schiedsrichter für das
|
||
Dateiformat** — der Swift-Leser verliert in 10 von 23 Dateien Geräte (Plan
|
||
§13, M2).
|
||
|
||
```bash
|
||
npm run oracle:java # = tools/java-oracle/run.sh
|
||
```
|
||
|
||
Braucht JDK 17+, Maven und `xvfb-run`. Filius öffnet beim Laden sein
|
||
Hauptfenster (`Information.reset` → `JMainFrame`), deshalb läuft es an einem
|
||
virtuellen Bildschirm statt „headless".
|
||
|
||
* Gelesen wird über Filius' eigene, private Lademethode
|
||
`SzenarioVerwaltung.netzwerkLaden` (per Reflection) — Javas Weg, kein Nachbau.
|
||
* Stand: `gitlab.com/filius1/filius` @ `6640354` (2.14.0), wird beim ersten
|
||
Lauf nach `.upstream/` geholt und gebaut.
|
||
* **Gewürfeltes:** Was nicht in der Datei steht, würfelt Filius zum Teil
|
||
(MAC-Adressen, die SSID eines Switches). Jede Datei wird deshalb **zweimal**
|
||
geladen; jeder Wert, der sich zwischen beiden Läufen unterscheidet,
|
||
erscheint als `null`. Zwei Läufe des Werkzeugs sind byte-gleich. (Bis
|
||
29.09.2026 suchte es die MAC im Dateitext und hielt dabei acht
|
||
kleingeschriebene für gewürfelt.)
|
||
* Bisher ausgelesen: Geräte (Klasse, Name, Beschriftung, Position,
|
||
Schnittstellen, bei Rechner/Notebook `useIPAsName`/`useMACAsName`), unter
|
||
`system` SSID, Lernzeit des Switches, RIP, manuelle Routen, die Firewall
|
||
von Router und Heimrouter, DHCP-Client und -Server, die statische
|
||
NAT-Tabelle des Heimrouters, die Verbindung eines Modems und das
|
||
Dateisystem (Inhalte als Länge und SHA-256, damit die Referenz klein
|
||
bleibt; bei Router und Heimrouter stehen vorn die Dateien, die Javas
|
||
Konstruktor aus eigenen Vorlagen erzeugt, dahinter die aus der Datei) und
|
||
die installierten Programme eines Rechners mit ihren Einstellungen (die
|
||
persönliche Firewall samt Regeln) (Klassen, die Filius
|
||
nicht mitbringt — eigene Anwendungen im Archiv unter `projekt/anwendungen`
|
||
— fehlen, weil das Werkzeug nur `konfiguration.xml` lädt); E-Mail: Konten des Servers aus der Bean-Liste und aus `/mailserver/konten.txt` (`kontenLaden`), Ordner und Adressbuch des Clients und sein Konto aus `/konten.txt` (`laden`); Kabel (Enden als Gerät/Schnittstelle),
|
||
Doku-Elemente.
|
||
|
||
## Getter-Standardwerte
|
||
|
||
XMLEncoder teilt gleiche `Integer`/`Boolean`-Objekte. Ein Wert, der einmal als
|
||
Ergebnis eines Getters geschrieben wurde (`<void id="Integer0"
|
||
property="iconTextGap"/>`), taucht später nur noch als Verweis auf — etwa als
|
||
x-Koordinate eines Geräts. Daran scheitert der Swift-Leser (Plan §13, M2).
|
||
|
||
`GetterDefaults` erzeugt die betroffenen Klassen wie XMLDecoder (ohne
|
||
Argumente) und ruft den Getter auf; das Ergebnis steht in
|
||
`packages/fls/src/javaDefaults.json`. Gemessen, nicht geraten: Filius' Knopf
|
||
setzt `verticalTextPosition` auf 3 (BOTTOM), nicht auf Swings 0 (CENTER).
|
||
|
||
Dasselbe gilt für **statische Konstanten**: Die erste `0` einer Datei kann als
|
||
`<object class="javax.swing.SwingConstants" field="CENTER"/>` stehen, und jede
|
||
spätere `0` — etwa die Rot-, Grün- und Blauwerte einer schwarzen Doku-Farbe —
|
||
verweist darauf. Schreibweise im Aufruf: `klasse::FELD`, Ergebnis
|
||
`"SwingConstants.CENTER": 0`.
|
||
|
||
## `IP.ipCheck`
|
||
|
||
Java-Filius schickt jede IP-Adresse und Maske beim Laden durch
|
||
`IP.ipCheck`. `IpCheckCases` ruft es für jede Zeile von
|
||
`packages/fls/test/ip-check.cases.txt` auf (ASCII, Nicht-ASCII als
|
||
`\uXXXX`) und schreibt `ip-check.java.json`. Gemessen: leere Abschnitte
|
||
zählen nicht (`10..0.0.1`), Vorzeichen und führende Nullen gehen, ebenso
|
||
Ziffern jeder Schrift in der BMP (Thai, Devanagari, Vollbreite) — aber kein
|
||
Leerzeichen und kein 𝟏 (Ersatzpaar).
|
||
|
||
## `/dns/hosts`
|
||
|
||
Javas DNS-Server liest seine Einträge bei jeder Anfrage aus der Textdatei
|
||
`/dns/hosts`. `DnsHostsCases` legt für jede Zeile von
|
||
`packages/fls/test/dns-hosts.cases.txt` (eine ganze Datei je Zeile, ASCII,
|
||
Zeilenumbruch als `\u000A`) einen Rechner mit dieser Datei an und schreibt,
|
||
was `DNSServer.holeResourceRecords()` liefert, nach `dns-hosts.java.json`.
|
||
Gemessen: Felder trennt nur ein einzelnes Leerzeichen (Tab und NBSP nicht),
|
||
Zeilen nur LF; ein Name, den Javas Muster ablehnt (`1und1.de`, `müller.de`),
|
||
wird leer, der Eintrag bleibt trotzdem; Typen außer A/MX/NS (auch `a`,
|
||
`CNAME`, eine Kommentarzeile) gelten als gültig; eine TTL, die kein `int`
|
||
ist, wird still 3600.
|
||
|
||
## Was Java aus unseren Dateien lädt
|
||
|
||
`run.sh` lädt auch die Dateien unter `packages/fls/test/written/`, die
|
||
`topologyWriter.test.ts` mit `UPDATE_WRITTEN=1` schreibt (nicht
|
||
eingecheckt), mit derselben Lademethode wie den Korpus, und schreibt
|
||
`packages/fls/test/written.java.json` samt SHA-256 jeder Datei
|
||
(`--sha256`), damit der Test merkt, wenn der Befund nicht mehr zur Ausgabe
|
||
passt. Je Kabel steht auch `panel`: die Geräte, zwischen denen die
|
||
Oberfläche es zeichnet (`JCablePanel.ziel1/ziel2`) — im Korpus bei allen 183
|
||
Kabeln die Geräte, die es verbindet.
|
||
|
||
## Was Java aus unserem XML macht
|
||
|
||
`BeansDump` liest jede `*.xml` unter `packages/fls/test/beans/` mit
|
||
`XMLDecoder` und beschreibt, was dabei herauskommt (Beans über ihre
|
||
Eigenschaften mit Lese- und Schreibmethode, Listen, Maps, Arrays,
|
||
`Rectangle`, `Color`; ein zweites Mal gesehenes Objekt als Verweis) —
|
||
`beans.java.json`. Fehler, die der Decoder sonst nur ins Log schreibt,
|
||
sammelt ein `ExceptionListener`. Zeichenketten stehen als ASCII mit
|
||
`\uXXXX`, weil ein einsames Surrogat in UTF-8 sonst zu „?“ würde.
|
||
|
||
## E-Mail-Kontodateien
|
||
|
||
`EmailFileCases server|client` legt für jede Zeile von
|
||
`packages/fls/test/email-server.cases.txt` bzw. `email-client.cases.txt`
|
||
einen Rechner mit dieser Datei an (`/mailserver/konten.txt` bzw.
|
||
`/konten.txt`) und schreibt, welche Konten `EmailServer.kontenLaden()` bzw.
|
||
`EmailAnwendung.laden()` daraus machen. Gemessen: Eine einzige Serverzeile
|
||
mit weniger als fünf Feldern lässt Java die ganze Datei verwerfen
|
||
(`NoSuchElementException` — die Simulation startet nicht); leere Felder
|
||
überspringt Java, statt sie zu zählen; eine Nachricht mit leerem Text geht
|
||
verloren, weil `split` leere Felder am Ende abschneidet. Beim Client gewinnt
|
||
die letzte Zeile, auch eine kaputte, die das Konto leert.
|