Vérifier et analyser si une session JCR fuit dans votre instance AEM

Dernière mise à jour : 2023-10-31

Recherchez et identifiez la cause de la fuite de session JCR de votre application AEM 6.x.

Description

Vérifiez si votre application AEM 6.x comporte une fuite de session JCR et recherchez la source.

Environnement

AEM 6.4,6.5

Résolution

I. VÉRIFIER S’IL EXISTE UNE FUITE DE SESSION

  1. Accédez à http://host:port/system/console/jmx et connectez-vous en tant qu’administrateur.
  2. Utilisez la fonction de recherche du navigateur pour rechercher toutes les occurrences des objets SessionStatistics sur la page.
  3. Si vous trouvez plus de 500, alors il y a une fuite de session.

II. IDENTIFIER LE CODE QUI LAISSE DES SESSIONS

Si vous avez trouvé une fuite de session, suivez les étapes ci-dessous pour trouver son origine.

  1. Faites défiler la page vers le bas jusqu’aux objets SessionStatistics .
  2. Ouvrez certains des objets SessionStatistics dans un nouvel onglet du navigateur en [Ctrl] +Clic sur certains qui comportent un horodatage ultérieur ou un numéro d’identification supérieur.  Par exemple, celui ci-dessous a un id de
  3. 12105:org.apache.jackrabbit.oak "SessionStatistics" "admin@session-12105@Aug 10, 2020 7:03:25 PM" {id=287}.
  4. Plus le numéro d’ID est élevé, plus la session a été créée après le dernier redémarrage de l’AEM.
  5. Examinez les arborescences des appels indiquant le code qui a ouvert ces sessions.
  6. Recherchez des packages java d’application dans la pile.  Si le code fait partie de votre application, reportez-vous à la section suivante ci-dessous.

III. CORRECTION DE LA FUITE DE SESSION

Pour empêcher et corriger les fuites de session JCR :

  • Si vous ouvrez une javax.jcr.Session dans votre code, puis fermez-le toujours via Session.logout()
  • Si vous ouvrez une org.apache.sling.api.resource.ResourceResolver dans votre code, puis fermez-le toujours via ResourceResolver.close()

Fermeture des objets Session :

Le code ci-dessous laisse une session ouverte :

try {
Session session = repository.loginAdministrative(null);
Node node = session.getNode("/content/we-retail");
  log.info("Node: " + node.getPath());
} catch (RepositoryException re) {
log.error(re.getMessage(), re);
}

*Remarque :*Outre la fermeture de la session, ce code appelle également repository.loginAdministrative pour l’ouvrir. Cette façon d’ouvrir des sessions a été abandonnée dans les versions ultérieures d’AEM pour des raisons de sécurité.

Pour fermer la session, placez le code par un bloc try/finally et appelez session.logout() :

Session session = null;
try {
session = repository.loginAdministrative(null);
// use session
} catch (RepositoryException re) {
log.error(re.getMessage(), re);
} finally {
if (session != null && session.isLive()) {
session.logout();
}
}

Soyez prudent lorsque vous créez une session ou en partagez une.  Lorsque vous partagez une session sur plusieurs objets, il devient plus difficile de suivre où elle a été ouverte et quand elle doit être fermée.  En outre, les sessions ne doivent jamais être partagées sur Java Threads.

Fermeture des objets ResourceResolver :

Le code ci-dessous laisse un ResourceResolver ouvert :

try{
ResourceResolver resourceResolver = resourceFactory.getServiceResourceResolver(paramMap);
  Resource resource = resourceResolver.getResource("/content/we-retail");
  log.info("Resource: " + res.getPath());
} catch(Exception e){
log.error(e.getMessage());
}

Pour fermer resourceResolver, placez le code dans un bloc try/finally et appelez resourceResolver.close() :

try{
ResourceResolver resourceResolver = resourceFactory.getServiceResourceResolver(paramMap);
  // use ResourceResolver
} catch (Exception e) {
log.error(e.getMessage());
} finally {
if(resourceResolver != null && resourceResolver.isLive()) {
resourceResolver.close();
  }
}

Remarque importante

Les objets Session et ResourceResolver obtenus via SlingRequest ou WorkflowSession ne doivent pas être fermés par votre application.  Par exemple:

slingRequest.getResourceResolver().adaptTo(Session.class);
//Or
workflowSession.getSession();

Ce résolveur et cette session seront fermés automatiquement une fois la requête traitée.

Sur cette page