13 grudnia 2007

Raven, Buildr i...JPA - nieudany start

Na grupie pl.comp.lang.java Michał Chmielarz zapytał o Dostęp do wielu baz danych przez JPA w ramach EJB 3.0. Pytanie bardzo ciekawe, więc postanowiłem odpowiedzieć prezentując przykładową aplikację okraszoną niewielkim artykułem (wprowadzeniem w temat). Jak to bywa w takiej sytuacji należało zestawić projekt i stworzyć kilka klas dla zobrazowania rozwiązania. I właśnie, kiedy już przymierzałem się do zestawienia środowiska do pracy z JPA na bazie doświadczeń przedstawionych w Testowanie złączeń FETCH JOIN w JPA z Apache Maven 2 natrafiłem na artykuł Introducing Raven: An Elegant Build for Java. Zawsze mnie to spotyka, że kiedy napotkam nowy temat to z wielu stron. Przecież nie tak dawno Radarek w komentarzu do Tworzenie wtyczek Maven 2 w Groovy zasugerował przyjrzenie się...Ravenowi, który jest tematem wspomnianego artykułu, a który okazało się, że jest połączeniem cech Maven 2 oraz Ruby - możnaby napisać, że jest to Maven 2 w Ruby. Nie zastanawiając się długo obmyśliłem sobie plan zestawienia środowiska opierając jego zarządzanie na Raven. JPA nie mogło mnie zaskoczyć, więc dodanie do zestawu Ravena nie powinno było sprawić problemu. A jednak.

Czytając artykuł rozpocząłem instalację Ravena, która sprowadziła się (a w zasadzie powinna była sprowadzić się) do pobrania paczki dystrybucyjnej i rozpakowania jej do wybranego katalogu z ustawieniem zmiennych JRUBY_HOME (u mnie wskazywała na c:/apps/raven) oraz PATH. Okazało się, że nie dane mi było popracować z Raven pod Cygwin. Zazywczaj nie pracuję bezpośrednio z linii poleceń Windows, a korzystam z Cygwin, w którym wciąż otrzymywałem komunikat o błędnej ścieżce.

jlaskowski@dev ~
$ export JRUBY_HOME=`cygpath -u c:/apps/raven`

jlaskowski@dev ~
$ export PATH=$JRUBY_HOME/bin:$PATH

jlaskowski@dev ~
$ rake --version
Error opening script file: \cygdrive\c\apps\raven\bin\rake (The system cannot find the path specified)

Z linii poleceń Windows wszystko grało, więc nie tracąc czasu na rozwiązywanie problemów niezwiązanych z tematem przewodnim - JPA i Raven - pozostawiłem ich rozwiązanie na później (później okazało się, że na duużo później).

C:\jpa-raven>rake --version
rake, version 0.7.3

Doczytałem w międzyczasie, że na pomoc nieszczęśliwemu Cygwin może przyjść z pomocą RubyGems, więc po chwili miałem je zainstalowane.

jlaskowski@dev /cygdrive/c/apps/rubygems
$ ruby setup.rb
mkdir -p /usr/lib/ruby/site_ruby/1.8/rbconfig
install -c -m 0644 rbconfig/datadir.rb /usr/lib/ruby/site_ruby/1.8/rbconfig/datadir.rb
mkdir -p /usr/lib/ruby/site_ruby/1.8/rubygems
install -c -m 0644 rubygems/builder.rb /usr/lib/ruby/site_ruby/1.8/rubygems/builder.rb
install -c -m 0644 rubygems/command.rb /usr/lib/ruby/site_ruby/1.8/rubygems/command.rb
mkdir -p /usr/lib/ruby/site_ruby/1.8/rubygems/commands
...
As of RubyGems 0.8.0, library stubs are no longer needed.
Searching $LOAD_PATH for stubs to optionally delete (may take a while)...
...done.
No library stubs found.

A następnie zainstalowałem Raven zgodnie z instrukcjami na stronie Installing Raven.

jlaskowski@dev ~
$ gem install rake
Bulk updating Gem source index for: http://gems.rubyforge.org
Successfully installed rake-0.7.3
1 gem installed
Installing ri documentation for rake-0.7.3...
Installing RDoc documentation for rake-0.7.3...

jlaskowski@dev ~
$ gem install raven
ERROR: While executing gem ... (Gem::RemoteFetcher::FetchError)
OpenURI::HTTPError: 404 Not Found reading http://gems.rubyforge.org/gems/raven-1.2.4.gem

Zaczynałem się już zastanawiać, czy miałem borykać się z problemami Ravena, czy zabrać się za rozwiązanie problemu głównego - JPA i wykorzystaniu dynamicznemu wielu baz danych. Daje Ravenowi jeszcze kilka minut.

Zgodnie z dokumentem instalacyjnym Raven pobrałem raven-1.2.4.gem i zainstalowałem go ręcznie.

jlaskowski@dev ~
$ gem install raven-1.2.4.gem
Successfully installed raven-1.2.4
1 gem installed
Installing ri documentation for raven-1.2.4...
Installing RDoc documentation for raven-1.2.4...

Uff, to się nazywa krótkie wprowdzenie do Ravena, a w zasadzie do Ruby. Jak tak dalej pójdzie, to pójdę z torbami za moje pomysły zmagania się z nowym oprogramowaniem zamiast rozwiązywać właściwe problemy.

Ponownie sprawdzam działanie ruby na Cygwin z moim krótkim projektem. Z pomocą artykułu mój pierwszy Rakefile wyglądał następująco:

require "raven"
require "rake/clean"
CLEAN.include ["target", "dist"]

dependency "compile_deps" do |task|
task.deps << [ "com-oracle-toplink" ]
end

task "default" => "compile_deps"

Próba uruchomienia go kończyła się niepowodzeniem.

jlaskowski@dev /cygdrive/c/jpa-raven
$ rake compile_deps
(in /cygdrive/c/jpa-raven)
rake aborted!
Platform is not a module
/cygdrive/c/jpa-raven/rakefile:1
(See full trace by running task with --trace)

Widocznie nie dane mi było dzisiaj popracować z Raven na Cygwin. Przechodzę na konsolę Windows.

C:\jpa-raven>rake
C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems/version.rb:116:in `initialize':
Malformed version number string toplink (ArgumentError)
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems/version.rb:106:in `new'
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems/version.rb:106:in `create'
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems/specification.rb:288:in `version='
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems.rb:505:in `version='
from (eval):4:in `load_specification'
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:128:in `initialize'
from (eval):2:in `new'
from (eval):2:in `load_specification'
... 9 levels...
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems.rb:76:in `active_gem_with_options'
from C:/apps/raven/lib/ruby/site_ruby/1.8/rubygems.rb:50:in `gem'
from :1

Tutaj niestety nie jest przyjemniej, wręcz powiem, że beznadziejnie, ale biorąc pod uwagę mój brak doświadczenia z Raven wierzę, że wynika to właśnie z...braku doświadczenia.

Na dzisiaj mam dosyć Ravena. Może i jest fajny, ale zaczyna mnie irytować. Odpuszczam. Kończę artykuł, a tam na koniec wzmianka o innym narzędziu do budowania projektów - Buildr. Popróbujmy jego możliwości i zobaczmy, co to cudeńko potrafi. Może z nim jestem w stanie posunąć się dalej?!

Podobnie do Raven, Buildr oparty jest o Ruby. Zaczynam od dokumentu Getting Started. Na konsoli sprowadziło się do wydania kilku poleceń (znowu jestem pod Cygwin).

jlaskowski@dev ~
$ gem install buildr
Updating metadata for 6 gems from http://gems.rubyforge.org
......
complete
Building native extensions. This could take a while...
Successfully installed facets-1.8.54
Successfully installed builder-2.1.2
Successfully installed needle-1.3.0
Successfully installed net-ssh-1.1.2
Successfully installed net-sftp-1.1.0
Successfully installed rubyzip-0.9.1
Successfully installed highline-1.4.0
Successfully installed rjb-1.0.11
Successfully installed Antwrap-0.6.0
Successfully installed rspec-1.0.8
Successfully installed xml-simple-1.0.11
Successfully installed archive-tar-minitar-0.5.1
Successfully installed buildr-1.2.10
13 gems installed
Installing ri documentation for facets-1.8.54...
Installing ri documentation for builder-2.1.2...
ERROR: While generating documentation for builder-2.1.2
... MESSAGE: Unhandled special: Special: type=17, text=""
... RDOC args: --ri --op /usr/lib/ruby/gems/1.8/doc/builder-2.1.2/ri
--title Builder -- Easy XML Building --main README --line-numbers --quiet lib
CHANGES Rakefile README doc/releases/builder-1.2.4.rdoc
doc/releases/builder-2.0.0.rdoc doc/releases/builder-2.1.1.rdoc
(continuing with the rest of the installation)
Installing ri documentation for needle-1.3.0...
Installing ri documentation for net-ssh-1.1.2...
Installing ri documentation for net-sftp-1.1.0...
Installing ri documentation for highline-1.4.0...
Installing ri documentation for Antwrap-0.6.0...
Installing ri documentation for rspec-1.0.8...
Installing ri documentation for archive-tar-minitar-0.5.1...
Installing ri documentation for buildr-1.2.10...
Installing RDoc documentation for facets-1.8.54...
Installing RDoc documentation for builder-2.1.2...
Installing RDoc documentation for needle-1.3.0...
Installing RDoc documentation for net-ssh-1.1.2...
Installing RDoc documentation for net-sftp-1.1.0...
Installing RDoc documentation for highline-1.4.0...
Installing RDoc documentation for Antwrap-0.6.0...
Installing RDoc documentation for rspec-1.0.8...
Installing RDoc documentation for archive-tar-minitar-0.5.1...
Installing RDoc documentation for buildr-1.2.10...

jlaskowski@dev /cygdrive/c/jpa-buildr
$ buildr
To use Buildr you need a buildfile. Do you want me to create one?:
1. From directory structure
2. Skip
? 1
Created /cygdrive/c/jpa-buildr/buildfile

Stworzony buildfile prezentuje się następująco.

jlaskowski@dev /cygdrive/c/jpa-buildr
$ cat buildfile
# Generated by Buildr 1.2.10, change to your liking
# Version number for this release
VERSION_NUMBER = "1.0.0"
# Version number for the next release
NEXT_VERSION = "1.0.1"
# Group identifier for your projects
GROUP = "jpa-buildr"
COPYRIGHT = ""

# Specify Maven 2.0 remote repositories here, like this:
repositories.remote << "http://www.ibiblio.org/maven2/"

desc "The Jpa-buildr project"
define "jpa-buildr" do

project.version = VERSION_NUMBER
project.group = GROUP
manifest["Implementation-Vendor"] = COPYRIGHT
end

Po kilku zmianach plik wyglądał już nieco inaczej.

jlaskowski@dev /cygdrive/c/jpa-buildr
$ cat buildfile
VERSION_NUMBER = "1.0.0"

GROUP = "pl.jaceklaskowski.jpa-buildr"

OPENJPA = ["org.apache.openjpa:openjpa:jar:1.0.1"]

# Specify Maven 2.0 remote repositories here, like this:
repositories.remote << "http://www.ibiblio.org/maven2/"

desc "The JPA-Buildr project"
define "jpa-buildr" do

project.version = VERSION_NUMBER
project.group = GROUP
manifest["Implementation-Vendor"] = "Jacek Laskowski - http://www.JacekLaskowski.pl"

compile.options.target = "1.5"

end

I faktycznie coś robił, ale nie byłem nawet na początku drogi zestawiania projektu.

jlaskowski@dev /cygdrive/c/jpa-buildr
$ buildr
(in /cygdrive/c/jpa-buildr)
Downloading org.apache.ant:ant:jar:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant/1.7.0/ant-1.7.0.jar
100% |.........................................| 1.2MB/ 1.2MB Time: 00:00:23
Downloading org.apache.ant:ant:pom:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant/1.7.0/ant-1.7.0.pom
100% |.........................................| 9.5KB/ 9.5KB Time: 00:00:00
Downloading org.apache.ant:ant-launcher:jar:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-launcher/1.7.0/ant-launcher-1.7.0.jar
100% |.........................................| 11.5KB/ 11.5KB Time: 00:00:00
Downloading org.apache.ant:ant-launcher:pom:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-launcher/1.7.0/ant-launcher-1.7.0.pom
100% |.........................................| 2.3KB/ 2.3KB Time: 00:00:00
Downloading xerces:xercesImpl:jar:2.6.2
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/xerces/xercesImpl/2.6.2/xercesImpl-2.6.2.jar
100% |.........................................| 987.0KB/987.0KB Time: 00:00:16
Downloading xerces:xercesImpl:pom:2.6.2
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/xerces/xercesImpl/2.6.2/xercesImpl-2.6.2.pom
100% |.........................................| 150B/ 150B Time: 00:00:00
Downloading org.apache.ant:ant-trax:jar:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-trax/1.7.0/ant-trax-1.7.0.jar
100% |.........................................| 6.7KB/ 6.7KB Time: 00:00:00
Downloading org.apache.ant:ant-trax:pom:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-trax/1.7.0/ant-trax-1.7.0.pom
100% |.........................................| 3.8KB/ 3.8KB Time: 00:00:00
Downloading org.apache.ant:ant-junit:jar:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-junit/1.7.0/ant-junit-1.7.0.jar
100% |.........................................| 90.6KB/ 90.6KB Time: 00:00:02
Downloading org.apache.ant:ant-junit:pom:1.7.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/ant/ant-junit/1.7.0/ant-junit-1.7.0.pom
100% |.........................................| 3.7KB/ 3.7KB Time: 00:00:00
Building jpa-buildr
Testing jpa-buildr
Downloading junit:junit:jar:4.3.1
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/junit/junit/4.3.1/junit-4.3.1.jar
100% |.........................................| 104.0KB/104.0KB Time: 00:00:02
Downloading junit:junit:pom:4.3.1
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/junit/junit/4.3.1/junit-4.3.1.pom
100% |.........................................| 998B/ 998B Time: 00:00:00
Downloading jmock:jmock:jar:1.2.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/jmock/jmock/1.2.0/jmock-1.2.0.jar
100% |.........................................| 104.2KB/104.2KB Time: 00:00:02
Downloading jmock:jmock:pom:1.2.0
Downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/jmock/jmock/1.2.0/jmock-1.2.0.pom
100% |.........................................| 895B/ 895B Time: 00:00:00

Ale moment! Przecież potrzebuję struktury projektu (!) Wydaje mi się, że Raven oraz Buildr są dobre, ale w momencie istnienia struktury projektowej ze wszystkimi plikami. Ja jednak potrzebuję narzędzia do stworzenia struktury projektowej oraz jego integracji z narzędziem IDE (Eclipse lub NetBeans). Na chwilę obecną nie sądzę, aby jakiekolwiek narzędzie IDE wspierało projekty zarządzane przez Raven czy Buildr, więc na dzisiaj odpuszczam i wracam do sprawdzonego Maven 2.

jlaskowski@dev /cygdrive/c
$ mvn archetype:create -DgroupId=pl.jaceklaskowski.jpa -DartifactId=jpa-multidb-buildr -Dversion=1.0
[INFO] Scanning for projects...
...
[INFO] Archetype created in dir: c:\jpa-multidb-buildr
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------

Mam już strukturę projektową, jednakże pozostaje problem związany z IDE. Który pozwoli mi na import projektu w tej postaci?! Eclipse i NetBeans pozwolą mi ostatecznie zaimportować projekt, jednakże wprowadzanie zależności projektowych w IDE nie będzie odzwierciedlone w konfiguracji Raven i Buildr. Pomysł utrzymywania dwu światów (IDE vs Raven/Buildr) na dzisiaj jest zbytnim wyzwaniem. Pozostaję przy Maven 2.

Na koniec mojej przygody z Buildr przekopiowałem plik buildfile zdefiniowany wyżej i wykonałem polecenie buildr help:projects, aby dowiedzieć się o zdefiniowanych projektach.

jlaskowski@dev /cygdrive/c/jpa-multidb-buildr
$ buildr help:projects
(in /cygdrive/c/jpa-multidb-buildr)
jpa-multidb-buildr # The JPA-MultiDB-Buildr project

Na razie odpuszczam Ravena i Buildr. Zacznę śledzić ich rozwój, ale na dzisiaj koniec z nimi. Wracam do przygotowania środowiska dla zobrazowania tematu obsługi wielu baz danych w JPA. To wydaje się bezproblemowe.