Special message to the visitors

In this area you can put any information you would like, such as: special offers, corporate motos, greeting message to the visitors or the business phone number.

This theme comes with detailed instructions on how to customize this area. You can also remove it completely.

Altı Kurşunlu Rus Ruleti

Archive for 'programming'

In this post, I covered basic integration of Flex and Spring JMS; summarized the flow of process in general.

Firstly I should explain the technology stack and what I want to do.

1- I need a RIA technology to push data from server to the client. Because I do not want to ask the server periodically if he has something new for him. This is an old-fashioned bullshit. So I will use Flex for user interface.

2- On server side, I want to process the requests asynchronously not to lock the user interface during the process. So, I need the “fire and forget” methodology of the JMS(Java Messaging Service) API. At this point I should emphasize that JMS is just an API to standardize the messaging services. There are plenty of implementations of JMS. I have chosen ActiveMQ because it has a support for:

  • virtual destinations to lower the number of required connections to message broker.
  • message persistance,
  • consumer priority,
  • message grouping,
  • different protocols like TCP,NIO to achieve the message broker and even an embedded one…

3- I want to do a professional job. What does it mean? I really really demand just to do my business and not to struggle with initilization and lifecycle management of the objects and decouple the modules to be able to plug them out when I found a more interesting and “new good-boy of the town” technology. Thus, I used Spring. Spring will initialize my objects, kill them when they are done. All I will do is to order what I want in the application context xml. Spring will do the job. Thanks Spring, love you, call me, my number is five oh five, oh sorry =)

4- The hard part, integrating the client and server side. That means, when client requests something, I need to solve it, send it to the server, the JMS destination, then take the message back and push it to the clients back. Ouucch? Shall I do this all by myself? Dont worry my friend, you will never walk alone. Spring-BlazeDS Integration will handle this all. You will just configure them. You are the boss, the king, the lord… Sorry, I am hooked on my words again. Somebody stop me:)

Well, lets do the job. Because words are cheap, time is too expensive. OK.

The diagram summarizes what we will do. Please look at it and if you are experienced correct me. There may be some misunderstanding of me. Care it, I really worked hard on it. Just for you man, just for you.


SBI-JMS-Flex

On client side, we will use the messaging API of Flex. It has consumers and producers. Producers generate a message and send it to post office called destination. The consumers subscribe to this destination. And wait for it, the clients the consumers that are subscribed to this destination are pushed this message. Wait wait wait… Pushed? Yeaah. Wow… But who do this magic, man? Blaze DS… Thanks to god, -or Adobe- there is this service that pushes the message to the desired consumers back. This is legendary, really.

The magic of the Blaze DS is the message broker. It finds the subscribers that are subscribed to the destination and push the message to them. Consumers do what they want with it. In our project BlazeDS runs on the server-side and it is managed by Spring. So lets first create our Flex mini project and then send our message to the BlazeDS message broker:

		

	
	
	
	

		
		
	
	


		

You see the consumer and producer definitions on line 2 and 3. We gave the same destination parameter to both of them. (This destination is in the ActiveMQ domain, the leftmost object in the diagram) Same client will produce a message and read it back after BlazeDS message broker push it back.

In diagram, you see the AMF channel. It is basically a channel that passes an actionscript object. It has an efficient format to carry the objects -much better than transporting them as XML-

On this AMF channel we transport our actionscript object message to the BlazeDS. So we define two AMF channels and set the channelset of the producer and consumer to this channel set. On the server hand of the channel the message is converted to a Java object and will be sent to the JMS destination. How? We will see it.

I say “message” repeated times. What the hack is that? As you can see, it is the AsyncMessage object. I will not dive into the details of the client side code more.

Going by step by step, everything will be clear. In this step, from Flex side we will request to the web context. And via a servlet request dispatcher, we direct this request to the Spring context. So lets define our dispatcher servlet:

 <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
 
    <!-- Map all *.spring requests to the DispatcherServlet for handling -->
    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/spring/*</url-pattern>
    </servlet-mapping>

Ok, we will redirect a request that has a “spring” part to the Spring context. So

http://{HOST}/{PROJECT_NAME}/spring/…

such a request will be redirected to the Spring context. After that, this request should be sent to the AMF channel endpoint. For this, the channel should be configured properly in the Spring context. Remember, we need the “spring” part, then we expand our URI such a way that it consists the channel endpoint part.

I configured the channel part like this:

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
            <endpoint url="{HOST}/{PROJECT_NAME}/spring/amf" 
 
class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>

So, the request “{HOST}/{PROJECT_NAME}/spring/amf” will be dispatched to the Spring context first and then the AMF channel endpoint.

Now, we are going on following the diagram. The labeled as 3 parts are in BlazeDS domain. BlazeDS has a HTTPFlexSession that controls the flex session and a listener that listens the AMFChannelEndpoint for new messages. We define it in the web.xml as:

<listener>
        <listener-class>flex.messaging.HttpFlexSession</listener-class>
</listener>

This listener waits for a message and pass it through the message broker. Between two of them, an interceptor may be allocated. This interceptor may be managed by the Spring. So this interceptor may be registered as a bean in the Spring context:

<flex:message-broker>
        <flex:message-interceptor ref="interceptor"/>
</flex:message-broker>
<bean id="interceptor" class="PaperUpdateMessageProcessor"/>

Here, PaperUpdateMessageProcessor implements org.springframework.flex.core.MessageInterceptor.

As you can see in the diagram, the message coming from the interceptor is pushed to the JMS destination by messagebroker. But while transporting an adapter function should be invoked. This adapter for the MessageService integrates Flex messaging with Java Message Service destinations and configured in the messaging-config.xml with “jms” id:

<adapters>
        <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
        <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/>
</adapters>

Maven Projesine Internal Bir Proje Eklemek

Maven, dependencyleri repositoryler üzerinden edinmek için kullanılıyor.

Büyük ihtimalle yanlış bir şey yapıyorum ama,

Projemdeki entityleri ayrı bir proje olarak tutup jar olarak eklediğim için Maven’a geçişimden sonra bir dependency olarak gösteriyorum:

Dependency’nin scope’unun system olması önemli. Bunu sistem olarak ekledikten sonra yolunu gösteriyorum.

(Büyük ihtimalle bunu local repository’e eklemenin çok daha profesyonel bir yolu olmalı. Araştıracağım. Zira bu blog kimseye bir şey öğretmek için yazılmıyor. Sadece ileride hangi yollardan geçtiğimi görmek, yanlışlarımı gözüme sokmak, kafama çarpmak için tutuluyor. O yüzden bu yolu bulduğum zaman bu postu da güncelleyeceğim. Bence hepiniz seksi insanlarsınız. Bunun kıymetini bilin.)


            paperify
            entities
            1.0.0
            system
            D:\NetBeansProjects\entities\dist\entities.jar

EAR içerisinde local dosyaları okumak

Normal bir web projesinde iş kolay. Web Content ya da WEB-INF altına istediğimiz dosyayı koyup ona erişebiliyoruz.

EAR projesinde ise;

File f = new File("talha.xml")

dediğimiz zaman application server’ın root’una düşüyoruz. Sittinsene ulaşamayız o dosyaya artık. Bu yüzden önce classloadera erişmemiz ve bunun üzerinde kaynaklara erişmemiz gerekiyor. Bunun için EAR projesinin altındaki web projesindeki(WAR) bir servletin içinde önce class loader’a erişiyoruz ve sonra buradan istediğimiz kaynağı çekiyoruz.

URL url = this.getClass().getClassLoader().getResource("WEB-INF/LimangoExample.xml");

getClassLoader() dediğimiz anda nereye düştüğümüzü görmek için:

this.getClass().getClassLoader().getResource(".")

‘i kullanabiliriz. Bu URL, EAR içindeki WAR projesinin kök dizinini veriyor. getResource içerisinde de istediğimiz dizine gidiyoruz.

Artık bu saatten sonra normal URL okur gibi okuyabiliriz dosyayı:

StringBuffer buffer = new StringBuffer();
BufferedReader in = new BufferedReader(
new InputStreamReader(
url.openStream()));
String inputLine;

while ((inputLine = in.readLine()) != null) {
buffer.append(inputLine);
}
in.close();

Dosyamız XML ise ve işleri biraz kolaylaştırmak istiyorsak JAXB’nin unmarshaller’ını kullanabiliriz okumak için.

HTTPClient apache commons codec’e bağımlı.

Projenin içerisine bunu koysan bile Glassfish’de runtime’da bu hatayı alıyorsun.

Almamak için domain library’nin altına da codec kütüphanesini koymalısın. Hayırlı olsun.

 Ufak bir hatırlatma: JPA’da;

EntityManager -> PersistenceContext’e

EntityManagerFactory ise Persistence Unit’e tekabül ediyor.

Glassfish’de bir entity manager elde etmek için yönetim konsolundan;

1-  Önce bir JDBC pool tanımlıyoruz.

2- Daha sonra bu JDBC pool üzerinde bir data source tanımlıyoruz. Bu data source’u JNDI’a hangi isimle bağlayacağımızı da bu ekranda belirliyoruz.

3- Projemiz içerisinde bir persistence unit oluşturuyoruz:

<persistence version=”1.0″ xmlns=”http://java.sun.com/xml/ns/persistence” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd“>
  <persistence-unit name=”WebApplication1PU” transaction-type=”JTA”>
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>webservice_JDBC_Source</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
    </properties>
  </persistence-unit>
</persistence>

Bu persistence ayarlarında transaction-type’ın JTA olduğuna dikkat edelim. Çünkü Java EE applicationlarında JTA kullanmak iyi bir pratik ki GlassFish zaten bunu zorunlu tutuyor.

Daha sonra <jta-data-source> node’unda kullanacağımız data source’un JNDI ismini belirtiyoruz.

Artık JNDI’a bağlı bir datasource’umuz var ve projemizin persistence ayarlarını bu data source’u kullanacak şekilde yapmış durumdayız. Sıra, bunu projemiz içerisinde kullanmakta…Bunun için;

1- web.xml’de bir persistence context refererence node’u oluşturuyoruz:

<persistence-context-ref>
<persistence-context-ref-name>persistence/WebApplication1PU</persistence-context-ref-name>
<persistence-unit-name>WebApplication1PU</persistence-unit-name>
</persistence-context-ref>

Burada persistence-context-ref-name logical (mantıksal) bir isim ve bu yüzden, aynı isimde fiziksel bir dosya falan olmasına gerek yok. Sadece çağırırken bu isimle çağıracağız.

persistence-unit-name ise fiziksel bir isim ve persistence.xml’deki ile aynı olmak zorunda.

Artık projemiz içerisinde JNDI’a lookup yapabiliriz. Data source’lar “java:comp/env/”  adresinde ikamet ediyor JNDI üzerinde.

EntityManager em = (EntityManager)new InitialContext().lookup(”java:comp/env/” + “persistence/WebApplication1PU“);

ile entity manager’ı elde etmiş durumdayız.

Hayırlı olsun.

Çok fenadır. Sunucumuzu çalıştırdık, admin paneline girip JDBC source tanımlamak istiyoruz ne bileyim, JNDI’a bağlı nelerimiz var bakmak istiyoruz, gaza gelmişiz, heyecanlıyız. O da ne… Yönetim konsoluna giremiyoruz.

Öncelikle Sun’a yazıklar olsun diyorum ve sebebini anlatmaya başlıyorum.

Bu, tipik bir character encoding sorunu. Koskoca Sun locale’i en_US olmayan bir JVM gördüğü zaman kendinden geçiyor ve paneli başlatamıyor. Bu yüzden ona istediğini verip kurtuluyoruz.

{Glassfish’in kurulu olduğu klasör} / domains / {domain adı }/ config / klasörüne gidiyoruz. domain.xml’de JVM ayarlarının olduğu kısmın sonuna bir jvm argümanı daha ekliyoruz:

-Duser.language=en_US

Hayırlı olsun. Bu arada Sun, ben sana server yazamazsın demedim. Düzeltin olm şunu. :)