aboutsummaryrefslogtreecommitdiff
path: root/src/main/resources/META-INF
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-15 10:51:11 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2026-08-15 10:51:11 +0200
commit2b1841e17533543d1cb15220ca86a2a37c853daf (patch)
tree01b940cb06c5abc36704d2d4853343ee7b38ce02 /src/main/resources/META-INF
parent5700bbcb89186e432c5c7dd232b61c052de8e784 (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')
-rw-r--r--src/main/resources/META-INF/native-image/eu.mulk/aendggner/reachability-metadata.json361
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