Модуль Liferay (комплект OSGi) остается в режиме "Остановка"
Иногда, когда я останавливаю свой модуль Liferay (например, когда я помещаю новую версию его JAR в deploy/
) модуль отказывается останавливаться.
Пока модуль должен перейти в состояние "Разрешено", он всегда остается в состоянии "Остановка":
Обычно это происходит из-за того, что поток где-то не завершен или сетевое соединение не закрыто должным образом, и часто бывает трудно исследовать это.
Мой вопрос: как эффективнее узнать, в чем проблема этого модуля Liferay?
Что я пробовал:
- В Gogo Shell
diag <module id>
похоже, не предоставляет никакой ценной информации о том, почему модуль отказывается выходить из состояния "Остановка". - jstack выводит тысячи строк, подавляющее большинство которых находится за пределами рассматриваемого модуля Liferay. Если бы был способ показать информацию jstack только для моего модуля, это было бы замечательно.
2 ответа
Сначала найдите PID вашего сервера веб-приложений:
ps aux | grep tomcat
Адаптируйте команду, если вы используете сервер, отличный от tomcat, или если у вас запущено несколько экземпляров.
Затем выведите все потоки этого сервера в файл:
jstack 12345 > jstack.txt
Где 12345 - это PID, который вы нашли на первом шаге.
Затем посмотрите на исходный код вашего пакета и найдите активатор службы. Обычно это выглядит так:
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();
}
}
Сделать заметку о:
- пространство имен,
- название класса,
- имя метода остановки.
Например, в приведенном выше примере они fr.free.nrw
, ServiceActivator
а также stop
и из этих трех получают полное имя fr.free.nrw.ServiceActivator.stop
,
Теперь откройте jstack.txt
и искать полное имя. Несмотря на то, что длина файла составляет тысячи строк, скорее всего, будет только один удар, и это проблемный поток:
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)
В этом файле перейдите к началу абзаца, который будет выглядеть примерно так:
"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)
Получив эту информацию, вы узнаете, что за проблема с потоками происходит, и сможете решить ее с помощью обычных методов отладки потоков Java ( 1 2).
Активатор, которым вы поделились, никогда не должен блокироваться в методе stop. Поэтому я сомневаюсь, что это может вызвать поведение, которое вы описали.