Tout d'abord, trouver le PID de votre serveur webapp:
ps aux | grep tomcat
Adapter la commande si vous exécutez un autre serveur que tomcat, ou si vous avez plusieurs instances en cours d'exécution.
Ensuite, Vidage de tous les fils de ce serveur dans un fichier:
jstack 12345 > jstack.txt
Où est le PID 12345 que vous avez trouvé dans la première étape.
Ensuite, regardez le code source de votre bundle et trouvez l'activateur de service. Il semble généralement comme ceci:
package fr.free.nrw;
[import section]
public class ServiceActivator implements BundleActivator {
private ServiceRegistration registration;
@Override
public void start(BundleContext context) throws Exception {
registration = context.registerService(
MyService.class.getName(), new MyServiceImpl(), null);
}
@Override
public void stop(BundleContext context) throws Exception {
registration.unregister();
}
}
Prenez note:
- l'espace de noms,
- le nom de classe,
- le nom de la méthode d'arrêt.
Par exemple, dans l'exemple ci-dessus, ils sont fr.free.nrw
, ServiceActivator
et stop
, et de ces trois obtenir le nom complet fr.free.nrw.ServiceActivator.stop
.
Maintenant, ouvrez jstack.txt
et recherchez le nom complet.Même si le fichier est des milliers de lignes, il n'y aura plus probablement être un seul coup, et qui est le fil problématique:
at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.unregister(ServiceRegistrationImpl.java:222)
at fr.free.nrw.ServiceActivator.stop(ServiceActivator.java:30)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:830)
at org.eclipse.osgi.internal.framework.BundleContextImpl$4.run(BundleContextImpl.java:1)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.internal.framework.BundleContextImpl.stop(BundleContextImpl.java:823)
Dans ce fichier, allez jusqu'au début du paragraphe, qui sera quelque chose comme ceci:
"fileinstall-/home/nico/p/liferay/osgi/modules" #37 daemon prio=5 os_prio=0 tid=0x00007f39480e3000 nid=0x384f waiting on condition [0x00007f395d169000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000eb8defb8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
avec cette information en main, vous connu ce genre de problème de filetage se passe, et vous serez en mesure de le résoudre avec des techniques de débogage de fil habituelles Java (12).
Utilisez-vous un activateur dans votre module? L'arrêt de l'état signifie que la méthode Activator.stop() a été appelée mais n'a pas encore été renvoyée. Un de vos threads devrait être dans cette méthode. –
@ChristianSchneider: Ajout de mon ServiceActivator. –
Vous êtes sur la bonne voie pour résoudre le problème avec jstack. Il a créé un vidage de thread, mais la plupart des threads ont environ 5-10 lignes. Recherchez le thread qui est beaucoup plus grand, en particulier qui a appel à la méthode ServiceActivator.stop. Ensuite, vous verrez ce qui cause l'impasse ou le long sommeil. –