我目前正在使用tomcat开发Liferay 7.1.2.ga3 CE,并在官方文档中复习教程的OSGI部分。这个:Docs
我决定尝试一个尽可能简单的项目。我在IntelliJ的想法中创建了一个Liferay工作区,并添加了一些组件,如图中所述。
问题是它要么不注入,要么注入但不检索dependency,因为在这种情况下,在使用者中_applicationServices变量始终为null。
编辑: 我在Liferay官方论坛上问了同样的问题:Liferay.org 中的问题
这是代码:
api:
@ProviderType
public interface ApplicationServices {
String getSearchFiltersForRegister(String registerCode);
}
提供商:
@Component(
immediate = true,
property = {
},
service = ApplicationServices.class
)
public class ApplicationServicesImpl implements ApplicationServices {
@Override
public String getSearchFiltersForRegister(String registerCode) {
return "OSGI modularity made service";
}
}
消费者:
@ManagedBean(name = "registerSearchBean")
@ViewScoped
@Component(
immediate = true,
property = {
"osgi.command.scope=getSearchFiltersForRegister",
"osgi.command.function=getSearchFiltersForRegister"
},
service = Object.class
)
public class RegisterSearchBean {
public String message;
@Reference
private ApplicationServices _applicationServices;
@PostConstruct
public void initBean(){
getSearchFiltersForRegister();
}
public void getSearchFiltersForRegister(){
ApplicationServices applicationServices=_applicationServices;
message=applicationServices.getSearchFiltersForRegister("asd");
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
注意:我还试图将consumre模块分离到另一个类中,并在这个bean中使用它,但没有成功。
其他信息:
- 该项目是一个渐变的LiferayWorkaspace
- Api和服务模块是通过模块文件夹
- JSF模块是通过带有gradle的maven原型生成的"war"文件夹中的支持
- Dependencies已正确定义,并且已在中正确部署Liferay服务器。至少看起来是这样……部署时不会出现丢失类的错误
我做错了什么?为什么应用程序服务总是为空
Neil Griffin在救生论坛上广泛回答:
嗨,Georgi,非常感谢您的联系。你问了一个非常重要的问题这个问题值得彻底回答。既然JSF是一种技术基于JavaEE,它希望该项目是一个Web应用程序ARchive(WAR)而不是Java ARchive。当战争部署到$LIFERAY_HOME/deploy,LIFERAY将自动转换Java EE WAR到OSGi Web应用程序捆绑包(WAemoticon。尽管WAB是一流的OSGi公民,但他们并不参与在构建时,通过用注释的类发现服务@组件。更自然地适合WAB的是CDI,它实现了通过扫描类路径部署服务的时间发现。所以粘贴的代码的困难在于:您正在组合OSGi声明服务构建时发现(通过@Component)CDI部署时间发现(通过@ViewScoped)。这些需要用于一种相互排斥的方式——换句话说,它们不可能组合。以下是令人鼓舞的消息——Liferay 7.1、7.2和7.3船带有weld-osgi-bundle.jar的$LIFERAY_HOME/模块,并完全支持Portlet3.0通过OSGiCDI集成的CDI需求。这意味着可以按顺序开发使用JSR330@Inject的WAR将OSGi服务注册表中的服务注入CDIBean。它还可以将CDIBean发布到OSGi服务中注册中心。我最近在Liferay DEVCON 2019上做了一个题为Portlet的演讲3.0 MVCBean和PortletMVC4Spring,展示了OSGiCDI集成的前景。如果你有时间,我建议你看演示,因为它应该帮助你更好地了解如何所有作品。但我很抱歉地说JSF不能承受这方面的优势。我们仍在努力实施JSR378,这使得在Liferay as a Portlet 3.0";bean portlet"——这就是启用所有OSGiCDI集成功能。我们让它发挥作用在liferay-faces-bridge-impl.git存储库的5.x分支中,但是在JSR378完成之前,将无法削减生产版本。所以除非你想试用5.x版本的桥接器,否则我建议您遵循我的DEVCON 2016中的建议题为"着眼于未来开发WAB"的演示我描述了如何使用ServiceTracker来获取服务从WAR portlet中的OSGi服务注册表JSF需要。话虽如此,这可能是一个好主意您可以在中使用@Component(Declarative services)开发OSGi服务JAR模块。JAR模块可以与JSF分开部署portlet WAR模块。这样,您应该能够获得通过JSR管理的bean中的ServiceTracker。最终,一旦我们发布JSR378,您将能够使用JSR330@Inject而不是ServiceTracker,以便将OSGi服务注入JSF托管bean(由CDI通过@javax.faces.view.ViewScoped管理)为了再次澄清,在将来,您可能希望使用CDI@ViewScoped注释的兼容版本,而不是用于JSF Managed Bean Facility(MBF)@javax.faces.bean.ViewScopedKind Regards,Neil