diff options
| author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-15 10:51:11 +0200 |
|---|---|---|
| committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2026-08-15 10:51:11 +0200 |
| commit | 2b1841e17533543d1cb15220ca86a2a37c853daf (patch) | |
| tree | 01b940cb06c5abc36704d2d4853343ee7b38ce02 /src/main/resources/META-INF/native-image | |
| parent | 5700bbcb89186e432c5c7dd232b61c052de8e784 (diff) | |
Die Web-App rechnet im Browser statt auf dem Server
Bisher lief die Weboberfläche auf einem JDK-HttpServer: Uploads landeten als
temporäre Dateien auf dem Server, die Synopse entstand dort. Das kostete
Betrieb (systemd, Reverse Proxy, Rate-Limiting, Timeouts) und verlangte ein
Datenschutzversprechen, das nur zusicherbar, nicht nachprüfbar war — gerade
Entwurfstexte verließen den Rechner der Nutzer:innen.
Neu übersetzt `./mvnw -Pwasm package` dieselbe Pipeline mit GraalVM Web Image
(`native-image --tool:svm-wasm`) nach WebAssembly, PDFBox eingeschlossen.
Ausgeliefert werden nur noch statische Dateien; gerechnet wird im Browser.
Die erzeugte Synopse ist byteweise identisch mit der der Befehlszeile
(SHA-256 verglichen für IfSG 48/27/21 und BayJG 151/3/54).
Die Befehlszeile bleibt unberührt: `./mvnw package` erzeugt unverändert das
JAR, alle Optionen und Meldungstexte sind gleich, das Wasm-Profil ist rein
additiv und verlangt Oracle GraalVM 25.1+ (die CE hat kein Web Image).
Portabilitätsschnitt (nützt beiden Fassungen):
* `Quelle` (Name + Bytes) ersetzt `Path` in der Pipeline; nur die
Befehlszeile kennt noch ein Dateisystem. Der Name trägt genau den
bisherigen `getFileName()`-Text, damit Warnungen und Quellenzeile
wortgleich bleiben.
* `DateiTyp` erkennt PDF/XML/Klartext an den Signaturbytes. Tika entfällt —
eine schwergewichtige Abhängigkeit samt ServiceLoader- und
XML-Konfiguration weniger, was der Wasm-Übersetzung unmittelbar zugutekommt.
Vier Eigenheiten von Web Image, die der Quelltext jeweils an Ort und Stelle
vermerkt:
* `java.util.zip.Inflater` ist nicht angebunden (GR-65205), ohne Inflate ist
kein PDF lesbar. `InflaterErsatz` substituiert ihn durch jzlib.
* Typisierte JS-Felder lassen sich nicht nach `byte[]` umsetzen
(„byteArrayHub is not defined“); der Dateiinhalt wandert als Base64.
* JULs Standardformatter ruft `StackWalker`, den es dort nicht gibt.
* Im Worker fehlt `document.currentScript`, worauf die Laufzeit das
Wasm-Modul neben `worker.js` sucht; die VM wird deshalb mit ausdrücklichem
Pfad ein zweites Mal gestartet.
Die Reachability-Metadaten stammen aus einem Lauf des Tracing-Agents über die
Pipeline; die PDFBox- und FontBox-Ressourcen sind als Globs ergänzt, sonst
scheitern PDFs an „Could not find referenced cmap stream Identity-H“.
Entfallen: WebMain, UploadHandler, StaticHandler, Multipart und die
systemd-Unit. Die nginx-Vorlage liefert jetzt statische Dateien aus, und die
Datenschutzseite sagt, was nun stimmt: Die Dateien verlassen den Rechner
nicht.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I38faf2ac0f764d601f080d4276babe4747773683
Diffstat (limited to 'src/main/resources/META-INF/native-image')
| -rw-r--r-- | src/main/resources/META-INF/native-image/eu.mulk/aendggner/reachability-metadata.json | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/src/main/resources/META-INF/native-image/eu.mulk/aendggner/reachability-metadata.json b/src/main/resources/META-INF/native-image/eu.mulk/aendggner/reachability-metadata.json new file mode 100644 index 0000000..4f85735 --- /dev/null +++ b/src/main/resources/META-INF/native-image/eu.mulk/aendggner/reachability-metadata.json @@ -0,0 +1,361 @@ +{ + "reflection": [ + { + "type": "ch.qos.logback.classic.Logger" + }, + { + "type": "com.sun.crypto.provider.AESCipher$General", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "java.awt.image.BufferedImage", + "jniAccessible": true, + "fields": [ + { + "name": "colorModel" + }, + { + "name": "imageType" + }, + { + "name": "raster" + } + ], + "methods": [ + { + "name": "getRGB", + "parameterTypes": [ + "int", + "int", + "int", + "int", + "int[]", + "int", + "int" + ] + }, + { + "name": "setRGB", + "parameterTypes": [ + "int", + "int", + "int", + "int", + "int[]", + "int", + "int" + ] + } + ] + }, + { + "type": "java.awt.image.ColorModel", + "jniAccessible": true, + "fields": [ + { + "name": "colorSpace" + }, + { + "name": "colorSpaceType" + }, + { + "name": "isAlphaPremultiplied" + }, + { + "name": "is_sRGB" + }, + { + "name": "nBits" + }, + { + "name": "numComponents" + }, + { + "name": "supportsAlpha" + }, + { + "name": "transparency" + } + ], + "methods": [ + { + "name": "getRGBdefault", + "parameterTypes": [] + } + ] + }, + { + "type": "java.awt.image.Raster", + "jniAccessible": true, + "fields": [ + { + "name": "dataBuffer" + }, + { + "name": "height" + }, + { + "name": "minX" + }, + { + "name": "minY" + }, + { + "name": "numBands" + }, + { + "name": "numDataElements" + }, + { + "name": "sampleModel" + }, + { + "name": "sampleModelTranslateX" + }, + { + "name": "sampleModelTranslateY" + }, + { + "name": "width" + } + ] + }, + { + "type": "java.awt.image.SampleModel", + "jniAccessible": true, + "fields": [ + { + "name": "height" + }, + { + "name": "width" + } + ], + "methods": [ + { + "name": "getPixels", + "parameterTypes": [ + "int", + "int", + "int", + "int", + "int[]", + "java.awt.image.DataBuffer" + ] + }, + { + "name": "setPixels", + "parameterTypes": [ + "int", + "int", + "int", + "int", + "int[]", + "java.awt.image.DataBuffer" + ] + } + ] + }, + { + "type": "java.awt.image.SinglePixelPackedSampleModel", + "jniAccessible": true, + "fields": [ + { + "name": "bitMasks" + }, + { + "name": "bitOffsets" + }, + { + "name": "bitSizes" + }, + { + "name": "maxBitSize" + } + ] + }, + { + "type": "java.lang.Boolean", + "jniAccessible": true, + "methods": [ + { + "name": "getBoolean", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "type": "java.lang.System", + "jniAccessible": true, + "methods": [ + { + "name": "load", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "type": "org.apache.commons.logging.LogFactory" + }, + { + "type": "org.apache.commons.logging.impl.SLF4JLogFactory" + }, + { + "type": "org.apache.commons.logging.impl.WeakHashtable", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "org.apache.log4j.LogManager" + }, + { + "type": "org.apache.logging.log4j.Logger" + }, + { + "type": "org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "org.jboss.logmanager.LogManager" + }, + { + "type": "org.slf4j.jul.JULServiceProvider" + }, + { + "type": "sun.awt.image.IntegerComponentRaster", + "jniAccessible": true, + "fields": [ + { + "name": "data" + }, + { + "name": "dataOffsets" + }, + { + "name": "pixelStride" + }, + { + "name": "scanlineStride" + }, + { + "name": "type" + } + ] + }, + { + "type": "sun.misc.Unsafe", + "fields": [ + { + "name": "theUnsafe" + } + ], + "methods": [ + { + "name": "invokeCleaner", + "parameterTypes": [ + "java.nio.ByteBuffer" + ] + } + ] + }, + { + "type": "sun.security.provider.MD5", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.security.provider.NativePRNG", + "methods": [ + { + "name": "<init>", + "parameterTypes": [ + "java.security.SecureRandomParameters" + ] + } + ] + }, + { + "type": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "<init>", + "parameterTypes": [] + } + ] + }, + { + "type": "sun.text.resources.cldr.FormatData" + }, + { + "type": "sun.util.resources.cldr.CalendarData" + } + ], + "resources": [ + { + "glob": "META-INF/services/java.net.spi.URLStreamHandlerProvider" + }, + { + "glob": "META-INF/services/java.time.zone.ZoneRulesProvider" + }, + { + "glob": "META-INF/services/javax.xml.parsers.DocumentBuilderFactory" + }, + { + "glob": "META-INF/services/org.apache.commons.logging.LogFactory" + }, + { + "glob": "META-INF/services/org.jboss.logging.LoggerProvider" + }, + { + "glob": "META-INF/services/org.slf4j.spi.SLF4JServiceProvider" + }, + { + "glob": "commons-logging.properties" + }, + { + "module": "java.base", + "glob": "jdk/internal/icu/impl/data/icudt76b/nfc.nrm" + }, + { + "module": "java.base", + "glob": "jdk/internal/icu/impl/data/icudt76b/ubidi.icu" + }, + { + "glob": "org/apache/fontbox/**" + }, + { + "glob": "org/apache/pdfbox/resources/**" + } + ] +}
\ No newline at end of file |
