Merhabalar arkadaşlar. Persistence konusunu işlediğimiz önceki yazımızın ardından bu yazımızda Message Driven Beans konusunu öğreneceğiz.
Message Driven Bean’ler de önceki yazıalrda gördüğümüz Session Bean’ler ve Entity Bean’ler gibi bir Enterprise Java Bean çeşididir. Görevi asenkron bir şekilde bir görevi yerine getirmektir. Örneğin siz bir işiniz için birisine mail attığınızda karşı tarafın anında okuması ve cevap vermesi çoğu zaman mümkün değildir. Bu nedenle mail sistemi asenkron bir yapı üzerinde yürür. İşte Message Driven Bean’ler de böyle bir şekilde yani asenkron bir şekilde işlemleri gerçekleştirirler.
Bu yazıda yapacağımız örnek Glassfish Uygulama Sunucusunu kullanacağımız için ayarlamalarımız da ona göre olacak. Şimdi adımlarınızın ne olması gerektiğine ve örnek uygulamamıza bakalım.
- İlk olarak IDE’nin içinden ya da terminal (ya da cmd) üzerinden GlassFiash sunucunuzu başlatın ve localhost:4848 adresine gidin.
- Açılan sayfada sol menüden Resources sekmesine tıklayın.
- Resources altında açılan menüden JMS (Java Message Service) Resources sekmesine tıklayın.
- Karşınıza Connection Factories ve Destination Resources adında iki link çıkacak. Önce Connection Factories’e tıklayın ve New butonu ile yeni bir Connection Factory oluşturun. Connection Factory oluştururken JNDI Name kısmını istediğiniz bir şey verebilirsiniz fakat Resource Type kısmına bu örnek için dikkat etmelisiniz. Bu örnekte javax.jms.QueueConnectionFactory öğesini seçmeniz gerekiyor.
- Daha sonra bir Destination Resource bir oluşturmanız gerekiyor. Önceki sayfadan Destination Resource linkine akabinde New butonuna tıklayıp yeni bir JMS Destination Resource oluşturun. Açılan saydaki textBoxlara dolduracağınız bilgiler yine size kalmış ancak Resource Type kısmından javax.jms.Queue seçin bu örnek için.
- Ayrı ayrı her iki işlem için de sağ üstteki OK butonu ile kayıt işlemini tamamlayın. Şimdi kod kısmına geçelim. Benim oluşturduğum Connection Factory ve Destination Resource şu şekilde:
IDE’nizde bir JSF projesi açtıktan sonra Source Packages altında bir paket oluşturup ona sağ tıklayın ve New kısmından Message-Driven Bean’i seçin. Eğer göremezseniz Other kısmına tıklayıp Enterprise JavaBeans menüsünden seçebilirsiniz. Aşağıdaki resime ve altyazısına dikkat edeniz.

Message-Driven Bean’i oluştururken Destinations kısmına dikkat etmemiz gerekiyor. Biz az önce Glassfish sunucusu içinde oluşturduğumuz Destination Resource’u kullanacağız. Bunun için Server Destinations radio butonunu işaretleyip içinden sunucu içinde tanımadığımız öğeyi seçiyoruz. Altta görünen kırmızı hata sınıfın zaten mevcut olmasından kaynaklanıyor.
Daha sonra Next butonuna tıklayıp akabinde de Finish butonuna tıklayarak işlemimizi bitirebiliriz. Şimdi bu ve diğer sınıflardaki kodlarımızı inceleyelim.
MessageDrivenBeanClass.java
package com.ilkgunel.messagedriven; import javax.ejb.ActivationConfigProperty; import javax.ejb.EJB; import javax.ejb.MessageDriven; import javax.jms.Message; import javax.jms.MessageListener; import com.ilkgunel.interfaces.EJBRemoteInterface; import java.io.Serializable; import javax.jms.JMSException; import javax.jms.ObjectMessage; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/BlogProjesi"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class MessageDrivenBeanClass implements MessageListener,Serializable{ public MessageDrivenBeanClass() { } @EJB EJBRemoteInterface EJBRemoteInterface; @Override public void onMessage(Message message) { try { ObjectMessage objectMessage = (ObjectMessage) message; String receivedMessage = (String) objectMessage.getObject(); EJBRemoteInterface.writeMessageToConsole(receivedMessage); } catch (JMSException e) { System.err.println("An Error Is Occured!"+e); } } }
Bir Java sınıfının Message-Driven Bean özelliği kazanabilmesi için @MessageDriven notasyonu ile sınıf işaretleniyor. Bu notasyona @ActivationConfigProperty notasyonu ile 2 parametre veriyoruz. @ActivationConfigProperty notasyonu da propertyName ve propertyValue adında iki parametre alıyor. Bu parametreler Sunucu içinde tanımladığımız Destination Resource’un Java koduna tanıtılması yapılıyor burada.
@EJB notasyonu ile EJB Interface’i implement sınıftaki metodu çağıracağız. Önceki derslerden hatırlayacağınız gibi direk EJB sınıfını değil EJB Interface’i kullanıyoruz.
Bu yazımız içinde bel kemiği özelliği taşıyan kısım ise onMessage metodur. Dışarıdan bir mesaj işlemi tetiklenmesi durumunda devreye girecek olan metot onMessage metodur. onMessage metodunu MessageListener arabirimini(interface) implement ettiğimiz için override ettik.Metot içinde öncelikle işlemler sırasında bir hata meydana gelmemesi için Message tipinde gelen parametreyi ObjectMessage tipinde elde ediyoruz. Daha sonra da String tipinde elde ediyoruz. Elde ettiğimiz String’i EJB sınıfındaki metodumuza yolluyoruz.
EJBRemoteInterface.java
package com.ilkgunel.interfaces; import javax.ejb.Remote; @Remote public interface EJBRemoteInterface { public void writeMessageToConsole(String message); }
Interface’imiz içinde iş yapacak metodumuzu tanımlıyoruz.
EJBClass.java
package com.ilkgunel.ejbClasses; import javax.ejb.Stateless; import com.ilkgunel.interfaces.EJBRemoteInterface; import java.io.Serializable; @Stateless public class EJBClass implements EJBRemoteInterface,Serializable{ @Override public void writeMessageToConsole(String message) { try { System.out.println("Message is:"+message); } catch (Exception e) { System.err.println("An Error Occured!\nError is:"+e); } } }
Interface içinde tanımadığımız metodun EJB sınıfı içinde gövdesini yazıyoruz.
JSFManagedBean.java
package com.ilkgunel.jsfbean; import java.io.Serializable; import javax.annotation.Resource; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.MessageProducer; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.Session; @ManagedBean @RequestScoped public class JSFManagedBeanClass implements Serializable{ @Resource(lookup = "jms/BlogProjesiFactory") private ConnectionFactory connectionFactoryObject; @Resource(lookup = "jms/BlogProjesi") private Queue queueObject; String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String sendMessage() { Connection con=null; try { con=connectionFactoryObject.createConnection(); Session session=con.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer producer=session.createProducer(queueObject); ObjectMessage msg=session.createObjectMessage(); msg.setObject(message); producer.send(msg); } catch (JMSException e) { System.out.println("Bir Hata Meydana Geldi.\n Hata:"+e); } finally { try { con.close(); } catch (Exception e) { System.err.println(e); } } return ""; } }
Managed Bean sınıfımız içinde MessageDrivenBeanClass sınıfı içinde yazdığımız onMessage metodunun çağırılma işleminin nasıl yapıldığını göreceğiz.
İlk olarak @Resource notasyonları ile ConnectionFactory ve Queue nesneleri tanımlıyoruz. Bu nesneleri tanımlarken notasyonlara birer lookup parametresi veriyoruz. Parametreler gördüğünüz üzere sunucu içinde tanımadığımız Connection Factory ve Destination Resource.
Kullanıcının gireceği mesajı tutacak bir message nesnesi ve bu nesnenin get-set metotlarını tanımlıyoruz.
- onMessage metodunu çağırma işleminin yapıalcağı sendMessage metodunun içinde, try-catch bloğunun içinde javax.jms.Connection tipinde bir nesneyi connectionFactoryObject nesnesini ve createConnection metodunu kullanarak oluşturuyoruz.
- Akabinde oluşturduğumuz con nesnesini kullanarak bir Session nesnesi oluşturuyoruz. createSession metodunu kullanırken iki parametre veriyoruz. Parametrelerin görevi temel olarak mesajın nasıl iletileceğini belirlemek. Eğer birinci parametre true olursa ikinci parametre ihmal ediliyor ve local bir transaction mekanizması devreye giriyor. Oraacle’daki dökümantasyona göre bu tavsiye edilen bir durum değil. Tavsiye edilen durum birinci parametreyi false, ikinci parametreyi Session.AUTO_ACKNOWLEDGE olarak vermek. Böylece mesaj alımı bir otomatik mekanizmaya alınmış oluyor. Mesaj iletim talebi geldiğinde mesaj otomatik iletilmiş oluyor.
- Sonraki adımda mesaj iletiminde kullanacağımız MessageProducer nesnesini session nesnesini ve createProduces metodunu kullanarak oluşturuyoruz. Metoda parametre olarak Queue nesnesini veriyoruz.
- Daha sonra gönderilecek mesajı koyacağımız bir ObjectMessage nesnesini session.createObjectMessage(); ifadesini kullanarak oluşturuyor ve setObject ile mesajı ObjectMessage nesnesine koyuyoruz.
- Son olarak producer.send(msg) ifadesi ile mesajımızı Message-Driven Bean’e ulaştırmış oluşturuyoruz.
- catch lie hata yakalaması ve finally lie Connection nesnesinin kapatılma işlemlerini gerçekleştiriyoruz.
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Facelet Title</title> </h:head> <h:body> <h:form> <h:inputText value="#{jSFManagedBeanClass.message}"/> <h:commandButton value="GÖNDER" action="#{jSFManagedBeanClass.sendMessage()}"/> </h:form> </h:body> </html>
Index kodumuz içinde bir inputText ile kullanıcıdan mesajı alıyoruz ve butonun action özelliği sayesinde sendMessage metodunu çağırıyoruz.
Ekran Çıktıları

Mesaj başarılı bir şekilde Message-Driven Bean’den geçti ve EJB sınıfına ulaştı. Ardından ekrana yazdırıldı.
Bu yazıda da bu kadar arkadaşlar. EJB teknolojisi içinde Message-Driven Bean’in kullanımını öğrenmiş olduk. Gelecek yazıda görüşmek üzere sağlıcakla kalın.
Gerçekten çok teşekkür ederim sayenizde EJB, JNDI, WildFly[ActiveMQ](kullanımını) öğrenmiş oldum.EJB konusu için hangi makaleyi ya da kitabı açsam ilk olarak “EJB’ler Java’nın en karmaşık teknolojilerindendir” diye başlıyorlar zaten o cümleyi okuduktan sonra konuyu anlayabilmek imkansız ama siz o kadar basitleştirmişsiniz ki; bana Spring Framework’tan daha kolay geldi.