25 Nisan 2011 Pazartesi

Maven3 (Proje yönetim aracı)-6: Örnek Çok Modüllü Proje

Bu yazıda daha önce Maven3 (Proje yönetim aracı)-4: Örnek Proje(simple-weather) ve Maven3 (Proje yönetim aracı)-5: Örnek Web Projesi(simple-webapp) nde anlattığım örnek projeleri bir araya getirip çok modüllü bir proje oluşturacağız. Proje kodlarını buradan indirebilirsiniz.

Çok modüllü bir proje, içinden sahip olduğu alt modüllere referans veren bir ebeveyn POM ile oluşturulur. Yani ebeveyn projemizi simple-parent/ dizinine koyar ve içine de şu POM'u koyarsak, simple-weather ve simple-webapp adında iki alt modülü olan bir çok modüllü proje elde etmiş oluruz:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.sonatype.mavenbook.multi</groupId>
  <artifactId>simple-parent</artifactId>
  <packaging>pom</packaging>
  <version>1.0</version>
  <name>Multi Chapter Simple Parent Project</name>
 
  <modules>
    <module>simple-weather</module>
    <module>simple-webapp</module>
  </modules>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.5</source>
            <target>1.5</target>
          </configuration>
        </plugin>
      </plugins>
   </pluginManagement> 
  </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Dikkat ederseniz ebeveyn projemizin paketleme tipi olarak JAR veya WAR gibi herhangi bir arşiv çesidi vermedik. Paketleme çeşidimiz sadece diğer projelere referansla içeren basit bir POM dosyası. Ayrıca bu POM'da modules adında daha önce karşılaşmadığınız bir öğe var: modules Bu öğe altındaki her module öğesi ebeveyn projenin dizini altındaki alt modüllerin dizinlerine işaret eder. Yani bizim örneğimize göre simple-weather ve simple-webapp adında iki alt dizine (modüle) sahibiz.
Bu ebeveny POM tarafından tanımlanmış bütün ayarlar, bağımlılıklar v.s. alt modüller tarafından kalıtım alınır.

simple-weather Alt Modülü
Modülümüzün POM'unu şu şekilde oluşturuyoruz:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.sonatype.mavenbook.multi</groupId>
    <artifactId>simple-parent</artifactId>
    <version>1.0</version>
  </parent>
  <artifactId>simple-weather</artifactId>
  <packaging>jar</packaging>

  <name>Multi Chapter Simple Weather API</name>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <configuration>
            <testFailureIgnore>true</testFailureIgnore>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement> 
  </build>

  <dependencies>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
    </dependency>
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <dependency>
      <groupId>jaxen</groupId>
      <artifactId>jaxen</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>velocity</groupId>
      <artifactId>velocity</artifactId>
      <version>1.5</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.3.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Modülün detaylarına inmeden önce burada birşey dikkatinizi çekmeli: parent öğesi. Bu öğe ile modülümüzün ebeveyn projesinin koordinatlarını belirtiyoruz.

Bu modülde şöyle bir yol izleyeceğiz: Tekrar kullanılabilirliği sağlamak için bir tane servis sınıfı yazacağız. Bu sınıf aynen komut satırından çalışan simple-weather projesi gibi girilen bölge koduna ait şehrin hava durumu bilgilerini geri dönecek. Servis sınıfımız işlemlerini gerçekleştirmek için simple-weather projesinin sınıflarını kullanacak.

package org.sonatype.mavenbook.weather;

import java.io.InputStream;

public class WeatherService {

    public WeatherService() {}

    public String retrieveForecast( String zip ) throws Exception {
        // Retrieve Data
        InputStream dataIn = new YahooRetriever().retrieve( zip );

        // Parse Data
        Weather weather = new YahooParser().parse( dataIn );

        // Format (Print) Data
        return new WeatherFormatter().format( weather );
    }
}

simple-webapp Alt Modülü
Bu modülümüz ise az önce simple-weather'da oluşturduğumuz servis sınıfını kullanıp, ondan aldığı verileri yayınlamak üzere birkaç servlet tanımlayacak. Şimdi öncelikle simple-weather modülünü kullanacağımız için POM'umuzda bu projeyi bağımlılık olarak belirtmeliyiz. POM'un geri kalanı zaten simple-webapp projesininkiyle aynı olacak.

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                      http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.sonatype.mavenbook.multi</groupId>
    <artifactId>simple-parent</artifactId>
    <version>1.0</version>
  </parent>

  <artifactId>simple-webapp</artifactId>
  <packaging>war</packaging>
  <name>simple-webapp Maven Webapp</name>
  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.4</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.sonatype.mavenbook.multi</groupId>
      <artifactId>simple-weather</artifactId>
      <version>1.0</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>simple-webapp</finalName>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
</project>

Servletimizde ise HTTP isteğinden bölge kodunu okuyoruz ve bir önceki modülde oluşturduğumuz WeatherService sınıfının retreiveForecast() metodunu çağırıyoruz. Dönen cevabı da out.println() ile istemciye yolluyoruz:
package org.sonatype.mavenbook.web;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class SimpleServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)
        throws ServletException, IOException {
 PrintWriter out = response.getWriter();
 out.println( "SimpleServlet Executed" );
        out.flush();
        out.close();
    }
}

Son olarak web.xml'imizde /weather adresine yapılan istekleri karşılamak üzere WeatherServlet'i kaydediyoruz:
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>simple</servlet-name>
    <servlet-class>org.sonatype.mavenbook.web.SimpleServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>weather</servlet-name>
    <servlet-class>org.sonatype.mavenbook.web.WeatherServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>simple</servlet-name>
    <url-pattern>/simple</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>weather</servlet-name>
    <url-pattern>/weather</url-pattern>
  </servlet-mapping>
</web-app>

Çok Modüllü Projeyi Derlemek
Sıra projelerimizi derlemeye geldi. simple-webapp, simple-weather'a bağımlı olduğu için, daha önce derlenmesi gerekli. Ancak bunu dert etmenize gerek yok, çünkü Maven (Reactor eklentisi) hangisinin daha önce derlenmesi gerektiğini bilecek kadar akıllı. Tek yapmanız gereken ebeveyn projenin olduğu dizinden mvn clean install komudunu çalıştırmak:
~/examples/ch-multi/simple-parent$ mvn clean install
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   Simple Parent Project
[INFO]   simple-weather
[INFO]   simple-webapp Maven Webapp
[INFO] ----------------------------------------------------------------------
[INFO] Building simple-weather
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------
[...]
[INFO] [install:install]
[INFO] Installing simple-weather-1.0.jar to simple-weather-1.0.jar
[INFO] ----------------------------------------------------------------------
[INFO] Building simple-webapp Maven Webapp
[INFO]    task-segment: [clean, install]
[INFO] ----------------------------------------------------------------------
[...]
[INFO] [install:install]
[INFO] Installing simple-webapp.war to simple-webapp-1.0.war
[INFO] 
[INFO] ----------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ----------------------------------------------------------------------
[INFO] Simple Parent Project ............................... SUCCESS [3.041s]
[INFO] simple-weather ...................................... SUCCESS [4.802s]
[INFO] simple-webapp Maven Webapp .......................... SUCCESS [3.065s]
[INFO] ----------------------------------------------------------------------

Tavsiye: Aslında yapmak zorunda olmasanız da mvn komudunu her çalıştırdığınızda clean evresini de ekleyin. Böylece Maven, daha önce oluşturulmuş bütün çıktıları silecek ve "temiz" bir inşa işlemine başlayacaktır.

Uygulamayı Çalıştırmak
Artık bildiğiniz üzere:
~/examples/ch-multi/simple-parent/simple-webapp $ mvn jetty:run
[INFO] ----------------------------------------------------------------------
[INFO] Building simple-webapp Maven Webapp
[INFO]    task-segment: [jetty:run]
[INFO] ----------------------------------------------------------------------
[...]
[INFO] [jetty:run]
[INFO] Configuring Jetty for project: simple-webapp Maven Webapp
[...]
[INFO] Webapp directory = ~/examples/ch-multi/simple-parent/\
                          simple-webapp/src/main/webapp
[INFO] Starting jetty 6.1.6rc1 ...
2007-11-18 1:58:26.980::INFO:  jetty-6.1.6rc1
2007-11-18 1:58:26.125::INFO:  No Transaction manager found
2007-11-18 1:58:27.633::INFO:  Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server

Jetty başladıktan sonra http://localhost:8080/simple-webapp/weather?zip=01201 adresine gidip servisi test edebilirsiniz. Sondaki 5 haneli numarayı değiştirip istediğiniz bölgenin hava durumunu öğrenebilirsiniz.
Aslında Türkiye'nin kodlarını da bulup İstanbul'un hava durumunu da öğrenmek lazım ya. Bu da size ödev olsun :)

Kolay Gelsin.

Hiç yorum yok:

Yorum Gönder