セッション Bean をメッセージ駆動型 Bean に注入するにはどうすればよいですか?
-
20-09-2019 - |
質問
私は Java EE についてはかなり初心者なので、これは愚かかもしれません。我慢してください:D
ステートレス セッション Bean をメッセージ駆動型 Bean に注入したいと考えています。基本的に、MDB は JMS メッセージを取得し、セッション Bean を使用して作業を実行します。セッション Bean はビジネス ロジックを保持します。
私のセッションBeanは次のとおりです。
@Stateless
public class TestBean implements TestBeanRemote {
public void doSomething() {
// business logic goes here
}
}
一致するインターフェイス:
@Remote
public interface TestBeanRemote {
public void doSomething();
}
私のMDBは次のとおりです。
@MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
@EJB
private TestBean testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}
今のところ、ロケット科学ではありませんね?
残念ながら、これを glassfish v3 にデプロイし、適切な JMS キューにメッセージを送信すると、glassfish が TestBean EJB を見つけられないというエラーが発生します。
java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/mvs.test.TestController/testBean' in SerialContext [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'mvs.test.TestBean#mvs.test.TestBean' [Root exception is javax.naming.NamingException: Lookup failed for 'mvs.test.TestBean#mvs.test.TestBean' in SerialContext [Root exception is javax.naming.NameNotFoundException: mvs.test.TestBean#mvs.test.TestBean not found]]]
そこで私の質問は次のとおりです。
- これはセッション Bean を別の Bean (特にメッセージ駆動型 Bean) に注入する正しい方法ですか?
- なぜ名前の検索が失敗するのでしょうか?
解決 4
[OK]を、私はセッションBeanに注釈@LocalBeanを追加する場合、それが動作することがわかりました。何...?
他のヒント
あなたはこのようなものを定義しようとすることができます:
@Remote
public interface TestBeanRemote {
public void doSomething();
}
@Stateless(name="TestBeanRemote")
public class TestBean implements TestBeanRemote {
public void doSomething() {
// business logic goes here
}
}
そして、MDBでます:
@MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
@EJB(beanName="TestBeanRemote")
private TestBeanRemote testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}
この作品ならば、私は説明を提供しようとするでしょう:)
私は非常に最初の例の問題は、あなたがそのインターフェースをEJBの実装を注入しようとしているとされていないということだと思います。あなたが任意のインターフェイスではなく、さらにリモート1を定義しない場合はEJB 3.1のローカル無インタフェースビューは単なる可能です。だから、次のように注入点を変更すると、うまくいかなければならない。
@EJB
private TestBeanRemote testBean;
あなたは、そう、単一のJVMを非クラスタ環境内のアプリケーションを使用している場合は、@Localにインターフェースの変更について考える必要があります。あなたは自分のリモートインタフェースを使用してEJBにアクセスしているとすぐに、あなたは多くのオーバーヘッドを得ています。パラメータと戻り値は、もはや参照によってアクセスすることはできませんが、値によって、彼らは常にコピーされる(仕様はそう言います)。より複雑なオブジェクトを扱う場合は、performenceの問題につながる可能性があります。
助けたことが望まます。
私の問題は、制御の反転に関連し、知識の私の不足とクラス/インタフェース名のNetBeansの提案によって引き起こされたと思われます。
右Beanと右のインターフェース見つけるために - - 私はそれらを適切に名前を付ける必要があります。私がいることが分かりました。ここではどのような作品です。
@Remote
public interface Test {
public void doSomething();
}
@Stateless
public class TestBean implements Test {
public void doSomething() {
// business logic goes here
}
}
そして、MDBに、私は 'テスト' にアクセスのないの 'TestBean':
@MessageDriven(mappedName = "jms/mvs.TestController", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class TestController implements MessageListener {
@EJB
private Test testBean;
public TestController() {
}
public void onMessage(Message message) {
testBean.doSomething();
}
}