2013-01-21 64 views
1

我正在使用帶有CDI的JBoss 7.1.1。JEE6:替代EJB聲明

我在JNDI中有一個名爲ServiceAccount的無狀態bean。這是真正的服務實施。 我有另一個名爲ServiceAccountMock的Statelss bean,它是一個模擬服務。 這兩個都從相同的接口herited,並打包在一個service.ear。

我想要做的是將mock服務聲明爲bean.xml中的替代方案,重新部署我的服務,然後所有客戶端都看到模擬版本(不更改客戶端上的任何內容)。

當我部署我service.ear,JBoss的說:

java.lang.IllegalArgumentException: JBAS011046: A component named 'ServiceAccount' is already defined in this module 

這是真實的,兩種服務都宣佈了同樣的方式(@Stateless(name = 「ServiceAccount」))。

如果我更改模擬版本的名稱,我必須在客戶端更改使用哪個EJB(並且我不想這樣做)。

有誰知道該怎麼做?

+0

在@Stateless註釋中爲替代無狀態EJB指定不同的名稱時,部署錯誤是否會消失? –

+0

@Reynols:是的。 – jmcollin92

回答

8

我不認爲你將能夠與在同一名稱部署2種豆同樣的應用。

如果bean的客戶端只是本地的,則應該使用CDI類型的注入選擇。

  • 如果你真的需要一個名字(這個模擬將有一個與真實實現不同的名字),刪除bean的名字或者輸入不同的名字。
  • 在模擬上保留@Alternative註釋。
  • 在注射點,使用接口作爲變量(也可能使用@Inject註釋代替@EJB一個可以幫助)的類型。

EJB規範和CDI還沒有完全對齊。 EJB有一些元素,如名稱,它們在應用程序中需要是唯一的,並且在CDI替代功能中沒有考慮到。

所以我不認爲你能夠混合EJB名稱注入選擇和CDI替代注入選擇。

+1

這也是我的結論。我實現的解決方法是擁有一個獨特的EJB Facade,其中注入了一個CDI的不同實現:對於客戶端EJB來說總是相同的,我可以將調用透明地路由到其他模擬Bean。 – jmcollin92

0

首先,您需要註釋ServiceAccountMock@Alternative,以告訴容器不使用它,如果沒有指示。

@Stateless(name="ServiceAccount") 
@Alternative 
public class ServiceAccountMock{ 
.... 
} 

然後在beans.xml你需要告訴A/S挑模擬實現:

... 
<alternatives> 
    <class>xx.yy.ServiceAccountMock</class> 
</alternatives> 
... 
+0

這已經完成了。但錯誤仍然存​​在。 – jmcollin92

+0

@ jmcollin92在這種情況下,我認爲一些代碼應該有所幫助。特別是「ServiceAccount」和「ServiceAccountMock」的類簽名。 –

+1

Thx爲您的答案。像上面的Kazaag一樣,我認爲這是不可能的。 CDI不處理JNDI:@Alternative不修改JNDI。我已經爲可能感興趣的人發佈了一個解決方法。 – jmcollin92