Erreur OpenWebStart avec Apache POI et fichier Excel

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

Références utiles