Table of Contents
Introduction : un bug silencieux mais bloquant
Lors du chargement d’un fichier Excel (.xlsx) via une application Java WebStart développée avec Apache POI, j’ai rencontré un bug bloquant.
Symptômes observés
- Un message silencieux apparaît dans la console :
java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredElementNSImpl.getTextContent()
- Le fichier Excel ne se charge pas.
- Aucun message clair ne permet d’identifier la cause.
Stack trace partielle
java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredElementNSImpl.getTextContent()
at org.apache.poi.openxml4j.opc.internal.unmarshallers.PackagePropertiesUnmarshaller.readElement(...)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(...)
...
Origine du bug
Ce bug est lié à une incompatibilité entre Apache POI et l’implémentation XML par défaut utilisée par OpenWebStart (OWS).
En effet, contrairement à l’ancien Java WebStart d’Oracle, OpenWebStart n’utilise pas toujours la même DocumentBuilderFactory
. Apache POI utilise intensément le parsing XML via javax.xml.parsers.DocumentBuilderFactory
, et certaines implémentations peuvent provoquer des erreurs d’appel de méthodes absentes (comme getTextContent()
dans ce cas).
Solution étape par étape
1. Définir la bonne factory XML via une option JVM
Il faut forcer l’utilisation de l’implémentation d’origine de Sun/Xerces.
Valeur à ajouter :
-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
2. Ajouter la propriété JVM via OpenWebStart
Deux étapes sont nécessaires :
a. Ajouter la variable d’environnement
Dans les variables d’environnement du système ou de l’utilisateur :
JAVAWS_VM_ARGS=-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
b. Modifier le fichier deployment.properties
Fichier à éditer :
C:\Program Files\OpenWebStart\config\deployment.properties
Ajoutez ou modifiez la ligne suivante :
deployment.jvm.arguments.whitelist=-Djavax.xml.parsers.DocumentBuilderFactory
⚠️ Sans cette whitelist, OWS bloquera votre paramètre avec un message du type :
Property 'XXX' is unknown.
3. Script PowerShell pour automatiser la configuration par utilisateur
Voici un petit script PowerShell permettant de :
- définir
NSSESSIONNAME
pour l’utilisateur courant - copier le fichier
deployment.properties
global dans le répertoire utilisateur (.config/icedtea-web
) :
# Initialisation de la variable NSSESSIONNAME pour la session de l'utilisateur
$env:NSSESSIONNAME = $env:USERNAME
# Définir NSSESSIONNAME de façon persistante pour l'utilisateur (sera chargée dans les futures sessions)
setx NSSESSIONNAME "$env:USERNAME"
$source = "C:\Program Files\OpenWebStart\config\deployment.properties"
$destFolder = "C:\Users\$env:USERNAME\.config\icedtea-web"
$destFile = "$destFolder\deployment.properties"
# Vérifier si le dossier existe, sinon le créer
if (!(Test-Path $destFolder)) {
New-Item -ItemType Directory -Path $destFolder -Force
}
# Copier le fichier
Copy-Item -Path $source -Destination $destFile -Force
Ce script garantit que la configuration OWS (y compris la whitelist JVM) soit bien appliquée pour chaque utilisateur Windows.
Conclusion
Ce bug très spécifique montre à quel point OpenWebStart, bien qu’utile pour remplacer Java WebStart, introduit une surcouche de sécurité qui peut poser problème dans les applications existantes.
Heureusement, il existe un contournement clair :
- passer par
JAVAWS_VM_ARGS
- autoriser explicitement les arguments JVM via
deployment.jvm.arguments.whitelist
- et appliquer ces paramètres pour chaque utilisateur grâce à un petit script PowerShell