Модуль Liferay (комплект OSGi) остается в режиме "Остановка"

Иногда, когда я останавливаю свой модуль Liferay (например, когда я помещаю новую версию его JAR в deploy/) модуль отказывается останавливаться.

Пока модуль должен перейти в состояние "Разрешено", он всегда остается в состоянии "Остановка":

Жизненный цикл OSGi

Обычно это происходит из-за того, что поток где-то не завершен или сетевое соединение не закрыто должным образом, и часто бывает трудно исследовать это.

Мой вопрос: как эффективнее узнать, в чем проблема этого модуля 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. Поэтому я сомневаюсь, что это может вызвать поведение, которое вы описали.

Другие вопросы по тегам