Scala i Maven – część I
Jakiś czas temu postanowiłem głębiej przyjrzeć się językowi Scala, przyznam się szczerze że skusiła mnie jego funkcyjność wraz z możliwościami wykorzystania dynamicznego. W chwili obecnej języki dynamiczne są bardzo „trendy” i dzięki takiemu framework’owi jak Ruby on Rails, język Ruby wypłynął na szerokie wody. W Javie możemy korzystać z kilku języków dynamicznych, oto niektóre z nich:
Pierwszą rzeczą która jest nam niezbędna do rozpoczęcia pracy z każdym nowym językiem jest środowisko, i nie chodzi mi tylko o IDE, ale o ogólną infrastrukturę. Jako że jestem fanem projektu Maven oraz samej koncepcji konfiguracji przez konwencje (oraz jej rozszerzenia o konfiguracje przez wyjątek) postaram się użyć właśnie tego narzędzia.
W pierwsze kolejności stworzymy projekt oraz nauczymy się z niego korzystać, zakładam tutaj że czytelnik miał do czynienia już z Maven’em w wersji 2.
Tworzenie projektu:
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \
-DarchetypeGroupId=org.scala-tools.archetypes \
-DarchetypeArtifactId=scala-archetype-simple \
-DarchetypeVersion=1.2 \
-DremoteRepositories=http://scala-tools.org/repo-releases \
-DgroupId=eu.itool.scala -DartifactId=testingscala
W ten sposob mam stworzony projekt. Jako że lubie pracować na aktualnej wersji Scali
zmieniamy w pliku pom.xml następujący tag.
<scala.version>2.7.3.RC2</scala.version>
Teraz zostało nam sprawdzić nasz projekt, przy okazji ucząc się niezbędnych goal’i:
uruchomienie testów (przy okazji sprawdzamy funkcjonowanie projektu)
$ mvn test
Za każdym razem oczekujemy na końcu takiego o to wyniku:
...
[INFO] ---------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ---------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Thu Jan 08 20:21:45 CET 2009
[INFO] Final Memory: 16M/38M
[INFO] ---------------------------------------------------------------
Jako że korzystamy ze wspomnianej przeze mnie konwencji źródła powinny się znajdować w następujących lokalizacjach
src/main/scala src/test/scala A o to podstawowe polecenia do pracy z projektem:
# sama kompilacja
$ mvn compile
# kompilacja i testy
$ mvn test
# kompilacja, testy i utworzenie archiwum
$ mvn package
W przypadku projektu mieszanego (Java/Scala/etc.) możemy chcieć użyć tylko goal’i dla Scali
# kompilacja źródeł
$ mvn scala:compile
# kompilacja i testy
$ mvn scala:testCompile
Jednym z ciekawych rozwiązań w skali jest możliwość uruchomienia kodu jako skryptów. Jak wiemy start JVM nie należy do najszybszych, wiec przygotowano rozwiązanie podobne do NailGun z JRuby, czyli kompilator jest odpalany jako server i cały czas oczekuje na polecenia ponownej kompilacji. Z poziomu Mavena służą do tego następujące goal’e
# kompilacja i testy z użyciem fsc
$ mvn scala:cc -Donce=true
# kompilacja i test z użyciem scalac
$ mvn scala:cc -Donce=true -Dfsc=false
Widoczny tutaj parametr -Donce=true służy do sygnalizacji ze operacja ma być wykonana tylko raz ponieważ domyślną opcją jest opcja kompilacji kontynuacyjnej (to dla tych co lubią języki skryptowe). Tak więc uruchamiamy kompilacje kontynuacyjna:
$ mvn scala:cc
Scala podobnie jak Java posiada narzędzia do tworzenia dokumentacji na podstawie komentarzy, do tego celu służą następujące polecenia:
# wygenerowanie całej strony wraz z dokumentacją
$ mvn site
# wygenerowanie samej dokumentacji.
$ mvn scala:doc
No dobrze, bawimy się kompilacją ale pytanie jak uruchomić nasz kod za pomocą naszego projektu. Możemy to zrobić na dwa sposoby, pierwszy sposób polega na uruchomieniu klasy poprzez reczne podanie jej nazwy i parametrów:
$ mvn scala:run -DmainClass=eu.itool.scala.App
Drugi sposób polega na wybraniu konkretnego laucher’a którego możemy zdefiniować w naszym pliku projektu pom.xml:
<plugin>
<groupId>maven</groupId>
<artifactId>maven-scala-plugin</artifactId>
<configuration>
<launchers>
<launcher>
<id>nasz</id>
<mainClass>eu.itool.scala.App</mainClass>
<!-- tutaj definiujemy opcjonalnie argumenty aplikacji -->
<args>
<arg>arg1</arg>
</args>
<!-- tutaj definiujemy opcjonalnie jvmArgs -->
<jvmArgs>
<jvmArg>-Xmx128m</jvmArg>
<jvmArg>-Djava.library.path=...</jvmArg>
</jvmArgs>
</launcher>
<!-- tutaj definiujemy kolejne laucher'y --></launchers>
</configuration>
</plugin>
tak wywolujemy naszego laucher’a:
# po nazwie
$ mvn scala:run -Dlauncher=nasz
# pierwszy zdefiniowany
$ mvn scala:run
Podobnie jak plugin’y JRuby’ego i Groovy’ego, tak plugin Scali pozwala na osadzenie wewnątrz pliku projektu pom.xml kodu który zostanie wykonany:
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>script</goal>
</goals>
</execution>
</executions>
<configuration>
<script>
println ("komunikat od Skali ... ale mnie władowali ;-)")
println(project.getArtifactId())
log.info( project("scala.version") )
</script>
</configuration>
</plugin>
Na koniec coś dla fanów script/console z Rails:
# kompilacja i uruchomienie interpretera w trybie interaktywnym
# z dostępem do kodu skompilowanego
$ mvn test
$ mvn scala:console
W następnej części postaram się pokazać podstawy Scali z użyciem naszego przykładowego projektu.


