Liferay模块(OSGi包)保持“停止”

时间:2017-08-01 07:40:57

标签: liferay osgi liferay-7 jstack gogo-shell

有时当我停止Liferay模块时(例如当我在deploy/中放置新版本的JAR时)模块拒绝停止。

当模块进入“已解决”状态时,它将永远处于“停止”状态:

OSGi lifecycle

通常是由于某个线程没有在某个地方终止,或者网络连接没有正确关闭,而且通常很难进行调查。

我的问题:如何更有效地了解Liferay模块的问题是什么?

我尝试了什么:

  • 在Gogo Shell中diag <module id>似乎没有提供有关该模块拒绝离开“停止”状态的原因的任何有价值的信息。
  • jstack输出数千行,其中绝大多数都在Liferay模块之外。如果有办法只显示我的模块的jstack信息,那就太好了。

2 个答案:

答案 0 :(得分:1)

首先,找到您的webapp服务器的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.nrwServiceActivatorstop,并且从这三个中获取全名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)来解决它。

答案 1 :(得分:0)

您共享的Activator永远不会阻止stop方法。所以我怀疑它会导致你所描述的行为。