2010-03-17 13 views
5

Java EE için oldukça yeniyim, bu aptalca olabilir .. benimle ayırabilirsin: DBir Oturum Bean bir Mesaj Driven Bean içine nasıl enjekte edilir?

Mesaja dayalı bir fasülye vatansız bir oturum fasulyesi enjekte etmek istiyorum. Temel olarak, MDB bir JMS iletisi alır, sonra işi gerçekleştirmek için bir oturum fasulyesi kullanır. Oturum fasulye iş mantığını tutar.

İşte benim Oturum Bean var:

@Stateless 
public class TestBean implements TestBeanRemote { 

    public void doSomething() { 
    // business logic goes here 
    } 
} 

eşleştirme arayüzü:

@Remote 
public interface TestBeanRemote { 

    public void doSomething(); 
} 

İşte benim MDB var:

@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(); 
    } 
} 

Şimdiye kadar, değil roket bilimi doğru?

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]]] 

Yani benim sorular şunlardır: Bu v3 glassfish dağıtma ve uygun JMS Kuyruğu bir mesaj gönderirken glassfish TestBean EJB bulamıyorsa o

yazık ki, ben hataları olsun

  • Bir oturum fasulyesinin başka bir fasülyeye (özellikle mesaj yönlendirmeli bir fasülye) enjekte edilmesi için doğru yol bu mu?
  • Neden adlandırma araması başarısız oluyor?

cevap

3

Tamam, ben ek bilgi @LocalBean oturum Bean'e eklersem işe yarar. Ne ...

@Remote 
public interface TestBeanRemote { 

    public void doSomething(); 
} 

@Stateless(name="TestBeanRemote") 
public class TestBean implements TestBeanRemote { 

    public void doSomething() { 
    // business logic goes here 
    } 
} 

Sonra MDB:

+0

Şimdi biraz daha uzağım. @LocalBean, Arabirim içermeyen bir fasulyeyi tanımlar. Demek istediğim, istediğim bu değil: D – Hank

+0

"@EJB private TestBeanRemote testBean" kullanmış olmalısınız. – Dagvadorj

6

böyle şeyler tanımlamaya deneyebilir misiniz

@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(); 
    } 
} 

bu iş, ben bir açıklama :)

+0

Maalesef, bu da işe yaramıyor. Sanırım IoC hakkında öğrendiklerim ile gideceğim. Yine de teşekkürler! – Hank

+0

@Hank Weird, benim düşünmem gerektiğini. Kafam karıştı ... –

4
sağlamak çalışacağım Eğer

Sorunumun Kontrolün Tersine Çevirilmesi ile ilgili olduğu ve bilgi eksikliğimin ve Netbeans'in Sınıf/Arayüz adlarına yönelik önerilerinin neden olduğu görülüyor.

Bunu buldum - doğru fasülyeyi ve doğru arabirimi bulmak için - onları düzgün şekilde adlandırmalıyım.

@Remote 
public interface Test { 

    public void doSomething(); 
} 

@Stateless 
public class TestBean implements Test { 

    public void doSomething() { 
    // business logic goes here 
    } 
} 

Ve MDB ben 'Testi' değil 'TestBean' erişmek: İşte çalışır nedir ben ilk örneğinin sorun enjekte çalıştığınız olduğunu düşünüyorum

@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(); 
    } 
} 
+0

Adlandırma kuralları ile ilgili bulgularınız hakkında herhangi bir referans ekleyebilir misiniz? –

+1

Burada deneyin: http://java.sun.com/blueprints/code/namingconventions.html – Hank

+0

Tamam, şimdi bunu daha fazla anlamaya başlıyorum. Arayüzün @ Loal olması durumunda yukarıdaki örneğim doğru olur. Oturum bean'ını bir şeye enjekte ettiğimde 'ı enjekte ediyorum. Konteyner daha sonra uygulama sınıfını ( Bean) ve uygun arabirimi (@Local kullanımı için: veya Local, @Remote kullanımı için bulmaya çalışır: Remote adlandırın. Yani sorun JNDI değildi, adlandırma kurallarına uymuyordu! – Hank

6

EJB'nin uygulanması ve arabirimi değil. EJB 3.1'in yerel arayüzsüz görünümü, herhangi bir arabirim tanımlamıyorsanız, hatta uzak bir arabirim bile olmasa da mümkündür.Yani dışarı çalışmalıdır aşağıdaki enjeksiyon noktasını değiştirerek:

@EJB 
private TestBeanRemote testBean; 

olmayan bir kümelenmiş ortamında başvurunuzu kullanıyorsanız, bu nedenle tek JVM, sen @Local arayüzünü değiştirme hakkında düşünmek gerekir. Uzaktan arayüzlerini kullanarak EJB'lere erişir erişmez, çok fazla yüke maruz kalıyorsunuz. Parametreler ve geri dönüş değerlerine artık referans olarak erişilemez, ancak her zaman kopyalandıklarından değerle belirtilir (belirtim böyle yazılır). Bu, daha karmaşık nesnelerle uğraşırken performans sorunlarına yol açabilir.

Yardım etmeyi umuyordum.

İlgili konular