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.
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 :
Étape | Action essentielle | Commentaires utiles |
---|---|---|
1 | Vérifier la présence de plusieurs JDK/JRE | Les 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% . |
2 | Corriger JAVA_HOME | La variable doit pointer vers la racine, pas vers \bin . Exemple :JAVA_HOME=C:\Program Files\Java\jdk‑17 |
3 | Mettre à jour PATH | Insérez %JAVA_HOME%\bin au début pour éviter qu’une version obsolète n’intercepte l’appel. |
4 | Tester hors service | Lancez 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. |
5 | Configurer WinSW ou sc create | Extrait 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 |
6 | Redémarrer le service | Une 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 versjava.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
- Compte de service dédié :
évitezLocalSystem
. Créez un compte local ou AD avec droit Log on as a service et lecture sur le répertoireC:\apps
. - Journalisation tournante :
dans WinSW, ajoutez :
<logmode>roll-by-size</logmode> <logpath>%ProgramData%\MyJarSvc\logs</logpath> - 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. - 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
- Version Java incompatible : un
.jar
compilé en Java 21 lancé sur un JRE 8 provoqueUnsupportedClassVersionError
. Compilez‑le ou mettez à jour votre JDK. - Paramètres mémoire inadéquats : ajoutez
-Xms256m -Xmx1g
dans les arguments WinSW pour éviterOutOfMemoryError: Java heap space
. - Dépendance système manquante : par exemple Microsoft Visual C++ Redistributable pour une bibliothèque JNI.
- 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. - 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 fameuxNAME NOT FOUND
.
Sécurisation et maintenance continue
Mises à jour Java sans interruption
Planifiez un rolling upgrade :
- Installez la nouvelle JDK dans
C:\Program Files\Java\jdk‑xx
. - Modifiez
JAVA_HOME
viasetx
ou le Registre HKLM ►Environment. - Redémarrez
MyJarSvc
lors d’une fenêtre faible trafic. - 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’unBINPATH
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.