Exécuter un fichier JAR comme service Windows Server 2019 : guide complet, erreurs Win32Exception et solutions

Assurez la disponibilité continue de vos applications Java sur Windows Server 2019 : transformez simplement votre fichier .jar en service Windows, maîtrisez l’automatisation au démarrage, renforcez la sécurité et facilitez la maintenance — le tout sans dépendre d’une connexion utilisateur.

Sommaire

Exécution d’un fichier .jar en tant que service Windows

Vue d’ensemble

Le scénario classique est le suivant : vous disposez d’une application Java exécutable par la commande java -jar XXX.jar et vous souhaitez qu’elle s’exécute comme tout autre service Windows, visible dans le Service Control Manager (SCM), redémarrable depuis la console « Services » ou via PowerShell Restart‑Service. Sous Windows Server 2019, la méthode privilégiée consiste à utiliser Windows Service Wrapper (WinSW) ou, plus simplement, la commande système sc create. Cependant, une configuration incomplète conduit souvent à l’erreur :

System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified

Cette erreur traduit presque toujours un chemin Java mal résolu. La table ci‑dessous résume les actions correctives :

ÉtapeAction essentielleCommentaires utiles
1Vérifier la présence de plusieurs JDK/JRELes installations côte à côte (ex. JDK 8, JDK 17, AdoptOpenJDK) font échouer la résolution de java.exe. Inventoriez-les via Get‑Command java ‑All ou la variable d’environnement %PATH%.
2Corriger JAVA_HOMELa variable doit pointer vers la racine, pas vers \bin. Exemple :
JAVA_HOME=C:\Program Files\Java\jdk‑17
3Mettre à jour PATHInsérez %JAVA_HOME%\bin au début pour éviter qu’une version obsolète n’intercepte l’appel.
4Tester hors serviceLancez java -jar XXX.jar dans Windows Terminal. Toute erreur d’arguments, de dépendances Spring ou de ports déjà utilisés apparaît ici, avant même d’impliquer le SCM.
5Configurer WinSW ou sc createExtrait WinSW :
<service> <id>MyJarSvc</id> <executable>%JAVA_HOME%\bin\java.exe</executable> <argument>-jar C:\apps\XXX.jar</argument> </service>
Commande SC :
sc create MyJarSvc binPath= "\"%JAVA_HOME%\bin\java.exe\" -jar \"C:\apps\XXX.jar\"" start= auto
6Redémarrer le serviceUne fois l’environnement corrigé :
net start MyJarSvc
Le statut passe durablement à « Running ».

Validation et diagnostic rapide

  • Dans l’Observateur d’événements, vérifiez Applications and Services Logs ► Microsoft‑Windows‑Winsw/Operational pour tout code de sortie Java.
  • Avec sc qc MyJarSvc, assurez‑vous que BINPATH reflète exactement le chemin absolu vers java.exe.
  • Lancez handle ‑a java.exe (Sysinternals) pour détecter un verrouillage de port ou de fichier.

Exécuter l’application en arrière‑plan dès le démarrage du serveur

Démarrage automatique via le Service Control Manager

Une fois le service créé, positionnez son type de démarrage sur auto :

sc config MyJarSvc start= auto

Le SCM invoque alors votre JVM juste après le chargement du noyau et des pilotes critiques, indépendamment de toute session utilisateur. C’est la solution la plus fiable pour les applications middleware, micro‑services Spring Boot, passerelles API, etc.

Solutions alternatives sans service

  • Tâche planifiée : utilisez le déclencheur « At Startup ». Cochez « Exécuter si l’utilisateur est connecté ou non » et « Exécuter avec les privilèges les plus élevés » pour imiter un service.
  • Script de démarrage Local GPO : dans Computer Configuration ► Windows Settings ► Scripts (Startup), déposez votre .bat ou .ps1. Simple, mais le temps de lancement dépend de la stratégie de groupe.
  • NSSM (Non‑Sucking Service Manager) : interface graphique minimale ; idéal pour les petites équipes qui veulent éviter XML. Commande type :
    nssm install MyJarSvc "%JAVA_HOME%\bin\java.exe" "-jar" "C:\apps\XXX.jar"
  • PowerShell 7 : New‑Service :
    New-Service -Name MyJarSvc -BinaryPathName '"%JAVA_HOME%\bin\java.exe" -jar "C:\apps\XXX.jar"' -StartupType Automatic

Bonnes pratiques complémentaires

  1. Compte de service dédié :
    évitez LocalSystem. Créez un compte local ou AD avec droit Log on as a service et lecture sur le répertoire C:\apps.
  2. Journalisation tournante :
    dans WinSW, ajoutez :
    <logmode>roll-by-size</logmode> <logpath>%ProgramData%\MyJarSvc\logs</logpath>
  3. Récupération automatique :
    sc failure MyJarSvc reset= 60 actions= restart/5000 redémarre le service après 5 s, trois tentatives, puis déclenche une action planifiée si besoin.
  4. Surveillance intégrée : combinez Get-Service MyJarSvc | Select‑Object Status, StartType et une alerte Event Log pour prévenir toute panne.

Dépannage avancé

Les cinq causes racines les plus fréquentes

  1. Version Java incompatible : un .jar compilé en Java 21 lancé sur un JRE 8 provoque UnsupportedClassVersionError. Compilez‑le ou mettez à jour votre JDK.
  2. Paramètres mémoire inadéquats : ajoutez -Xms256m -Xmx1g dans les arguments WinSW pour éviter OutOfMemoryError: Java heap space.
  3. Dépendance système manquante : par exemple Microsoft Visual C++ Redistributable pour une bibliothèque JNI.
  4. Timeout SCM : si l’app démarre lentement (>30 s), le SCM envoie Start Pending timed out. Dans WinSW, paramétrez <onfailure><action restartDelay="60000"/></onfailure> ou ajoutez --delay 60000 à NSSM.
  5. Chemin UNC : le SCM interprète mal \\NAS\share\my.jar. Copiez localement ou mappez un lecteur.

Outils incontournables

  • jcmd pid VM.flags pour confirmer les options JVM effectives.
  • logman query providers + ETW pour tracer les appels système.
  • ProcMon (Sysinternals) filtré sur java.exe pour repérer le fameux NAME NOT FOUND.

Sécurisation et maintenance continue

Mises à jour Java sans interruption

Planifiez un rolling upgrade :

  1. Installez la nouvelle JDK dans C:\Program Files\Java\jdk‑xx.
  2. Modifiez JAVA_HOME via setx ou le Registre HKLM ►Environment.
  3. Redémarrez MyJarSvc lors d’une fenêtre faible trafic.
  4. Contrôlez la version :Get‑Process java | Select‑Object Path.

Audit et durcissement

  • Activez AppLocker ou l’exploit protection pour empêcher le chargement dynamique non signé.
  • Stockez les secrets (tokens JWT, chaînes JDBC) dans le Windows Credential Manager ou un vault HashiCorp, pas en clair dans l’XML WinSW.
  • Consignez la variable _JAVA_OPTIONS afin d’éviter une injection par utilisateur malveillant.

Supervision proactive

Intégrez le service à Windows Admin Center ou à un outil APM (Elastic APM, Prometheus + Grafana) pour mesurer :

  • Temps de réponse HTTP / JMS
  • Utilisation CPU % par processus java.exe
  • Garbage Collection pausing time via -Xlog:gc

FAQ éclair

Comment forcer le service à s’arrêter proprement ?

Ajoutez le paramètre JVM -XX:+ExitOnOutOfMemoryError ou interceptez SIGTERM via un shutdown hook. WinSW exécutera alors la méthode stop avant de tuer la JVM.
Peut‑on exécuter plusieurs services à partir du même .jar ?

Oui : dupliquez le fichier MyJarSvc.exe de WinSW, modifiez les identifiants <id> et changez le port d’écoute (Spring : --server.port), puis enregistrez chaque instance séparément.
Que se passe‑t‑il si l’on désinstalle Java ?

Le service revient en statut « Failed to Find BinPath » et génère l’erreur 2 (Windows cannot find the file specified). D’où l’importance de surveiller la clé ImagePath :

reg query "HKLM\SYSTEM\CurrentControlSet\Services\MyJarSvc" /v ImagePath

Points clés à retenir

  • 90 % des arrêts immédiats proviennent d’un JAVA_HOME ou d’un BINPATH mal renseigné.
  • Tester l’exécutable manuellement reste la méthode la plus rapide pour séparer problème applicatif et problème d’hébergement.
  • WinSW, NSSM et le Task Scheduler sont tous viables ; la sélection dépend de votre besoin de granularité (journalisation, récupération, comptes de service).
  • Sécurisez et documentez vos variables d’environnement dans le Registre ou un script ;
    vous éviterez les surprises lors d’un patch Tuesday ou d’une mise à niveau majeure de Java.

En appliquant ces bonnes pratiques, vous obtenez une application Java démarrée avant toute connexion, supervisée, redémarrée automatiquement et prête pour les upgrades — du véritable DevOps made in Windows Server.

Sommaire