Liferay 模块(OSGi 包)保留在 "Stopping"

标签 liferay osgi liferay-7 jstack gogo-shell

有时,当我停止 Liferay 模块时(例如,当我将其 JAR 的新版本放入 deploy/ 时),该模块拒绝停止。

虽然模块应该进入“已解决”状态,但它永远保持在“停止”状态:

OSGi lifecycle

通常是由于线程未在某处终止,或者网络连接未正确关闭,调查起来通常很痛苦。

我的问题:如何更有效地找出这个Liferay模块的问题是什么?

我尝试过的:

  • 在 Gogo Shell 中 diag <module id>似乎没有提供任何关于模块为何拒绝离开“停止”状态的有值(value)的信息。
  • jstack输出数千行,其中绝大多数位于所讨论的 Liferay 模块之外。如果有一种方法可以仅显示我的模块的 jstack 信息,那就太好了。

最佳答案

首先,找到您的 web 应用服务器的 PID:

ps aux | grep tomcat

如果您正在运行 Tomcat 以外的其他服务器,或者您有多个实例正在运行,请调整该命令。

然后,将该服务器的所有线程转储到文件中:

jstack 12345 > jstack.txt

其中 12345 是您在第一步中找到的 PID。

然后,查看 bundle 的源代码,并找到服务激活器。它通常看起来像这样:

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 )。

关于Liferay 模块(OSGi 包)保留在 "Stopping",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45431762/

相关文章:

liferay - 如何在 Liferay 中集成 Google Docs 文档?

liferay - 使用 jspf 钩子(Hook)定制 LifeRay portlet

java - OSGI 包的命令行参数和 JVM 参数

eclipse - "Export-Package: ."是什么意思?

liferay - 如何从 Liferay 7.4 中的 ddmfieldattribute 表中获取 SmallAttributeValue 字段?

liferay - 无法更新 ID 为 y 的包 : x. jar。 bundle 已卸载

liferay - 我怎样才能找到——在 Liferay 6.1 的哪些页面上部署了哪些 portlet?

tomcat - 将tomcat session 超时与已部署的应用程序同步

java - 创建需要用户参数的 OSGI 服务

maven - 如何从 Liferay 7 取消部署 portlet?