17 kwietnia 2008

Pierwsze kroki z MDA w wykonaniu AndroMDA

22 komentarzy
Po komentarzu Krzyśka do wpisu Pierwsze kroki z UML w NetBeans 6.1, w którym wspomniał o MDA i lekturze artykułu Mariusza Wójcika Spring Framework - projektowanie aplikacji w oparciu o koncepcję MDA nie miałem wątpliwości, że po wczorajszej zabawie z UML dzisiaj pora spróbować sił z MDA - Model-Driven Architecture. Podejście MDA pozwala na tworzenie aplikacji bazując na modelach UML niezależnie od docelowego środowiska uruchomieniowego i użytych technologii, które są transformowane do aplikacji wynikowej za pomocą pewnych magicznych transformat. W innych słowach możnaby założyć, że wystarczy jedynie trochę porysować i po dodaniu pewnych atrybutów utworzenie aplikacji to jedynie wydanie polecenia Generate. Trochę się człowiek nasłuchał o tego typu programowaniu, że fajne i takie tam, ale praktycznej wiedzy żadnej. Czas to zmienić.

Rozpocząłem od wspomnianego artykułu Mariusza, a później zajrzałem na strony AndroMDA. Zacząłem od dostępnej dokumentacji, gdzie w Environment Setup napisano:

Install Maven - A repository containing all versioned dependencies. This repository is used during the build and deploy processes (very similar to the .NET Global Assembly Cache concept).

Użycie Mavena do tworzenia aplikacji zawsze spotyka się z moją aprobatą, więc nie miałem złudzeń, że dzisiaj będzie znowu przyjemnie. Wzmianka o .Net w kontekście Mavena była zaskakująca. Może ktoś coś napisać o tym .NET Global Assembly Cache w kilku krótkich, żołnierskich zdaniach? Ja tu wierzę, że pomysły nowatorskie płynące z projektów otwartych, a tu się okazuje, że w .Net to już dawno wszystko (?) było ;-)

Właśnie niedawno wyszła wersja Apache Maven 2.0.9, więc przy okazji uaktualnimy ją i popróbujemy się z AndroMDA.

Uwaga na potencjalny błąd w tandemie Maven-AndroMDA:

(Note that as of this writing, the latest version of Maven is 2.0.7, but it has a minor issue with AndroMDA 3.2 - this has been fixed in the latest snapshot release. Advanced users may wish to install Maven 2.0.7, but you will have to manually delete the section in app\pom.xml.)

Dzisiejszy pomysł to stworzenie aplikacij webowej z wykorzystaniem AndroMDA, które realizuje specyfikację MDA. Zamiast, jak to polecano w dokumentacji AndroMDA, uruchomienia aplikacji na JBAS skorzystam z aktrakcyjniejszej funkcjonalnie oferty serwera Java EE 5, potencjalnie Apache Geronimo (chociaż w obwodzie oczekuje i GlassFish).
 jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn -v
Maven version: 2.0.9
Java version: 1.5.0_14
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn archetype:create -DgroupId=pl.jaceklaskowski.jsf.mda -DartifactId=mda-webapp
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:create] (aggregator-style)
[INFO] ------------------------------------------------------------------------
...
[INFO] OldArchetype created in dir: c:\projs\sandbox\mda-webapp
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Uruchamiam NetBeans IDE 6.1 RC1 i importuję projekt, aby zmodyfikować pom.xml (plik konfiguracyjny "serce" projektu mavenowego). Wcześniej zainstalowałem netbeansową wtyczkę wspierającą projekty mavenowe (patrz Tworzenie wtyczek Maven 2 z NetBeans IDE 6.1), więc wystarczy Ctrl+Shift+O i wybrać katalog, który stworzyłem wcześniej ręcznie (auć, przecież mogłem to stworzyć z poziomu NB!).


Po zmianach pom.xml prezentuje się następująco:
 <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>pl.jaceklaskowski.jsf.mda</groupId>
<artifactId>mda-webapp</artifactId>
<version>1.0</version>
<name>Aplikacja webowa z pomocą (Andro)MDA, Maven2 i NetBeans 6.1</name>
<url>http://www.jaceklaskowski.pl</url>
<build>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<groupId>org.andromda.maven.plugins</groupId>
<artifactId>andromdapp-maven-plugin</artifactId>
<version>3.2</version>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>andromda</id>
<name>AndroMDA Repository</name>
<url>http://team.andromda.org/maven2</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>andromda</id>
<name>AndroMDA Repository</name>
<url>http://team.andromda.org/maven2</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Wybieram Build z menu kontekstowego projektu (zaznaczam projekt w widoku Projects i z menu pod prawym przyciskiem myszki wybieram Build). BUILD SUCCESSFUL w oknie Output upewnia mnie, że wszystko jest jak należy.

W sekcji Install a UML tool proponuje się skorzystanie z narzędzia UML, w którym zobrazuję mój pomysł nowej aplikacji webowej, którą następnie wyeksportuję w odpowiednim formacie zrozumiałym dla AndroMDA. Mam dostęp do wszystkich wymienionych produktów, ale do IBM Rational Software Architect (obecnie w wersji 7.0.0.6), który wspiera UML2/EMF jest mi najbliżej skorzystam z niego (mógłbym również skorzystać z NetBeans IDE 6.1 i jego wsparcia UMLa, ale skoro nie jest wymieniony na stronie na razie odpada).

We wskazanej gotowej aplikacji na stronie TimeTracker Tour można znaleźć plik readme.txt, w którym napisano:

The project located in this directory has been generated by Naresh Bhatia using the andromdapp:generate Maven plugin.

Fajnie wiedzieć, że przynajmniej część mojej pracy mogę zrzucić na barki mavena. Spróbujmy dowiedzieć się więcej o tej wtyczce z pomocą mvn help:describe (tak mógłbym wszystko wyczytać w pliku, albo na stronie, ale pomyślałem, że pochwalę się moją znajomością Maven-Fu ;-)).
 jlaskowski@work ~
$ mvn help:describe -Dplugin=org.andromda.maven.plugins:andromdapp-maven-plugin:3.2
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'help'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [help:describe] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [help:describe]
[INFO] Plugin: 'org.andromda.maven.plugins:andromdapp-maven-plugin:3.2'
-----------------------------------------------
Group Id: org.andromda.maven.plugins
Artifact Id: andromdapp-maven-plugin
Version: 3.2
Goal Prefix: andromdapp
Description:

A plugin for running AndroMDA's AndroMDApp application generator
to generate Maven2 AndroMDA powered applications.
albo nawet z parametrem -Dmedium=true, który przedstawi funkcjonalność wtyczki w okrojonej postaci (dla czytających o mocnych nerwach proponuje się opcję -Dfull=true. Uprasza się o zapięcie pasów przez uruchomieniem polecenia ;-)).
 jlaskowski@work ~
$ mvn help:describe -Dplugin=org.andromda.maven.plugins:andromdapp-maven-plugin:3.2 -Dmedium=true
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'help'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [help:describe] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [help:describe]
[INFO] Plugin: 'org.andromda.maven.plugins:andromdapp-maven-plugin:3.2'
-----------------------------------------------
Group Id: org.andromda.maven.plugins
Artifact Id: andromdapp-maven-plugin
Version: 3.2
Goal Prefix: andromdapp
Description:

A plugin for running AndroMDA's AndroMDApp application generator
to generate Maven2 AndroMDA powered applications.

Mojos:

Goal: 'clean-structure'
Description:
Removes the an AndroMDApp generated application structure.

Goal: 'generate'
Description:
AndroMDA application generator Mojo.

Goal: 'build'
Description:
A Mojo used for executing the build goals from the top level project.

Goal: 'deploy'
Description:
Provides the deployment of applications to a given directory.

Goal: 'eclipse'
Description:
Writes the necessary .classpath and .project files for a new eclipse application.

Goal: 'maven'
Description:
Allows the execution of maven from a given project (searches for nested pom.xml files and executes Maven)

Goal: 'schema'
Description:
Provides the ability to drop database schemas.

Goal: 'instrument-scripts'
Description:
Allows for the {@link ScriptClassGenerator} mojo to be invoked. on one or more given classes.

Goal: 'undeploy'
Description:
Provides the undeployment of applications from a given directory.
Importuję aplikację timetracker-completed do NB i wykonuję Clean and Build (przecież nie będę tego robił z linii poleceń, kiedy dotykam MDA, nieprawdaż?). Jedna uwaga, projekt TimeTracker po zaimportowaniu zostanie oznaczony przez NB jako posiadający błędy i wykonanie budowania spowoduje rozwiązanie problemów (niedostępności bibliotek w lokalnym repozytorium mavena). Trochę to trwa zanim aplikacja zostanie zbudowana, aż po około 2-3 minutach pojawia się [ERROR]BUILD FAILURE. Hmm, czyżbym tracił cierpliwość? Próbuję innymi technikami - z menu kontekstowego projektu TimeTracker wybieram Open Required Projects (wcześniej jedynie otworzyłem projekt główny) i sprawdzam klasę UserVOComparator (projekt TimeTracker Common (jar)). Najwyraźniej nie ma klasy UserVO w projekcie. Wykonanie polecenia
 jlaskowski@work /cygdrive/c/temp/timetracker-completed
$ find . -name UserVO.java -print
nie napawa optymizmem. Może ten plik jest tworzony dynamicznie podczas budowania? Zgodnie z dokumentacją powinienem mvn install w katalogu głównym aplikacji. Niech będzie.
 jlaskowski@work /cygdrive/c/temp/timetracker-completed
$ mvn install
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] An invalid artifact was detected.

This artifact might be in your project's POM, or it might have been included transitively
during the resolution process. Here is the information we do have for

o GroupID: org.andromda.timetracker
o ArtifactID: timetracker-common
o Version: <<< MISSING >>>
o Type: jar

[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.artifact.InvalidArtifactRTException: For artifact {org.andromda.timetracker:timetracker-common:null:jar}:
The version cannot be empty.
at org.apache.maven.artifact.DefaultArtifact.validateIdentity(DefaultArtifact.java:147)
at org.apache.maven.artifact.DefaultArtifact.<init>(DefaultArtifact.java:122)
at org.apache.maven.artifact.factory.DefaultArtifactFactory.createArtifact(DefaultArtifactFactory.java:158)
at org.apache.maven.artifact.factory.DefaultArtifactFactory.createDependencyArtifact(DefaultArtifactFactory.java:58)
at org.apache.maven.project.DefaultMavenProjectBuilder.createManagedVersionMap(DefaultMavenProjectBuilder.java:452)
at org.apache.maven.project.DefaultMavenProjectBuilder.buildInternal(DefaultMavenProjectBuilder.java:912)
at org.apache.maven.project.DefaultMavenProjectBuilder.buildFromSourceFileInternal(DefaultMavenProjectBuilder.java:506)
at org.apache.maven.project.DefaultMavenProjectBuilder.build(DefaultMavenProjectBuilder.java:198)
at org.apache.maven.DefaultMaven.getProject(DefaultMaven.java:583)
at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:461)
at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:534)
at org.apache.maven.DefaultMaven.getProjects(DefaultMaven.java:365)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:292)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Pięknie! Napawa optymizmem do dalszej ewaluacji, co?

Kończę rozdział i po chwili jestem w Starter App. Zamiast jednak tworzyć aplikację z linii poleceń, skorzystam z NB.

Ctrl+Shift+N i z kategorii Maven wybieram Maven Project. Wciskam przycisk Add... gdzie podaję dane wtyczki, którą wykorzystam do tworzenia aplikacji.


Jak się okazuje takie podejście nie przejdzie, gdyż NB zakończy pracę z:
 [ERROR]BUILD ERROR
------------------------------------------------------------------------
Error creating from archetype

Embedded error: The META-INF/maven/archetype.xml descriptor cannot be found.
Wracam na linię poleceń. Już będę grzeczny.
 jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [andromdapp:generate]
log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester).
log4j:WARN Please initialize the log4j system properly.
INFO [AndroMDA] discovered andromdapp type --> 'j2ee'
INFO [AndroMDA] discovered andromdapp type --> 'richclient'

Please choose the type of application to generate [j2ee, richclient]
j2ee

Please enter the location in which your new application will be created (i.e. f:/java/development):
c:/projs/sandbox

Please enter your first and last name (i.e. Chad Brandon):
Jacek Laskowski

Which kind of modeling tool will you use? [uml1.4, uml2, emf-uml2]:
emf-uml2

Please enter the name of your J2EE project (i.e. Animal Quiz):
Powitanie

Please enter an id for your J2EE project (i.e. animalquiz):
mda-powitanie

Please enter a version for your project (i.e. 1.0-SNAPSHOT):
1.0

Please enter the root package name for your J2EE project (i.e. org.andromda.samples.animalquiz):
pl.jaceklaskowski.powitanie

Would you like an EAR or standalone WAR? [ear, war]:
ear

Please enter the type of transactional/persistence cartridge to use [hibernate, ejb, ejb3, spring, none]:
ejb3

Please enter the database backend for the persistence layer
[hypersonic, mysql, oracle, db2, informix, mssql, pointbase, postgres, sybase, sabdb, progress, derby]:
derby

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]:
no

Will your project have a web user interface? [yes, no]:
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]:
jsf

Would you like to use Facelets or JSP as your view type for JSF? [facelets, jsp]:
facelets

Would you like to use the JBoss Seam application framework? [yes, no]:
yes

Would you like to be able to expose your services as web services? [yes, no]:
yes

Would you like to use the JSR181 (webservice defined by annotations) EJB3 cartridge specific implementation? [yes, no]:
yes
-------------------------------------------------------------------------------------
G e n e r a t i n g A n d r o M D A P o w e r e d A p p l i c a t i o n
-------------------------------------------------------------------------------------
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/application/META-INF/jboss-app.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/config/mda-powitanie-ds.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/core/target/classes/META-INF/ejb-jar.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/core/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
Output: 'file:/c:/projs/sandbox/mda-powitanie/common/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/mappings/WebMergeMappings.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/andromda.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/uml/mda-powitanie.uml2'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/src/main/properties/messages.properties'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/target/mda-powitanie-web-1.0/WEB-INF/web.xml'
-------------------------------------------------------------------------------------
New application generated to --> 'file:/c:/projs/sandbox/mda-powitanie/'
Instructions for your new application --> 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
-------------------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Otwieram projekt mda-powitanie i projekty zależne w NB (Ctrl+Shift+O). Teraz jest czysto (z ostrzeżeniami, których udam, że nie zauważam).


Jak w poprzednim projekcie w katalogu głównym znajduje się plik readme.txt (widoczny w NB w oknie Files, gdyż Projects ukrywa pliki, których nierozpoznaje).

Wykonuję mvn install w wydaniu NB, tj. Clean and Build. W pobieranych zależnościach, podczas budowania, pojawiają się myfaces-impl-1.1.1, tomahawk-1.1.1, aż kończę z
 ------------------------------------------------------------------------
[ERROR]BUILD ERROR
------------------------------------------------------------------------
Failed to resolve artifact.

Missing:
----------
1) org.andromda.profiles.uml14:andromda-profile-seam:xml.zip:1.0-SNAPSHOT

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.andromda.profiles.uml14 -DartifactId=andromda-profile-seam \
-Dversion=1.0-SNAPSHOT -Dpackaging=xml.zip -Dfile=/path/to/file

Path to dependency:
1) pl.jaceklaskowski.powitanie:mda-powitanie-mda:pom:1.0
2) org.andromda.profiles.uml14:andromda-profile-seam:xml.zip:1.0-SNAPSHOT

----------
1 required artifact is missing.

for artifact:
pl.jaceklaskowski.powitanie:mda-powitanie-mda:pom:1.0

from the specified remote repositories:
central (http://repo1.maven.org/maven2),
andromda (http://team.andromda.org/maven2)
Ech, znowu kłopoty. Kasuję projekt i zaczynam jeszcze raz, tyle że bez Seama i Web Services (po tylu problemach stałem się mniej wymagający).
 jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [andromdapp:generate]
log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester).
log4j:WARN Please initialize the log4j system properly.
INFO [AndroMDA] discovered andromdapp type --> 'j2ee'
INFO [AndroMDA] discovered andromdapp type --> 'richclient'

Please choose the type of application to generate [j2ee, richclient]
j2ee

Please enter the location in which your new application will be created (i.e. f:/java/development):
c:/projs/sandbox

Please enter your first and last name (i.e. Chad Brandon):
Jacek Laskowski

Which kind of modeling tool will you use? [uml1.4, uml2, emf-uml2]:
emf-uml2

Please enter the name of your J2EE project (i.e. Animal Quiz):
Powitanie

Please enter an id for your J2EE project (i.e. animalquiz):
mda-powitanie

Please enter a version for your project (i.e. 1.0-SNAPSHOT):
1.0

Please enter the root package name for your J2EE project (i.e. org.andromda.samples.animalquiz):
pl.jaceklaskowski.powitanie

Would you like an EAR or standalone WAR? [ear, war]:
ear

Please enter the type of transactional/persistence cartridge to use [hibernate, ejb, ejb3, spring, none]:
ejb3

Please enter the database backend for the persistence layer
[hypersonic, mysql, oracle, db2, informix, mssql, pointbase, postgres, sybase, sabdb, progress, derb
derby

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]:
no

Will your project have a web user interface? [yes, no]:
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]:
jsf

Would you like to use Facelets or JSP as your view type for JSF? [facelets, jsp]:
facelets

Would you like to use the JBoss Seam application framework? [yes, no]:
no

Would you like to be able to expose your services as web services? [yes, no]:
no
-------------------------------------------------------------------------------------
G e n e r a t i n g A n d r o M D A P o w e r e d A p p l i c a t i o n
-------------------------------------------------------------------------------------
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/application/META-INF/jboss-app.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/config/mda-powitanie-ds.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/core/target/classes/META-INF/ejb-jar.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/core/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
Output: 'file:/c:/projs/sandbox/mda-powitanie/common/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/mappings/WebMergeMappings.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/andromda.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/uml/mda-powitanie.uml2'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/src/main/properties/messages.properties'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/target/mda-powitanie-web-1.0/WEB-INF/web.xml'
-------------------------------------------------------------------------------------
New application generated to --> 'file:/c:/projs/sandbox/mda-powitanie/'
Instructions for your new application --> 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
-------------------------------------------------------------------------------------
Ponownie otwarcie projektu w NB i Clean and Build, które kończy się:
 INFO  [AndroMDA] completed model processing --> TIME: 10.688[s], RESOURCES WRITTEN: 118
[andromdapp:eclipse {execution: default}]
Project file written --> 'C:\projs\sandbox\mda-powitanie\.project'
found project pl.jaceklaskowski.powitanie:mda-powitanie-common:jar:1.0
found project pl.jaceklaskowski.powitanie:mda-powitanie-core:ejb:1.0
found project pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0
------------------------------------------------------------------------
[ERROR]BUILD ERROR
------------------------------------------------------------------------
Error creating eclipse configuration

Embedded error: Unable to download the artifact from any repository

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.jboss -DartifactId=jboss-remoting \
-Dversion=4.0.4-GA -Dpackaging=jar -Dfile=/path/to/file


org.jboss:jboss-remoting:jar:4.0.4-GA

from the specified remote repositories:
central (http://repo1.maven.org/maven2),
andromda (http://team.andromda.org/maven2)
co jednak mnie nie przeraża, bo sam projekt został zbudowany, a jedynie projekt eclipsowy się nie utworzył.

..po chwili...

No dobrze, dobrze - zajmę się i tym (co, jak się zaraz okaże, nie było właściwą decyzją). Do głównego pom.xml projektu dodaję
 <repository>
<id>jboss.com</id>
<name>JBoss Repository</name>
<url>http://repository.jboss.com/maven2/</url>
</repository>
i ponownie podchodzę do Clean and Build. Znowu błąd. Dziwne, ale tego jboss-remoting nie ma w repozytorium jboss.com. Jest jednak w wersji 4.0.5-GA w repozytorium andromda (http://team.andromda.org/maven2). Wniosek: wtyczka andromdapp-maven-plugin w wersji 3.2 tworzy projekt z przestarzałymi (i niedostępnymi) zależnościami. Na stronie wtyczki andromdapp-maven-plugin data ostatniej publikacji to 01 Mar 2008 11:53 CET, jednakże jest to dla wersji 3.3-SNAPSHOT. Nie ma wielkiego wyboru jak popróbować jej.

Na szczęście projekt AndroMDA przewidział taką sytuację, że chciałbym skorzystać z wtyczki poza projektem, gdzie w pom.xml mógłbym zdefiniować zależność i udostępnił gotowy plik zip z koniecznymi artefaktami mavenowymi do rozpakowania w lokalnym repozytorium mavena.
 jlaskowski@work /cygdrive/c/projs/sandbox
$ cd c:/.m2

jlaskowski@work /cygdrive/c/.m2
$ wget -c \
http://team.andromda.org/maven2/org/andromda/maven/plugins/\
andromdapp-maven-plugin/3.3-SNAPSHOT/andromdapp-maven-plugin-install-3.3-SNAPSHOT.zip
...
12:13:49 (153.83 KB/s) - `andromdapp-maven-plugin-install-3.3-SNAPSHOT.zip' saved [80881/80881]

jlaskowski@work /cygdrive/c/.m2
$ jar -xvf andromdapp-maven-plugin-install-3.3-SNAPSHOT.zip
created: org/
created: org/andromda/
created: org/andromda/maven/
created: org/andromda/maven/plugins/
created: org/andromda/maven/plugins/andromdapp-maven-plugin/
created: org/andromda/maven/plugins/andromdapp-maven-plugin/3.3-SNAPSHOT/
inflated: org/andromda/maven/plugins/andromdapp-maven-plugin/3.3-SNAPSHOT/andromdapp-maven-plugin-3.3-SNAPSHOT.jar
inflated: org/andromda/maven/plugins/andromdapp-maven-plugin/3.3-SNAPSHOT/andromdapp-maven-plugin-3.3-SNAPSHOT.pom
inflated: org/andromda/maven/plugins/andromdapp-maven-plugin/maven-metadata-local.xml
Gotowe! Znowu podchodzę do stworzenia projektu z wtyczką andromdapp-maven-plugin w wersji 3.3-SNAPSHOT.
 jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.3-SNAPSHOT:generate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

GroupId: org.andromda.maven.plugins
ArtifactId: andromda-maven-plugins
Version: 3.3-SNAPSHOT

Reason: Unable to download the artifact from any repository

org.andromda.maven.plugins:andromda-maven-plugins:pom:3.3-SNAPSHOT

from the specified remote repositories:
ibiblio.org (http://repo1.maven.org/maven2)
Tego już za wiele! Wracam do wtyczki w wersji 3.2 i rezygnuję z EJB3, co powinno znieść wymaganie odnośnie jakichkolwiek zależności jbossowych.
 jlaskowski@work /cygdrive/c/projs/sandbox
$ mvn org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [org.andromda.maven.plugins:andromdapp-maven-plugin:3.2:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] [andromdapp:generate]
log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester).
log4j:WARN Please initialize the log4j system properly.
INFO [AndroMDA] discovered andromdapp type --> 'j2ee'
INFO [AndroMDA] discovered andromdapp type --> 'richclient'

Please choose the type of application to generate [j2ee, richclient]
j2ee

Please enter the location in which your new application will be created (i.e. f:/java/development):
c:/projs/sandbox

Please enter your first and last name (i.e. Chad Brandon):
Jacek Laskowski

Which kind of modeling tool will you use? [uml1.4, uml2, emf-uml2]:
emf-uml2

Please enter the name of your J2EE project (i.e. Animal Quiz):
Powitanie

Please enter an id for your J2EE project (i.e. animalquiz):
mda-powitanie

Please enter a version for your project (i.e. 1.0-SNAPSHOT):
1.0

Please enter the root package name for your J2EE project (i.e. org.andromda.samples.animalquiz):
pl.jaceklaskowski.powitanie

Would you like an EAR or standalone WAR? [ear, war]:
ear

Please enter the type of transactional/persistence cartridge to use [hibernate, ejb, ejb3, spring, none]:
none

Will your project need workflow engine capabilities? (it uses jBPM and Hibernate3)? [yes, no]:
no

Will your project have a web user interface? [yes, no]:
yes

Would you like your web user interface to use JSF or Struts? [jsf, struts]:
jsf

Would you like to use Facelets or JSP as your view type for JSF? [facelets, jsp]:
jsp

Would you like to be able to expose your services as web services? [yes, no]:
no
-------------------------------------------------------------------------------------
G e n e r a t i n g A n d r o M D A P o w e r e d A p p l i c a t i o n
-------------------------------------------------------------------------------------
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/application/META-INF/jboss-app.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/src/main/config/mda-powitanie-ds.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/app/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
Output: 'file:/c:/projs/sandbox/mda-powitanie/common/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/mappings/WebMergeMappings.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/config/andromda.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/src/main/uml/mda-powitanie.uml2'
Output: 'file:/c:/projs/sandbox/mda-powitanie/mda/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/src/main/properties/messages.properties'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/pom.xml'
Output: 'file:/c:/projs/sandbox/mda-powitanie/web/target/mda-powitanie-web-1.0/WEB-INF/web.xml'
-------------------------------------------------------------------------------------
New application generated to --> 'file:/c:/projs/sandbox/mda-powitanie/'
Instructions for your new application --> 'file:/c:/projs/sandbox/mda-powitanie/readme.txt'
-------------------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Ponownie Clean and Build w NB.
 ------------------------------------------------------------------------
[ERROR]BUILD ERROR
------------------------------------------------------------------------
Failed to resolve artifact.

Missing:
----------
1) org.andromda.cartridges:andromda-jsf-cartridge-components:jar:unknown

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.andromda.cartridges -DartifactId=andromda-jsf-cartridge-components \
-Dversion=unknown -Dpackaging=jar -Dfile=/path/to/file

Path to dependency:
1) pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0
2) org.andromda.cartridges:andromda-jsf-cartridge-components:jar:unknown

2) oracle.adf.view.faces:adf-faces-api:jar:unknown

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=oracle.adf.view.faces -DartifactId=adf-faces-api \
-Dversion=unknown -Dpackaging=jar -Dfile=/path/to/file

Path to dependency:
1) pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0
2) oracle.adf.view.faces:adf-faces-api:jar:unknown

3) org.apache.myfaces:tomahawk:jar:unknown

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.apache.myfaces -DartifactId=tomahawk \
-Dversion=unknown -Dpackaging=jar -Dfile=/path/to/file

Path to dependency:
1) pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0
2) org.apache.myfaces:tomahawk:jar:unknown

4) org.apache.myfaces:myfaces-api:jar:unknown

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.apache.myfaces -DartifactId=myfaces-api \
-Dversion=unknown -Dpackaging=jar -Dfile=/path/to/file

Path to dependency:
1) pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0
2) org.apache.myfaces:myfaces-api:jar:unknown

----------
4 required artifacts are missing.

for artifact:
pl.jaceklaskowski.powitanie:mda-powitanie-web:war:1.0

from the specified remote repositories:
central (http://repo1.maven.org/maven2),
andromda (http://team.andromda.org/maven2)
Teraz jest jeszcze gorzej. Na dzisiaj koniec tego ewaluowania AndroMDA. Teraz już wiem, dlaczego tak niewielu korzysta z MDA. Fajne w założeniach, ale po prostu nie działa (albo ja coś pokręciłem i zamiast dać się prowadzić za rękę to przekombinowałem). Może ktoś ma jakieś sugestie gdzie, co i jak należałoby wykonać, aby skorzystać jednak z AndroMDA? Jakieś doświadczenia z narzędziem, albo jego konkurentami mile widziane.

I pytanie konkursowe: Co oznacza skrót MDA?
  1. "Moja Droga Agatko!" (szczęśliwi, którzy mogą tak tytułować listy do swej ukochanej)
  2. Mam Dość, Ale się nie poddaję
  3. Model-Driven Architecture
  4. ManDarynA gwarowo
Nagród nie ma.

16 kwietnia 2008

Pierwsze kroki z UML w NetBeans 6.1

4 komentarzy
UML (Unified Modelling Language) nigdy nie należał do moich podstawowych narzędzi programistycznych, którymi posługiwałem się podczas tworzenia oprogramowania. Ostatnimi jednak czasy odczuwam niedosyt różnorodności sposobów przedstawiania swoich myśli i zauważam, że mowa (jakkolwiek wyćwiczona) nierzadko przedstawia je właściwie. UML jest językiem obrazowania idei i słowo obrazowanie, jakkolwiek nie stosowane szeroko w tym kontekście, jak najbardziej mi tu pasuje i wyraża, co autor miał na myśli. Język UML jest sposobem wizualnego przedstawiania myśli i pomaga w ich relacji innym. Warto się zainteresować UMLem i mimo nieczęstego użycia w naszych projektach, zacząć go stosować (nawet mimo braku jego użycia przez cały zespół projektowy, gdyż dobre rzeczy same się reklamują i raz zauważony w użyciu UML może stać się podstawowym językiem wymiany informacji). Więcej o UML na stronach "producenta" - http://www.uml.org.

Dzisiaj miałem przyjemność przeczytać wpis Expectation driven developement in NetBeans IDE 6.1 Beta, gdzie autor zastosował umlowy diagram klas do zademonstrowania, co będzie tworzył, a dalej, w komentarzach, znalazłem informację o wsparciu UMLa przez NetBeans 6.1. Dodając do tego moje (wciąż bierne) zainteresowanie UMLem i trwający konkurs NetBeans IDE 6.1 Beta Blogging Contest mogłem ponownie upiec dwie pieczenie na jednym ogniu - zapoznać się z UMLem i sprawdzić jego wsparcie w NetBeans 6.1, a w dodatku zgłosić mój wpis w konkursie (to w sumie daje aż 3 pieczenie na jednym ogniu!).

Zacząłem od lektury artykułu w sekcji UML NetBeansa - Why Model With UML?, gdzie napisano This article serves as a primer for the basic concepts of UML oraz This article is written for those engineers who can never find time to model a project before starting to code and for those engineers who have not yet considered creating models of their systems prior to coding them, aż w końcu This article presents some methods and strategies to help you be more efficient and possibly even save time. To jakby stworzone specjalnie dla mnie! Po 10 minutach miałem go za sobą. Mimo, że wiele tez przedstawionych w artykule było mi znanych, artykuł czytałem z wielkim zainteresowaniem. Obawiałem się początkowo, że będzie trochę przydługi, ale był w sam raz i zaprezentował UML w sposób nie pozostawiający złudzeń, że jest to obowiązkowy sposób na rozpoczęcie projektu, każdego projektu.

Kolejny artykuł w serii wprowadzenia UMLa to UML: Developing Applications. Trochę mnie przeraziło Expected duration: 25 minutes, ale pomyślałem, że skrócę tu i tam, abym jedynie rozeznał się gdzie i jak zacząć, aby ostatecznie przeczytać artykuł i samemu coś stworzyć. Podczas lektury artykułu zdecydowałem się go nieznacznie uatrakcyjnić, w ten sposób, że w artykule tworzona jest aplikacja desktopowa, a ja postanowiłem stworzyć aplikację webową. Oni desktopową, ja webową.

Nie siląć się na wymyślny przykład postanowiłem stworzyć aplikację webową, która będzie witała użytkownika w języku, który jest przez niego wybrany jako domyślny w przeglądarce.

Ctrl+Shift+N i z kategorii Web wybrałem Web Application.

Podałem dane projektu:

Project Name: PowitanieWebApp
Server: GlassFish V2
Context Path: /powitanie
Frameworks: JavaServer Faces

I zatwierdziłem je Finish.

Ctrl+Shift+N i z kategorii UML wybrałem Java-Platform Model.


Opis tego typu projektu - Java-Platform Model - bardzo wymyślny:

Creates a platform-dependent modeling project in the system with empty containers for your model and elements. As you create and populate your model, Java modeling (business) rules are applied to the model.
Nic nie zrozumiałem!

Wciskam Next > i jako w polu Project Name wpisuję PowitanieWebAppUML. Finish.

Wybieram Class Diagram o nazwie PowitanieClassDiagram.


Finish.

Pojawi się edytor UML z diagramem klas. Po prawej stronie pojawi się paleta elementów UML.


Utworzyłem klasę Powitanie z mapą pozdrowień (zaznaczam element Class i przeciągam do edytora. Enter i podaję nazwę Powitanie). Tworzę pakiet pl.jaceklaskowski.jsf.uml z użyciem elementu Package. Ciekawym podejściem jest umożliwienie stworzenia wielu elementów danego typu (na przykład pakietów) i nadawanie im nazw przez Enter, czyli lewy przycisk myszy, Enter, wpisuję nazwę i ponownie Enter, i tak z kolejnymi elementami.

Definiuję atrybut Map<String, String> powitania = new HashMap<String, String>() i kasuję operację setPowitania.

Dodałem operację (metodę) addPowitanie(String jezyk, String powitanie)


Prawym przyciskiem na projekcie PowitanieWebAppUML wybieram menu Generate Code, gdzie jako Target Project podaję PowitanieWebApp. Zatwierdzam OK.

Projekt PowitanieWebApp zostanie oznaczony jako błędny (czerwona ikona na nazwie projektu), gdyż Map oraz HashMap są podane bez ich pakietów. Otwieram Powitanie.java, Ctrl+Shift+I i Enter. Po chwili NetBeans rozpozna zmiany i zniesie komunikat błędu. Jest czysto.

Dodaję ciało do konstruktora i metody addPowitanie. Ostatecznie klasa prezentuje się następująco:
 package pl.jaceklaskowski.jsf.uml;

import java.util.HashMap;
import java.util.Map;


//
// #[regen=yes,id=DCE.0C3BC662-D50C-31DA-16B7-26AFB9E13435]
//

public class Powitanie {

//
// #[regen=yes,id=DCE.20E0A115-46D3-0681-089A-41017816B6C6]
//

private Map powitania = new HashMap();

//
// #[regen=yes,id=DCE.5585E6DF-BAC1-C496-0665-DEC6A9BA153E]
//

public Powitanie () {
// zdefiniuj kilka powitań
powitania.put("en", "Hi!");
powitania.put("pl", "Cześć!");
powitania.put("de", "MoinMoin!");
powitania.put("ru", "Zdrastwujcie!");
}

//
// #[regen=yes,id=DCE.5AB5D39E-7AF1-D127-881C-3F9F766AE597]
//

public void addPowitanie (String jezyk, String powitanie) {
powitania.put(jezyk, powitanie);
}

//
// #[regen=yes,regenBody=yes,id=DCE.383F3A78-B7A8-812E-E5D4-B13087852CFE]
//

public Map getPowitania () {
return powitania;
}

}
Owe znaczniki <editor-fold> są związane z powiązaniem klasy z diagramem UML.

Pora na zdefiniowanie nowopowstałej klasy jako ziarna zarządzanego JSF. Tutaj niestety jedynym sposobem jest edycja pliku konfiguracyjnego aplikacji jsf - faces-config.xml. Ale moment! Niespodzianka! Możliwość definiowania ziaren jest możliwa poprzez Add Managed Bean... w widoku XML edytora faces-config.xml.


Tego wcześniej nie wiedziałem, ani nie napotkałem w artykułach netbeansowych. Choćby dlatego warto było zacząć naukę UML (i już mi się będzie UML w wykonaniu NetBeans mile kojarzył ;-))

Definiuję nowe ziarno powitanie, wybieram klasę z listy Browse... o zasięgu session.


Zatwierdzam przyciskiem Add.

Plik faces-config.xml prezentuje się następująco:
 <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>powitanie</managed-bean-name>
<managed-bean-class>pl.jaceklaskowski.jsf.uml.Powitanie</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Zmieniam stronę welcomeJSF.jsp dodając wywołanie ziarna:
 <%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Pozdrowienia</title>
</head>
<body>
<f:view>
Powitanie w języku <b>${pageContext.request.locale.language}</b> brzmi...
<h1><h:outputText value="#{powitanie.powitania[request.locale.language]}" /></h1>
</f:view>
</body>
</html>
Zmiana polega na wywołaniu metody getPowitania() ziarna powitanie zwracającej mapę, której kluczem jest język, który w JSF uzyskuje się poprzez request.locale.language, podczas gdy w JSP za pomocą pageContext.request.locale.language (to są dwa różne języki EL rozróżniane przez znaki # oraz $, odpowiednio).

Najwyższy czas przekonać się o działaniu mojej aplikacji webowej. Wciskam F6 i po chwili moim oczom ukazuje się...


Zmiana języka na pl (w Firefox - Tools > Options... > Advanced > General > Languages) i F5 (odświeżenie strony) i


A na ru (rosyjski)


Działa! Niemiecki pozostawiam jako ćwiczenie domowe.

Czy to zademonstrowało UMLa w wykonaniu NetBeans 6.1 w pełni? Wątpię. Kolejnym razem jednak znowu coś spróbuję i może w ten sposób poznam UML lepiej. Może nawet zacznę go regularnie używać?

Na zakończenie sprawdzę jeszcze co udostępnia NetBeans w demonstracyjnych aplikacjach - Ctrl+Shift+N, Samples > UML i jest jedynie UML Bank App Sample.


Niewiele. Na szczęście przykład działa, chociaż odpowiada temu, co właśnie przeczytałem. Potrzebuję artykułu o tworzeniu aplikacji webowych z użyciem UML. Choćby niewielki, który wskaże, czy w ogóle ma to sens. Wciąż poszukuję...

I pytanie konkursowe (w trwającym konkursie bez nagród): Co to jest UML?

15 kwietnia 2008

Tworzenie wtyczek Maven 2 z NetBeans IDE 6.1

0 komentarzy
Zainspirowany wpisem Własny plugin mavena postanowiłem spróbować swoich sił na polu tworzenia wtyczek dla Apache Maven 2 i po krótkiej lekturze Guide to Java Plugin Development byłem gotów. Z pomocą NetBeans IDE 6.1 i jego wtyczki Maven miałem po chwili (mniej niż 5 minut!) swoją własną wtyczkę. Może to nie tylko początek mojej kariery jako twórca wtyczek mavenowych, ale również początek serii 5-minutowych wpisów?!

Domyślnie NetBeans IDE 6.1 nie udostępnia wsparcia dla tworzenia projektów opartych o Maven 2 (dalej zwanego m2) i trzeba ratować się instalacją wtyczki Maven.

Z menu Tools wybieramy pozycję Plugins i odszukujemy wtyczki Maven.


Zaznaczamy ją, wciskamy przycisk Install i po chwili NetBeans już wie, co to Maven.

Wciskam Ctrl+Shift+N, a następnie z kategorii Maven wybieram Maven Project.


Wciskam przycisk Next >.

Wybieram Maven Mojo Archetype.


W zależności od "zasobności" lokalnego repozytorium Mavena lista może się nieznacznie różnić od zaprezentowanej. W przypadku braku potrzebnego archetypu (= rodzaju wtyczki wspierającej tworzenie projektu) można skorzystać z przycisku Add... i go dodać ręcznie.


I Finish. Po chwili projekt wtyczki jest gotowy.


W oknie Output - Project Creationg pojawi się BUILD SUCCESSFUL.


Zmieniam nazwę klasy mojo na EchoMojo oraz jej zawartość, aby definiowała zadanie echo, które przyjmuje jeden argument, który z kolei będzie wypisywany podczas uruchomienia.
 package pl.jaceklaskowski.maven.plugins.echo;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

/**
* Zadanie, ktore wypisuje podany komunikat
* @goal echo
* @requiresProject false
*/
public class EchoMojo extends AbstractMojo {

/**
* Komunikat
* @parameter expression="${komunikat}"
* @required
*/
private String komunikat;

public void execute() throws MojoExecutionException {
getLog().info(komunikat);
}
}
Dodanie @requiresProject false określa, że wykonanie wtyczki nie będzie wymagało projektu mavenowego do jej wykonania (bardzo pomocne do wtyczek narzędziowych niezależnych od projektu jak help:describe czy mojego testowego uruchomienia).

Wybieram menu Clean and Build


które spowoduje zainstalowanie wtyczki w lokalnym repozytorium mavenowym. Pomyślna instalacja wtyczki w repozytorium, to wymarzona pora na jej uruchomienie.

Najpierw sprawdzę, czy wtyczka jest rozpoznawana przez m2.
 jlaskowski@work ~
$ mvn -v
Maven version: 2.0.7
Java version: 1.5.0_14
OS name: "windows xp" version: "5.1" arch: "x86"

jlaskowski@work ~
$ mvn help:describe -DgroupId=pl.jaceklaskowski.maven.plugins.echo -DartifactId=echo-maven-plugin
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'help'.
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [help:describe] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [help:describe]
[INFO] artifact pl.jaceklaskowski.maven.plugins.echo:echo-maven-plugin: checking for updates from central
[INFO] Plugin: 'pl.jaceklaskowski.maven.plugins.echo:echo-maven-plugin:1.0'
-----------------------------------------------
Group Id: pl.jaceklaskowski.maven.plugins.echo
Artifact Id: echo-maven-plugin
Version: 1.0
Goal Prefix: echo
Description:

Unknown

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
(Żebym to ja wiedział jak pozbyć się tego Unknown).

I w końcu faktyczne uruchomienie wtyczki.
 jlaskowski@work ~
$ mvn pl.jaceklaskowski.maven.plugins.echo:echo-maven-plugin:1.0:echo -Dkomunikat="Witaj Jacku"
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [pl.jaceklaskowski.maven.plugins.echo:echo-maven-plugin:1.0:echo] (aggregator-style)
[INFO] ----------------------------------------------------------------------------
[INFO] [echo:echo]
[INFO] Witaj Jacku
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
Działa! Można jeszcze wprowadzić kilka usprawnień w jej działaniu, ale to już pozostawiam wytrwałym. A skoro o nich, to pytanie konkursowe (w trwającym od jakiegoś czasu konkursie bez nagród): Jaki rodzaj wtyczki wspomaga tworzenie projektów w Maven 2 (projekty wtyczek, aplikacji webowych, itp.)?

Jeśli masz swoją opinię nt. przydatności (bądź nieprzydatności) NetBeans 6.1 polecam udział w konkursie NetBeans IDE 6.1 Beta Blogging Contest, w którym głos ludu jest nagradzany, a najwyższą wygraną jest...własna wiedza!

13 kwietnia 2008

XXIX spotkanie Warszawskiej Grupy Użytkowników Technologii Java (Warszawa JUG)

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG) zaprasza na XXIX spotkanie, które odbędzie się 15.04.2008 o godzinie 18:00 w sali 5440 Wydziału MIMUW przy ul. Banacha 2 w Warszawie.

Temat prezentacji: Zastrzyk z soku, czyli Google Guice
Prowadzący: Tomasz Szymański (szimano)

Czy w Javie 5.0 trzeba jeszcze używać <<new>> albo fabryk obiektów? Nie! Google Guice zmienia sposób patrzenia na tworzenie nowych obiektów. Zapomninamy o antycznym <<new>> - nastała era @Inject.

Może jest to trochę przesadzony wstęp do prezentacji Tomka, ale jest w nim ziarno prawdy (zbieżność nazw przypadkowa). Tomek pokaże, jak Guice ułatwia tworzenie obiektów, przechowywanie oraz współdzielenie ich pomiędzy innymi obiektami. Jednym słowem, zarządzanie obiektami w wykonaniu Guice przed nami. Google Guice nie stara się być nowym Springiem, czyli czymś w czym można zrobić wszystko. Jego zadanie jest proste - szybki, lekki i łatwy do zrozumienia szkielet służący do wstrzeliwania zależności (co może wam przypominać właśnie wspomnianego Springa, dla którego wielu uważa go jako konkurenta w zakresie IoC/DI). To i inne ciekawostki, w których wykorzystanie Guice może być użyteczne Tomek planuje pokazać.

Tomek Szymański (magister, inżynier, mąż, złośliwiec) - w/g jeszcze nie uzupełnionej strony o nim na Wikipedii: dumny posiadacz pomarańczowego pasa na javaBLACKbelt, miłośnik javy, absolwent oraz doktorant Wydziału Elektrycznego Politechniki Warszawskiej, pracownik pewnej firmy (choć kontraktowy) robiącej najczęściej używany serwer aplikacyjny*. Technologie spod parasola Google interesują Tomka od początku ich publicznego początku.

* w/g pewnych badań

Planowany czas prezentacji to 1,5 godziny, po której planuje się 15-30-minutową dyskusję.

Wstęp wolny!

Zapraszam w imieniu Tomka i grupy Warszawa JUG!

12 kwietnia 2008

Warszawski dzień NetBeans RoadShow

7 komentarzy

Sobota była ostatnim dniem NetBeans RoadShow, w którym uczestniczę z prezentacją JSF 1.2 w wykonaniu NetBeans IDE 6.1. Tym razem w Warszawie i kolejny raz publiczność nie zawiodła - i pod względem frekwencji, jak i aktywności. Udało mi się zademonstrować 6 z 7 planowanych przykładów i z reakcji publiczności mogę mniemać, że ich liczba i skomplikowanie były odpowiednie. Z dobrym odbiorem spotkały się również pytania kontrolne, za które można było otrzymać koszulkę NetBeans. Na ostatni 7. przykład nie starczyło czasu, więc pozostawiłem go sobie na najbliższy artykuł (w zasadzie przedstawiłem go w większej części w poprzednim wpisie Nowości NetBeans IDE 6.1 - JSF CRUD Generator). Mimo wszystko powtórzę go w detalach niebawem. Kręcę się koło pomysłu napisania książki o Java EE 5 i tego typu artykuły obserwuję, że mogłyby być świetnym materiałem na książkę. Wiele osób pyta o podstawowe tematy związane z Java EE 5, których wyjaśnienie można znaleźć w wielu miejscach w Sieci, ale czy to ich liczba, czy brak powiązania między nimi, a może w końcu bariera językowa sprawiają, że początkujący, polscy programiści zainteresowani Korporacyjną Javą 5 nie mogą się w nich odnaleźć. Pomysł jest, a z realizacją...się zobaczy ;-)

Podczas dzisiejszej mojej prezentacji dowiedziałem się o ciekawej funkcjonalności NetBeans, która upraszcza tworzenie metod typu setter/getter. Do tej pory korzystałem z funkcji Refactor > Encapsulate Fields... lub Alt+Insert przy zdefiniowanej zmiennej instancji, a wystarczy po prostu zdefiniować ją i....Ctrl+Spacja.


Warto zwrócić uwagę na metody getKomunikat() oraz setKomunikat(String komunikat), które odpowiadają polu instancji komunikat. To jest ta rzecz, o której nie wiedziałem wcześniej. Miłe! Tego typu tricki, kiedy poznane, znacząco mogą skrócić czas tworzenia aplikacji. Kolejny plus publicznych wystąpień - nie tylko prelegent może coś przekazać słuchaczom, ale i w drugą stronę też to działa.

Niestety, nie udało mi się jednak odtworzyć problemu z wiązaniem stron JSF korzystając z edytora faces-config.xml, który pierwszy raz napotkałem na wczorajszej prezentacji w Krakowie. Na razie mam (i kilku z uczestników mojej krakowskiej prezentacji) świadomość jego istnienia, ale póki co, jest on głęboko schowany w czeluściach netbeansowego kodu. Na dzisiejszej prezentacji poszło wyjątkowo bezwyjątkowo ;-)

Wczoraj podczas mojego powrotu z Krakowa miałem możliwość wysłuchania podcastu w wykonaniu Romana Strobla i...no właśnie tego drugiego nazwiska nie pamiętam, w którym dowiedziałem się o funkcji, która do dzisiaj była niewielkiej dla mnie wartości - Undock Window (Alt+Shift+D). Dzięki uprzejmości Karola Harezlaka okazuje się, że może się ona przydać podczas pracy z wieloma (dwoma, trzema, czterema, ech, rozmarzyłem się) monitorami. Wtedy "rozszczepienie" okienek NetBeans może być nieocenione.


Korzystając z okazji posiadania tak licznej publiczności (naliczyłem około 80 osób) nie mogłem opanować się, aby nie pochwalić się moją nową wiedzą klawiszową. Szybko okazało się, że jestem bodajże ostatnim, który o tych skrótach klawiszowych nie wiedział (!) O zgrozo, dlaczego mi wcześniej nie powiedziano o nich. Tyle czasu poszło do kosza. Niedawno, całkiem przypadkiem, zademonstrowano mi możliwość kasowania całych wyrazów w Windows za pomocą klawisza Ctrl+Backspace oraz Ctrl+Delete. Zamiast ciągłego przyciskania klawisza Backspace, można po prostu wcisnąć klawisz Ctrl i...znowu oszczędzamy trochę czasu.

Na konferencji dowiedziałem się o wydaniu wersji NetBeans IDE 6.1 Release Candidate 1 (RC1), która szczęśliwie okazała się być wersją, którą prezentowałem podczas moich wystąpień krakowskiej i warszawskiej. Ja korzystałem z wersji rozwojowej z 2 dni wcześniej, na której wydaje się być oparte RC1. Mimo wszystko pobrałem ją, bo a nuż coś na koniec jeszcze dodano.

Zakończyliśmy prezentację o JSF 1.2 i NetBeans 6.1 kilkoma pytaniami, wśród których pojawiło się jedno o wsparcie dla Hibernate. Dla mnie Hibernate to jeden z wielu dostawców JPA (dostawca JPA jest w relacji JPA jak sterownik JDBC w stosunku do JDBC), więc zdawkowo odpowiedziałem, że być może skoro korzystam z JPA. Prawda jest taka, że tandem NetBeans-Hibernate nigdy nie był pod moją lupą i nie wiedziałem, czy w ogóle byłby możliwy. Dowiedziałem się, że istnieje wtyczka (wspierająca) Hibernate dla NetBeans 6.1, o której również wspomniano w Feature Highlights w dokumencie NetBeans IDE 6.1 Release Candidate Information w sekcji New Update Center Modules - Hibernate Framework Support. Dokument czytałem wcześniej, ale nie pamiętam, abym trafił na tę informację. Kolejna zaleta publicznych wystąpień, że nie tylko prelegent słuchaczom, ale i słuchacze prelegentowi coś wyjaśnią, przedstawią, czy wskażą.

Moja prezentacja JSF 1.2 w wykonaniu NetBeans IDE 6.1 z tegorocznego NetBeans RoadShow po Polsce dostępna jest do pobrania jako JacekLaskowski-NetBeansRoadShow-JSFiNetBeans61-11-12.04.2008.pdf.

Jutro ostatni dzień NetBeans RoadShow w Polsce, we Wrocławiu. Tam mnie jednak nie będzie, ale mimo wszystko zapraszam w imieniu organizatorów. Może ktoś podeśle linka z relacją jak było? Paweł?

11 kwietnia 2008

NetBeans RoadShow - dzień pierwszy w Krakowie

2 komentarzy

Wyjątkowo jak na moje przygotowania do podróży udało mi sie pojawić na dworcu Warszawa Centralna dużo przed czasem. Była godzina 8:45. Pociąg EuroCity (EC) Bem do Krakowa odjeżdża o 9:05, więc jest jeszcze trochę czasu, aby rozejrzeć się po literaturze fachowej w pobliskim kiosku. Rozglądam sie po półce z czasopismami informatycznymi, a tam Linux, PHP, Linux, Internet, Photoshop i tak przez bodajże 10 czasopism. Nic typowo javowego! Masakra. Mimo, ze czytania mam po brzegi, to nie mogłem oprzeć się pokusie kupienia jakieś nowej gazetki, aby poczuć klimaty literackie poza znanymi mi serwisami i po polsku. Pomyślałem o swojej żonie i dzieciakach (tak, aby ich wyedukować informatycznie właśnie przez gazetki) i postanowiłem kupić pierwszą lepszą o Internecie - rodzinka łyknie trochę wiedzy informatycznej, a sam rozejrzę się w typie i sposobie pisania artykułów. I tu pełne zaskoczenie. Moją uwagę zwróciło czasopismo Internet Maker wydanie kwietniowe (2/08), gdzie na pierwszej stronie widnieje temat Wojna na frameworki, a poniżej Django i Zend Framework pojawił się...Wicket (!) Już nie miałem wątpliwości, jaką gazetę kupić. Niepokojący był jednak fakt niskiej liczby czasopism javowych, a szczególnie tego jednego Software Developer's Journal (tutaj nasuwa się pomysł wydawania gazetki javowej elektronicznie i papierowo, który możnaby zrealizować w ramach Warszawa JUG). W końcu namierzyłem SDJ przykrytego innymi linuksowo-graficzno-internetowymi publikacjami. Bardzo mile zaskoczyła mnie okładka i w ogóle jakość czasopisma (nie mówię tutaj o wartości merytorycznej, a jedynie jej ogólnej prezencji). Zajrzałem do środka, aby rozejrzeć się kto i o czym pisze, a tam artykuł o DWR, jakości oprogramowania i...tyle. Zaplanowalem lekturę SDJ, ale jeszcze nie dzisiaj - wystarczy mi jedno czasopismo. Pora płacić za Internet Maker (19 PLN) i jazda do pociągu.

W pociągu nie mniej milej. Jestem osobą, która nie cierpi jazdy samochodem w roli kierowcy, gdyż czym dłuższa trasa, tym więcej czasu muszę ślęczeć za kierownicą i zamiast zająć się czymś przyjemnym, jak czytanie, to człowiek siedzi i jedzie, siedzi i jedzie, i tak przez kilka godzin. Nuda na maksa. Zamiast tego zawsze w dłuższe wyjazdy wybieram pociąg. Uwielbiam jeździć pociągami, szczególnie tymi ze składu InterCity, bo mogę zająć się czytaniem, rozpoznawaniem i w ogóle odłożonymi na później sprawami. Muszę przyznać, że z nieukrywaną radością widzę jak IC radzi sobie coraz lepiej na tym polu i wagony wyglądaja coraz lepiej. Są wygodne, a co mnie dzisiaj zaskoczyło, to i klimatyzowane. Kiedykolwiek mogę, wybieram miejsce w klasie 1. i zawsze sprawdzam, czy dostępne są kontakty. Niestety nie można jeszcze dowiedzieć się, czy miejsce jakie mam na bilecie będzie w wagonie z kontaktami, czy nie. Ważne jest, ze kupno biletu w pociągu kosztuje dodatkowo jedynie 6 PLN, więc można się rozejrzeć po wagonach i siąść tam, gdzie są kontakty. Wcześniej telefonowalem do kasy IC, gdzie przemiły gość obsłużył mnie informując mnie, że na 3 wagony z bodajże 50 miejscami siedzącymi jest jedynie 3 pasażerów, więc ze znalezieniem miejsca i kupnem biletu w 1. klasie już w pociągu nie będzie żadnych problemów. Biletu na pociągi miedzynarodowe - EuroCity - nie można kupić w Internecie, ale przy owym dodatkowym 6 PLN nie jest to żadnym problemem. Dodatkowe 6 PLN postanowilem poświecić, aby odszukać miejsca z kontaktem. Jakież było moje zdumienie, kiedy okazało się, że cała jedynka jest klimatyzowana, a dodatkowo miejsca są przestronne i pod oparciami moje kontakty! Tego mi było trzeba. Pociąg o 9:05 do Krakowa jedzie do Bukaresztu, a bodajże o 9:10 czy 9:15 jest pociag EC do Pragi. I tu pomysł, aby z rodzinką wybrać się do Pragi nie samochodem, a właśnie pociągiem. Próbował ktoś? Gdzie spanie? Jadę na konferencję organizowaną przez załogę z NetBeans, wiec kto jak kto, ale oni, Czesi, beda wiedzieli co, gdzie, kiedy i za ile, więc o wszystko zamierzam wypytać właśnie ich.

Po kolejnej próbie prezentacji i jej udoskonaleniu o kolejne przykłady, zabrałem sie za czytanie Internet Maker'a. Nie potrafię tego wytłumaczyć, ale czasopisma przeglądam od ostatniej strony (może dlatego, ze łatwiej się wertuje pobieżnie kartki?!) i zacząłem lekturę od artykułu Kurs UML - aplikacje Interfejsy (2) autorstwa Marcina Staniszczaka. Krótko i na temat. Artykuł na 5+. Nie mogłem już doczekać się artykułu o Wickecie, więc od razu przewertowałem kartki do niego. I tu kolejne dzisiaj zaskoczenie - artykuł Framework Wicket jest autorstwa...wspomnianego już Marcina Staniszczaka. O UMLu było ciekawie i rzeczowo, więc i przy prezentacji Wicketa tego samego oczekiwałem. Aplikacja prezentowana w artykule bardzo trywialna (sam pamietam, ze opisywalem podobną), jednakże intrygujący był zrzut ekranu na rysunku 4 Uruchomienie kontenera servletów Jetty z wyjątkiem NCDFE (=NoClassDefFoundException)! To na pewno nie jest ten zrzut, który powinien trafić do artykułu w finalnej wersji. Poza tym "incydentem" artykuł oceniam bardzo wysoko, bo nie wgłębia się w szczegóły, a prezentuje Wicketa pobieżnie acz praktycznie i przystępnie.

O 12:00 pojawiłem się w Krakowie. Przed budynkiem AGH przywitał mnie Radek Holewa. Miałem krótką wizytę na przerwie obiadowej w pizzerni, ale w oczekiwaniu na pizzę nadszedł mój czas prezentacji i tyle się najadłem. Moja prezentacja JSF 1.2 w wykonaniu NetBeans IDE 6.1 była wspaniała, tzn. nie potrafię ocenić jej od strony uczestnika-słuchacza, a jedynie uczestnika-prelegenta i piszę tu o klimacie, jaki stworzyli słuchacze. Było kilku ziewających, ale zrzuciłem to na barki poprzedników (którzy ich po prostu najwyraźniej wcześniej zmęczyli). W trakcie prezentacji przedstawiłem tajniki JSF i zaprezentowałem ich realizację w NetBeans 6.1 z GlassFish v2. Dowiedziałem się, że istnieje mapowanie klawiszy w NetBeans 6.1 odpowiadające klawiszom Eclipsowym, więc w końcu zaprzestanę mojego biadolenia na różne ustawienia klawiszy między środowiskami, które zmieniam w zależności od nastroju i potrzeb. Wystarczy skorzystać z menu Tools > Options > Keymap i wybrać Eclipse w menu Profile.


Po tym już Ctrl+Shift+F działa w NetBeans identycznie jak w Eclipse. W końcu! To jedna z zalet interaktywnych prezentacji-warsztatów, gdzie człowiek współpracuje ze słuchaczami. W międzyczasie pojawiło się kilka wyjątków, z których najbardziej drażliwym nazwałby IAE (=IllegalArgumentException), którego nie mogę niestety teraz zreprodukować. Pojawił się przy wiązaniu stron JSF w edytorze faces-config.xml.

Końcówka dzisiejszego dnia prezentacji była jeszcze lepsza. Jak zwykle zdążyć na pociąg stanowi największy dla mnie wyczyn, szczególnie w Krakowie. Kiedy o 15:20 zreflektowałem się, że mam pociąg o 15:55 powiedziano mi, że już nie mam na co liczyć, że nie zdążę na pociąg. Kiedy dodałem, że jadę (taksówką), a nie idę, odpowiedziano mi, że tym bardziej nie zdążę. Ciekawe podejście. Organizatorzy stanęli na wysokości zadania i udało się - zdążyłem! Cieszę się, że mogłem uczestniczyć w konferencji, bo była to ta konferencja, na której pytanie "Ilu z Was korzysta z NetBeans?" spotkało się z większą liczbą podniesionych rąk niż pozostałe środowiska. Byli też wśród uczestników desperaci, którzy czytają mój Notatnik, ale o nich nie ma co wspominać - aż trudno uwierzyć, że nie mają przyjemniejszych rzeczy do robienia jak czytanie Notatnika ;-)

Jutro kolejny dzień NetBeans RoadShow w Warszawie. Tym razem z włączonym mapowaniem klawiszy jak w Eclipse.

08 kwietnia 2008

Konferencja NetBeans RoadShow w Krakowie, Warszawie i Wrocławiu w dniach 11-13 kwietnia 2008

0 komentarzy

Właśnie skończyło się Forum IT, gdzie prezentowałem ofertę firmy IBM w zakresie wsparcia technologii Korporacyjnej Javy 5 (IBM Rational Application Developer 7.5 oraz IBM WebSphere Application Server 6.1 z rozszerzeniem EJB 3.0 Feature Pack), a tu na horyzoncie wyłania się nowa konferencja NetBeans RoadShow, czyli jak to przedstawiono na stronie konferencji:

NetBeans RoadShow, ogólnopolskie tournee będące częścią NetBeans WorldTour 2008 promującego środowisko developerskie NetBeans.

Z tym promującym to bym nie przesadzał, bo jeśli o mnie chodzi, to nie mam zamiaru promować NetBeansa, a raczej zademonstrować wsparcie technologii JavaServer Faces 1.2 przez ostatnią wersję rozwojową NetBeans IDE 6.1 i GlassFisha v2, więc się okaże, czy będzie to promocja, czy wręcz przeciwnie (spokojnie, nie jest tak źle, co można było już przeczytać niejednokrotnie w moim Notatniku o NB6, acz samej słodyczy nie będzie ;-)).

W piątek, 11-ego kwietnia jestem w Krakowie (sala 426, pawilon C2, AGH), a w sobotę, 12-ego kwietnia w Warszawie (sala 3180, MIMUW) prezentując temat JSF1.2 a NetBeans IDE 6.1 BETA. Więcej o agendzie konferencji na stronie Agenda konferencji.

Impreza jest darmowa, więc gorąco zachęcam do uczestnictwa, jako sposób na poznanie narzędzia NetBeans 6.1 oraz możliwość spotkania i porozmawiania o własnych zainteresowniach w gronie użytkowników javy.

Szczególnie zachęcam do rejestracji, gdyż Paweł Szulc z PWrJUG wyzwał mnie na pojedynek rejestrujących, w którym stwierdził, że najwięcej zarejestrowanych będzie we Wrocławiu i to jeszcze w liczbie przekraczającej 150 (!) Oczywiście podjąłem wyzwanie i wierzę, że społeczność warszawska użytkowników javy nie zawiedzie i zademonstruje swoją solidarność w postaci liczby zarejestrowanych i tłumnie zawita w progi wydziału MIM UW na Banacha 2. Wiem, że będzie rówież wiele osób spoza Warszawy i na nich też liczę. Rejestrujmy się! Niech wie, kto rządzi! ;-)