如果我引用服务,Gogo Shell 命令会消失
Gogo Shell command disappears if I reference service
源代码
在我的模块中,我写了这个 Liferay 服务:
package jp.co.my.module;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.module.framework.service.IdentifiableOSGiService;
import com.liferay.portal.kernel.service.BaseLocalServiceImpl;
public class TestService extends BaseLocalServiceImpl
implements IdentifiableOSGiService {
public void test() throws PortalException {
System.out.println("In the future I will do stuff here");
}
@Override
public String getOSGiServiceIdentifier() {
return TestService.class.getName();
}
}
在同一模块中,我编写了一个使用该服务的命令:
package jp.co.my.module;
import com.liferay.portal.kernel.exception.PortalException;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(
property = {
"osgi.command.function=test",
"osgi.command.scope=liferay"
},
service = Object.class)
public class TestCommand {
public void test() throws PortalException {
System.out.println("In the future I will call the service here");
}
@Reference private volatile TestService _testService;
}
问题
模块部署正确,但在 Gogo 中 Shell 命令不可用:
g! test
gogo: CommandNotFoundException: Command not found: test
g! b 1001
jp.co.my.module_1.0.0 [1001]
Id=1001, Status=ACTIVE Data Root=/home/nico/liferay/osgi/state/org.eclipse.osgi/1001/data
"No registered services."
Services in use:
{org.osgi.service.log.LogService, org.eclipse.equinox.log.ExtendedLogService}={service.id=2, service.bundleid=0, service.scope=bundle}
No exported packages
Imported packages
com.liferay.portal.kernel.exception; version="7.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.module.framework.service; version="1.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.service; version="1.27.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
No fragment bundles
No required bundles
但是! 如果我从 TestCommand.java
中删除 @Reference private volatile TestService _testService;
,它 工作完美:
g! test
In the future I will call the service here
g! b 1005
jp.co.my.module_1.0.0 [1005]
Id=1005, Status=ACTIVE Data Root=/home/nico/liferay/osgi/state/org.eclipse.osgi/1005/data
"Registered Services"
{java.lang.Object}={osgi.command.function=test, component.name=jp.co.my.module.TestCommand, component.id=2740, osgi.command.scope=liferay, service.id=7652, service.bundleid=1005, service.scope=bundle}
Services in use:
{org.osgi.service.log.LogService, org.eclipse.equinox.log.ExtendedLogService}={service.id=2, service.bundleid=0, service.scope=bundle}
No exported packages
Imported packages
com.liferay.portal.kernel.exception; version="7.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.module.framework.service; version="1.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.service; version="1.27.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
No fragment bundles
No required bundles
问题:这是为什么?如何正确引用服务?
我没有使用过 liferay,但它似乎非常接近 OSGI 概念。你的 TestCommand 是一个依赖于 TestService 的组件,因为你使用了@Reference。这意味着 TestService 也是一个组件。但是您还没有在任何地方将 TestService 定义为组件。
我有根据的猜测是 TestService 也必须使用 @Component,所以 liferay 会知道它是一个组件,创建它,并将它注入 TestCommand:
@Component
public class TestService extends BaseLocalServiceImpl
implements IdentifiableOSGiService {
尝试创建和引用未定义 java 接口的组件可能会出现其他问题,我不知道。
EDIT2:它在没有该行的情况下完美运行的原因是删除@Reference 删除了 TestCommand 和 TestService 之间断开的依赖关系 link。有了这条线,依赖链就在那里但没有解决,所以你的 TestCommand 不会启动
编辑 3:
@Component(
configurationPid = "jp.co.my.module",
immediate = true,
property = {},
service = TestService.class
)
源代码
在我的模块中,我写了这个 Liferay 服务:
package jp.co.my.module;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.module.framework.service.IdentifiableOSGiService;
import com.liferay.portal.kernel.service.BaseLocalServiceImpl;
public class TestService extends BaseLocalServiceImpl
implements IdentifiableOSGiService {
public void test() throws PortalException {
System.out.println("In the future I will do stuff here");
}
@Override
public String getOSGiServiceIdentifier() {
return TestService.class.getName();
}
}
在同一模块中,我编写了一个使用该服务的命令:
package jp.co.my.module;
import com.liferay.portal.kernel.exception.PortalException;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component(
property = {
"osgi.command.function=test",
"osgi.command.scope=liferay"
},
service = Object.class)
public class TestCommand {
public void test() throws PortalException {
System.out.println("In the future I will call the service here");
}
@Reference private volatile TestService _testService;
}
问题
模块部署正确,但在 Gogo 中 Shell 命令不可用:
g! test
gogo: CommandNotFoundException: Command not found: test
g! b 1001
jp.co.my.module_1.0.0 [1001]
Id=1001, Status=ACTIVE Data Root=/home/nico/liferay/osgi/state/org.eclipse.osgi/1001/data
"No registered services."
Services in use:
{org.osgi.service.log.LogService, org.eclipse.equinox.log.ExtendedLogService}={service.id=2, service.bundleid=0, service.scope=bundle}
No exported packages
Imported packages
com.liferay.portal.kernel.exception; version="7.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.module.framework.service; version="1.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.service; version="1.27.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
No fragment bundles
No required bundles
但是! 如果我从 TestCommand.java
中删除 @Reference private volatile TestService _testService;
,它 工作完美:
g! test
In the future I will call the service here
g! b 1005
jp.co.my.module_1.0.0 [1005]
Id=1005, Status=ACTIVE Data Root=/home/nico/liferay/osgi/state/org.eclipse.osgi/1005/data
"Registered Services"
{java.lang.Object}={osgi.command.function=test, component.name=jp.co.my.module.TestCommand, component.id=2740, osgi.command.scope=liferay, service.id=7652, service.bundleid=1005, service.scope=bundle}
Services in use:
{org.osgi.service.log.LogService, org.eclipse.equinox.log.ExtendedLogService}={service.id=2, service.bundleid=0, service.scope=bundle}
No exported packages
Imported packages
com.liferay.portal.kernel.exception; version="7.1.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.module.framework.service; version="1.0.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
com.liferay.portal.kernel.service; version="1.27.0" <org.eclipse.osgi_3.10.200.v20150831-0856 [0]>
No fragment bundles
No required bundles
问题:这是为什么?如何正确引用服务?
我没有使用过 liferay,但它似乎非常接近 OSGI 概念。你的 TestCommand 是一个依赖于 TestService 的组件,因为你使用了@Reference。这意味着 TestService 也是一个组件。但是您还没有在任何地方将 TestService 定义为组件。
我有根据的猜测是 TestService 也必须使用 @Component,所以 liferay 会知道它是一个组件,创建它,并将它注入 TestCommand:
@Component
public class TestService extends BaseLocalServiceImpl
implements IdentifiableOSGiService {
尝试创建和引用未定义 java 接口的组件可能会出现其他问题,我不知道。
EDIT2:它在没有该行的情况下完美运行的原因是删除@Reference 删除了 TestCommand 和 TestService 之间断开的依赖关系 link。有了这条线,依赖链就在那里但没有解决,所以你的 TestCommand 不会启动
编辑 3:
@Component(
configurationPid = "jp.co.my.module",
immediate = true,
property = {},
service = TestService.class
)