Sprężyste jaja na wiosnę – cz. 1 – potrzebne produkty

Po dłuższej nieobecności na łamy bloga wraca Egg Framework. Wraca w postaci dłuższego tutoriala poświęconego tworzeniu aplikacji Egg + Spring. Tutorial będzie składał się z kilku części. Pierwsza z nich będzie poświęcona przygotowaniom do pracy oraz stworzę w niej najprostszą aplikację Eggową. W drugiej części przedstawię podstawy wiązania Egga i Springa, a w trzeciej dokończymy pisać naszą aplikację wzbogacając ją o szablony i przygotowując paczkę dystrybucyjną.

Co nam będzie potrzebne.

Aplikacje będziemy budowali za pomocą Mavena 2. Jeżeli go nie masz to ściągnij i zainstaluj. Następnie należy pobrać Egg Framwork ze strony projektu. Po rozpakowaniu archiwum otrzymamy dostęp do źródeł oraz przygotowanych zawczasu plików jar. W linii poleceń wchodzimy do katalogu sources/egg2 i następnie uruchamiamy proces kompilacji i instalacji egga:

Listing 1

mvn clean compile install

Egg zainstaluje się w lokalnym repo mavena. Ważne dla nas informacje znajdują się na samym początku logu:

Listing 2

[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO] Egg Framework 2.0
[INFO] Egg 2 Core
[INFO] Egg 2 Tests Support
[INFO] Egg 2 Model
[INFO] Egg 2 View
[INFO] Egg 2 Controller
[INFO] Egg 2 Xhtml View Tags
[INFO] Egg 2 Server
[INFO] Egg 2 Controller Examples
[INFO] Egg 2 View Examples
[INFO] Egg 2 View Spring MVC Integration
[INFO] Egg 2 View SpringMVC Examples
[INFO] Egg 2 Xhtml View Examples
[INFO] Egg 2 Xhtml Prototype Support (AJAX)
[INFO] Egg 2 Xhtml Prototype Examples (AJAX examples)

Jest to spis wszystkich dostępnych modułów egga. Cały proces budowania trwał na moim kompie około 2 i pół minuty. Mamy już główną zalezność dla naszego przyszłego projektu, ale nadal nie mamy samego projektu. Czas zatem utworzyć nowy projekt w mavenie.

Przygotowanie projektu

Wystarczy w linii poleceń wydać komendę:

Listing 3

mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes /
-DgroupId=org.runelord.tutorials.egg -DartifactId=egg-spring-tutorial

Po około 3 sekundach zostanie utworzony katalog egg-spring-tutorial o następującej strukturze:

Listing 4

\egg-spring-tutorial
|-pom.xml
\src
\main
\java
\org
\runelord
\tutorial
\egg
|-App.java
\test
\java
\org
\runelord
\tutorial
\egg
|-AppTest.java

Jak widać utworzony został plik pom.xml oraz testowa klasa i test do niej. Kolejnym krokiem jest przerobienie naszego projektu na projekt Eclipse:

Listing 5

mvn eclipse:eclipse

Jako że mamy wolność to możemy też zrobić projekt netbeansowy lub dowolny inny o ile będziemy wiedzieli jak. Z tego też powodu nie będę wspierał się screeenshotami. Zapewne połowa z was będzie ruszała netbeansa zatem nie ma to sensu. Następnie w katalogu src/main musimy dodać kilka karalogów by w końcu otrzymać taki oto projekt:

Listing 6

\egg-spring-tutorial
|-.classpath
|-.project
|-pom.xml
\src
\main
\java
\org
\runelord
\tutorial
\egg
|-App.java
\lib
\resources
\webapp
\test
\java
\org
\runelord
\tutorial
\egg
|-AppTest.java
\target
|-mvn-eclipse-cache.properties

Teraz należy dodać kilka zależności do naszego pliku pom.xml, aby w rezultacie otrzymać coś takiego:

Listing 7

<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.runelord.tutorial.egg</groupId>
<artifactId>egg-spring-tutorial</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>egg-spring-tutorial</name>
<url>http://maven.apache.org</url>
<properties></properties>
<build>
<outputDirectory>
${basedir}/target/WEB-INF/classes
</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<encoding>${project.encoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>[3.8.1, )</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>[2.0.7, )</version>
</dependency>
<dependency>
<groupId>org.eggframework</groupId>
<artifactId>egg2-core</artifactId>
<version>2.0M1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eggframework</groupId>
<artifactId>egg2-server</artifactId>
<version>2.0M1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eggframework</groupId>
<artifactId>egg2-view-springmvc</artifactId>
<version>2.0M1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eggframework</groupId>
<artifactId>egg2-view-xhtml</artifactId>
<version>2.0M1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

Kolejnym krokiem będzie uruchomienie mavena w celu ściągnięcia zależności.

Listing 8

mvn compile

Dlaczego teraz? Otóż jeżeli będzie nam brakowało jakiejś zależności to zostanie ona pobrana z netu. Może być to proces czasochłonny, a zatem warto zrobić to już na samym początku, by później móc skupić się na pisaniu kodu.

Mamy już gotowe wstępne środowisko dla naszego projektu. Jednak, aby całość banglała jak skowronek o poranku należy wykonać jeszcze jedną rzecz. Do katalogu src/lib musimy skopiować następujące pliki:

  • aopalliance-1.0.jar
  • avalon-framework-4.1.3.jar
  • commons-beanutils-1.6.jar
  • commons-collections-2.1.jar
  • commons-digester-1.7.jar
  • commons-fileupload-1.2.jar
  • commons-io-1.2.jar
  • commons-logging-1.1.jar
  • egg2-2.0M1-SNAPSHOT.jar
  • egg2-controller-2.0M1-SNAPSHOT.jar
  • egg2-controller-springmvc-2.0M1-SNAPSHOT.jar
  • egg2-core-2.0M1-SNAPSHOT.jar
  • egg2-model-2.0M1-SNAPSHOT.jar
  • egg2-server-2.0M1-SNAPSHOT.jar
  • egg2-view-2.0M1-SNAPSHOT.jar
  • egg2-view-springmvc-2.0M1-SNAPSHOT.jar
  • egg2-view-xhtml-2.0M1-SNAPSHOT.jar
  • ehcache-1.2.jar
  • jasper-compiler-4.2.20RC0.jar
  • jasper-runtime-4.2.20RC0.jar
  • javassist-3.0.jar
  • jsp-api-2.0.jar
  • jstl-1.0.jar
  • junit-3.8.1.jar
  • log4j-1.2.12.jar
  • logkit-1.0.1.jar
  • org.mortbay.jetty-5.1.9.jar
  • oro-2.0.8.jar
  • servlet-api-2.4.jar
  • spring-2.0.7.jar
  • standard-1.0.6.jar
  • stax-1.2.0.jar
  • stax-api-1.0.1.jar
  • xml-apis-1.0.b2.jar

Dzięki temu w późniejszych etapach będziemy mogli stworzyć archiwum dystrybucyjne war. Czas na pierwszą prostą aplikację

Przystępujemy do gotowania

Wielką zaletą egga jest wbudowany serwer Jetty. Wystarczy zatem napisać małą klasę , która uruchomi się jak zwykła aplikacja. Najprostszy sposób na uruchomienie naszego serwera to implementacja metody main:

Listing 9

package org.runelord.tutorial.egg;

import org.eggframework2.server.EggServer;

public class Main {
public static void main( String[] args ) throws Exception
{
EggServer.startWebApp(18080, "/egg", "target");
}
}

Jak widać serwer będzie działał na porcie 18080, kontekst /egg,/samp>, a aplikacji należy szukać w katalogutarget. Uruchamiamy i…

Listing 10

log4j:WARN No appenders could be found for logger (org.mortbay.util.Container).
log4j:WARN Please initialize the log4j system properly.

… no i dupa mówiąc krótko. W rzeczywistości, świadomie, pominąłem jedną dość istotną czynność. Nigdzie nie utworzyłem pliku web.xml. Czas zatem powrócić do edycji pliku pom.xml. Jego nowa wersja wzbogaciła się o fragment:

Listing 11

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>run</id>
<goals>
<goal>run</goal>
</goals>
<phase>compile</phase>
<configuration>
<tasks>
<copy todir="${basedir}/target/WEB-INF">
<fileset
dir="${basedir}/src/main/webapp/WEB-INF/" includes="*.xml" />
<fileset dir="${basedir}/src/main/resources/"
includes="*.properties" />
</copy>
<copy todir="${basedir}/target/WEB-INF/lib">
<fileset dir="${basedir}/src/main/lib/"
includes="*.jar" />
</copy>
<copy todir="${basedir}/target/template">
<fileset
dir="${basedir}/src/main/webapp/WEB-INF/template/"
includes="*.html" />
</copy>
<copy todir="${basedir}/target/">
<fileset dir="${basedir}/src/main/webapp/html"
includes="*.html" />
</copy>
</tasks>
</configuration>
</execution>
</executions>
</plugin>

Spowoduje to, że w trakcie kompilacji zostaną skopiowane pliki properties, xml i jar do odpowiednich katalogow w katalogu target. Dodatkowo należy jeszcze utworzyć plik web.xml w katalogu src/main/webapp/WEB-INF. Bedzie on wyglądał w następujacy sposób:

Listing 12

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet id="egg">
<servlet-name>example</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>egg</servlet-name>
<url-pattern>*.egg</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>/index.egg</welcome-file>
<welcome-file>/index.html</welcome-file>
</welcome-file-list>
</web-app>

Skoro mamy już serwlet egg i klasę dispatchera ze springa to musimy jeszcze w tym samym katalogu utworzyć plik egg-servlet.xml:

Listing 13

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- view resolver -->
<bean id="viewResolver"
class="org.eggframework2.view.springmvc.EggSiteViewResolver">
</bean>
</beans>

Przy okazji dodałem odrazu konfigurację view resolvera. Dobra teraz czas to wszytko uruchomić

Listing 14

mvn clean compile

Poszło. Nieźle o fakcie kopiowania plików poinformował mnie maven:

Listing 15

[INFO] [antrun:run {execution: run}]
[INFO] Executing tasks
[copy] Copying 3 files to D:\tutorials\Egg2\egg-spring-tutorial\target\WEB-INF
[copy] Copying 34 files to D:\tutorials\Egg2\egg-spring-tutorial\target\WEB-INF\lib

No dobra… tego jeszcze nie da się uruchomić z linii poleceń, ale zostało skompilowane poprawnie. Na tym etapie poprawna kompilacja nas zadowala. Uruchamiać będziemy aplikaję z poziomu IDE.

Ten ostatni akt wali ze środowiskiem skupił się na dodaniu do źródeł katalogu src/main/resources/ i wskazaniu katalogu docelowego na target/WEB-INF/classes. Naciskamy Alt+Shift+x a potem j i…

Listing 16

INFO - Version Jetty/5.1.9
INFO - Checking Resource aliases
WARN - Invalid welcome file: /index.egg
WARN - Invalid welcome file: /index.html
INFO - Started org.mortbay.jetty.servlet.WebApplicationHandler@8c436b
INFO - Parent class loader is: sun.misc.Launcher$AppClassLoader@18e3e60
INFO - Scratch dir for the JSP engine is: C:\DOCUME~1\koziolek\LOCALS~1\Temp\Jetty__18080__egg
INFO - IMPORTANT: Do not modify the generated servlets
INFO - Initializing Spring FrameworkServlet 'egg'
INFO - Started WebApplicationContext[/egg,/egg]
INFO - Started SocketListener on 0.0.0.0:18080
INFO - Started org.mortbay.jetty.Server@121cc40

… a pod adresem http://localhost:18080/egg/

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax