exportProject.ts is the counterpart of importProject.ts: from the editor model to the Java view topologyWriter.ts writes. Step X1, the topology: each node becomes the Java device of its kind with name, position and label flags; its ports become interfaces or ports; each link a cable drawn between its nodes; each documentation item a GUIDocuItem. A port's MAC is the one the simulation uses (the file's, or one derived from the port id); a router's gateway and DNS server go to every interface, as Java's own setters do (Java reads the first interface's only). A host with a wireless card joins a switch by a wireless cable, the only wireless connection Java makes. The import now enables a host's wireless by Java's card flag, also without an SSID, where Swift enables it for every SSID. Checked by Java: every corpus file, imported, exported and written, loads in Java FILIUS to the topology of the original up to named departures of the model (a derived MAC where Java rolls one at each load; documentation in render order, with the model's empty text, Dialog 12 and minimum size where Java has none or less). A synthetic model adds a label with IP and MAC, positions between pixels, a five-port switch, a wireless notebook, a three-interface router and a half-transparent bold text. 17 mutation probes, each loaded by Java, were all caught. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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).
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 samt Funk-Eigenschaft
wireless, bei Rechner/NotebookuseIPAsName/useMACAsName), untersystemSSID, 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 unterprojekt/anwendungen— fehlen, weil das Werkzeug nurkonfiguration.xmllä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); ein Empfänger, den eine ältere Datei als Zeichenkette hält, samt dem, was JavasAddressEntry(String)daraus macht; 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, und unter
packages/fls/test/exported/, die exportProject.test.ts mit
UPDATE_EXPORTED=1 schreibt (beide nicht eingecheckt), mit derselben
Lademethode wie den Korpus, und schreibt written.java.json bzw.
exported.java.json daneben, 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.