메시지 구동 콩에 세션 콩을 주입하는 방법은 무엇입니까?
-
20-09-2019 - |
문제
나는 Java ee에 합리적으로 새로운 것이므로 이것은 바보 일 수 있습니다 .. 나와 함께 곰 pls : D
무국적 세션 콩을 메시지 구동 콩에 주입하고 싶습니다. 기본적으로 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]]]
그래서 내 질문은 다음과 같습니다.
- 이것이 세션 콩을 다른 콩에 주입하는 올바른 방법 (특히 메시지 구동 콩)입니까?
- 명명 조회가 실패한 이유는 무엇입니까?
해결책 4
좋아, @localbean @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의 구현을 주입하려고한다는 것입니다. EJB 3.1의 로컬 인터페이스보기는 원격 인터페이스가 아니라 인터페이스를 정의하지 않으면 가능합니다. 따라서 주입 지점을 다음으로 변경해야합니다.
@EJB
private TestBeanRemote testBean;
클러스터되지 않은 환경에서 응용 프로그램을 사용하는 경우 단일 JVM이면 인터페이스를 @local로 변경하는 것에 대해 생각해야합니다. 원격 인터페이스를 사용하여 EJB에 액세스하자마자 많은 오버 헤드를 얻게됩니다. 매개 변수와 반환 값은 더 이상 참조별로 액세스 할 수 없지만 항상 복사되므로 값으로 액세스 할 수 있습니다 (사양은 그렇게합니다). 이로 인해 더 복잡한 물체를 다룰 때 수행 문제가 발생할 수 있습니다.
그것이 도움이 되었기를 바랐습니다.
내 문제는 통제의 역전과 관련이 있고 수업/인터페이스 이름에 대한 지식 부족과 Netbeans의 제안으로 인한 것 같습니다.
나는 오른쪽 콩과 올바른 인터페이스를 찾기 위해 올바르게 이름을 지정해야한다는 것을 알았습니다. 다음은 효과가 있습니다.
@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();
}
}