1

Spring ポートレットがほとんどない Web アプリケーションがあります。すべてのポートレットには、宣言されたコントローラを含む xml がありますが、コントローラによって使用されるサービスは applicationContext.xml に配置されます。すべてのポートレットに対して 1 つの Spring アプリケーション コンテキストが (独自の xml ファイルから) 作成され、そのすべてのコンテキストが applicationContext.xml から作成された Spring アプリケーション コンテキストをルート コンテキストとして持つことがわかっています。つまり、applicationContext.xml で宣言されたすべての Bean は、すべてのポートレットに共通です。

それでは、例を見てみましょう:

ポートレットの xml ファイルexample-portlet.xml : ... ...

コントローラExampleController.java :

package example.controller;
@Controller
@RequestMapping(value = "VIEW")
public class NavigareController {

@Autowired
private ExampleService es;
...
}

applicationContext.xml :

...
<context:component-scan base-package="example.service />
...

サービスExampleServiceImpl.java :

package example.service;
@Service
public class ExampleServiceImpl implements ExampleService {
...
}

サーバーがアプリケーション内で起動すると、アプリケーションが起動し、すべてが正常に機能します。アプリケーションが再デプロイされると、次のエラーが発生します。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleController'...
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private example.service.ExampleService...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [example.service.ExampleService]...

その結果、ポートレットは開始されません。

lifery のソースをデバッグしたところ、次のコードが見つかりました。

package org.springframework.web.portlet
...
public abstract class FrameworkPortlet extends GenericPortletBean
implements ApplicationListener<ContextRefreshedEvent> {
...
protected ApplicationContext initPortletApplicationContext() {
ApplicationContext parent = PortletApplicationContextUtils.getWebApplicationContext(getPortletContext());
ApplicationContext pac = createPortletApplicationContext(parent);
...

上記のコードは、最初のケース (サーバーが内部でアプリケーションを開始する場合) では null の親を返しませんが、2 番目のケース (アプリケーションが再デプロイされる場合) では null の親を返します。PortletApplicationContextUtils.getWebApplicationContext(getPortletContext()) 内には、次のコードがあります。

Object attr = pc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

したがって、最初のケースではこの属性はポートレット コンテキストにありますが、2 番目のケースではポートレット コンテキストにはありません。問題は明らかです。exampleService Bean が null の親で見つかりません。

問題は、ホット デプロイメント プロセスにバグがあるかどうかです。. 私を助けてください!!!

4

1 に答える 1

2

Liferay のバージョンは何ですか? 6.1.1 の場合、これは既知の問題です。

http://issues.liferay.com/browse/LPS-29103

ポートレットを 1 回だけデプロイする必要がある場合は、チケットで提案されているように、web.xml 内のリスナーの順序を手動で変更します。

ポートレットを大量に (開発のために) 再デプロイする必要がある場合、以前のソリューションは非常に時間がかかります。最も簡単な方法は、6.2.0 ブランチから修正をバックポートすることです。

于 2012-10-02T05:48:08.913 に答える