30 grudnia 2010

Embeddable EJB 3.1 z GlassFish 3.1 i NetBeans IDE 7.0

1 komentarzy
Biorąc pod uwagę liczbę dni do końca roku, ten wpis będzie co najwyżej przedostatnim wpisem na moim blogu, a na pewno ostatnim dotykającym tematu Java EE 6, EJB 3.1 i in.

Korzystając z okazji, chciałbym życzyć Tobie wszystkiego dobrego w nowym roku 2011 i nakłaniam do jeszcze większej aktywności. Nie czekaj, aż powiedzą, ale mów, proponuj, bądź liderem w swojej społeczności. Dla poszukujących natchnienia polecam lekturę wpisu na blogu Damiana Nowaka - Apprenticeship – długa droga ku Software Craftsmanship. Nie wiem, czy to styl pisania Damiana, czy może sama książka, ale tylko takich wpisów życzę nam w nadchodzącym roku. Niech kasa pójdzie w zapomnienie - niech będzie jej tyle, aby nie stanowiła kwestii do rozwiązania - a czas spędzajmy na tworzeniu - nowego i użytecznego oprogramowania, społeczności przez chociażby dzielenie się wiedzą. Nie ważne jaki był (i jeszcze będzie przez kolejne 2 dni) rok 2010, ale ważne, ile możesz zrobić, aby 2011 był jeszcze lepszy. Zalatuje socjotechniką, ale dobre myślenie poprawia mój nastrój, więc może i Twój również, a to może przełożyć się na coś wyjątkowego.

W takim tonie przedkładam Tobie do oceny mój nowy artykuł Embeddable EJB 3.1 z GlassFish 3.1 i NetBeans IDE 7.0, w którym...

Rozdział 22. Embeddable Usage specyfikacji Enterprise JavaBeans (EJB) 3.1 opisuje nową cechę specyfikacji, która pozwala na uruchomienie kontenera EJB i zarządzanych przez niego komponentów EJB poza serwerem aplikacyjnym Java EE 6 - jedynie na poziomie środowiska Java SE. W ten sposób autorzy specyfikacji przewidują (a my programiści im wierzymy) uproszczenie procesu testowania, przetwarzania wsadowego (w którym użycie transakcji jest kluczowe) czy użycie EJB w samodzielnych aplikacjach desktopowych. Innymi słowy, mamy wszystko, co oferuje kontener EJB 3.1 bez konieczności uruchamiania pełnego serwera aplikacyjnego Java EE, którego sama konfiguracja uruchomieniowa mogła przyprawić o ból głowy.

Zainteresowanych lekturą nie zatrzymuję już i jeszcze tylko na odchodne dorzucę nieśmiało, aby komentować, pytać i kwestionować. Wszyscy zostaną *odpowiednio* potraktowani :-)

28 grudnia 2010

Google Guice z Clojure - niebagatelna rola IRC w moim rozwoju

3 komentarzy
Do moich poczynań z JRuby on Rails i komentarzy do wpisu Świąteczne próby z JRuby on Rails wrócę w kolejnym wpisie. Dzisiaj będzie o czymś troszkę innym.

Zdumiewające, jak wiele wiedzy można zdobyć stosując wciąż konwencjonalne sposoby nauki. IRC to narzędzie stare jak sam Internet i pamiętam, ile sprawiało mi przyjemności i satysfakcji, kiedy spędzałem godziny siedząc przed terminalem na uczelni klepiąc dyskusje na jakimś bliżej nieokreślonym kanale. Nie miało znaczenia, gdzie, z kim i o czym, byle można było odsiedzieć swoje przez terminalem. Człowiek nic nie robi i czas mu leci - wtedy to był boski stan.

Przez długi czas nie uważałem IRCa za poważne narzędzie. Kojarzyło mi się właśnie z tym błogim stanem nic-nie-robienia, bo w zasadzie w Sieci jeszcze niewiele można było wtedy robić. Kiedy przyłączyłem się do Apache OpenEJB moje postrzeganie IRCa nieznacznie przesunęło się w stronę większego użycia przy rozwiązywaniu problemów - łatwiej było dopytać o szczegóły działania tego czy innego ustrojstwa. Raczej z rzadka tam zaglądałem, bojąc się nieprzerwanych dyskusji, które fajnie było prowadzić, ale w podsumowaniu wyglądały mizernie.

Nie wiem dlaczego, ale postanowiłem uruchomić Google Guice z poziomu Clojure. Czasami takie pomysły są zarzewiem kolejnych, więc nie zastanawiając się długo, zabrałem się za temat.

Początek był trywialny. Chwila zastanowienia i...potrzebny jest Guice w CLASSPATH do Clojure REPL. Nie inaczej, kiedy klasa javowa chce wywołać inną - obie muszą (zwykle) siebie widzieć przez CLASSPATH. Uruchamiam Clojure 1.3.0-alpha4 z odpowiednimi bibliotekami Guice.
jacek:~
$ CLASSPATH=~/apps/guice/guice-3.0-rc1.jar:~/apps/guice/javax.inject.jar:~/apps/guice/aopalliance.jar clj -13
CLOJURE_DIR:  /Users/jacek/apps/clojure
CLOJURE_CONTRIB_JAR:  /Users/jacek/apps/clojure-contrib-1.3.0-alpha3.jar
Clojure 1.3.0-alpha4
user=>
Pierwsza biblioteka oczywista, a dwie pozostałe wyszły "w praniu", kiedy kolejno uruchamiałem potrzebne elementy Guice.

Skracając znacznie moją historię, dotarłem do momentu, w którym miałem następujący stan:
user=> (import '(com.google.inject Guice AbstractModule))
com.google.inject.AbstractModule
user=> (def module (proxy [AbstractModule] [] (configure [] (println "configure called"))))
#'user/module
user=> (Guice/createInjector module)
IllegalArgumentException No matching method found: createInjector  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:77)
I tu mała zagwozdka. W javadoc dla com.google.inject.Guice jest metoda createInjector, która powinna akceptować mój moduł. Zresztą niejedna.

I tak stan dumania, co by tu począć, trwał cały dzień. W zasadzie trochę dłużej, bo już wczoraj odnotowałem sobie, gdzie stanąłem i zabrałem się za dalsze dumanie z samego rana.

Wieczorem miałem dosyć. Postanowiłem napisać na grupę użytkowników clojure i iść spać. I już miałem pisać, kiedy przypomniałem sobie o kanale #clojure. I to był strzał w dziesiątkę!
[11:22pm] jlaskowski: hi
[11:23pm] jlaskowski: I'm having troubles with java.lang.IllegalArgumentException: No matching method found: createInjector
[11:23pm] jlaskowski: CLASSPATH=`pwd`/guice/guice-3.0-rc1.jar:`pwd`/guice/javax.inject.jar:`pwd`/guice/aopalliance.jar clj -13
[11:23pm] jlaskowski: CLOJURE_DIR:  /Users/jacek/apps/clojure
[11:23pm] jlaskowski: CLOJURE_CONTRIB_JAR:  /Users/jacek/apps/clojure-contrib-1.3.0-alpha3.jar
[11:23pm] jlaskowski: Clojure 1.3.0-alpha4
[11:23pm] jlaskowski: (def mm (proxy [AbstractModule] [] (configure [] (println "configure called"))))
[11:23pm] jlaskowski: (bean mm)
[11:24pm] jlaskowski: {:class user.proxy$com.google.inject.AbstractModule$0}
[11:24pm] jlaskowski: and when I call (Guice/createInjector mm)
[11:24pm] jlaskowski: it spits out the exception
[11:24pm] jlaskowski: http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/AbstractModule.html
[11:25pm] jlaskowski: how can I find out what is wrong exactly?
[11:25pm] jlaskowski: how do I find out what Clojure can call upon a class?
[11:26pm] jlaskowski: any helpful reflection methods to use?
[11:26pm] amalloy: jlaskowski: createInjector takes an array of Modules, not a single module
[11:27pm] amalloy: java's Foo.bar(Whatever...) is sugar for arrays
[11:27pm] jlaskowski: right
[11:27pm] jlaskowski: but have a look at the full stack trace
[11:27pm] jlaskowski: user=> (.printStackTrace *e)
[11:27pm] jlaskowski: java.lang.IllegalArgumentException: No matching method found: createInjector
[11:27pm] jlaskowski: at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:77)
[11:27pm] jlaskowski: at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:202)
[11:27pm] jlaskowski: at user$eval17.invoke(NO_SOURCE_FILE:4)
[11:27pm] jlaskowski: at clojure.lang.Compiler.eval(Compiler.java:6201)
[11:27pm] jlaskowski: at clojure.lang.Compiler.eval(Compiler.java:6168)
[11:27pm] jlaskowski: at clojure.core$eval.invoke(core.clj:2680)
[11:27pm] jlaskowski: at clojure.main$repl$read_eval_print__5619.invoke(main.clj:179)
[11:27pm] jlaskowski: at clojure.main$repl$fn__5624.invoke(main.clj:200)
[11:27pm] jlaskowski: at clojure.main$repl.doInvoke(main.clj:200)
[11:27pm] jlaskowski: at clojure.lang.RestFn.invoke(RestFn.java:422)
[11:27pm] jlaskowski: at clojure.main$repl_opt.invoke(main.clj:266)
[11:27pm] jlaskowski: at clojure.main$main.doInvoke(main.clj:361)
[11:27pm] jlaskowski: at clojure.lang.RestFn.invoke(RestFn.java:437)
[11:27pm] jlaskowski: at clojure.lang.Var.invoke(Var.java:409)
[11:27pm] jlaskowski: at clojure.lang.AFn.applyToHelper(AFn.java:169)
[11:27pm] jlaskowski: at clojure.lang.Var.applyTo(Var.java:518)
[11:27pm] jlaskowski: at clojure.main.main(main.java:37)
[11:27pm] amalloy: augh do not do that
[11:27pm] amalloy: http://gist.github.com
[11:28pm] jlaskowski: amalloy: ok, will use it
[11:29pm] amalloy: anyway, yes. it can't find a method with that name whose parameters are (Foo), only one whose parameters are (Foo[])
[11:29pm] jlaskowski: you're right!
[11:29pm] jlaskowski: so how can I call a method that accepts an array?
[11:29pm] amalloy: you can find this out for yourself with clojure.contrib.repl-utils/show
[11:30pm] amalloy: jlaskowski: ##(doc into-array) is one way; in this case it looks like Guice will also accept an Iterable, so you can just pass it a clojure vector
[11:30pm] sexpbot: ⟹ "([aseq] [type aseq]); Returns an array with components set to the values in aseq. The array's component type is type if provided, or the type of the first value in aseq if present, or Object. All values in aseq must be compatible with the component type. Class objec... http://gist.github.com/756642
[11:31pm] jlaskowski: HURRAYY - you saved my day, amalloy
[11:31pm] jlaskowski: it works fine now
[11:32pm] Luyt_: Freenode's channels are a great resource, because of all the friendly and knowledgeable people on it!
[11:32pm] jlaskowski: it's awesome how quickly it's sorted out!
[11:32pm] Luyt_: ...and some communities are really great.
[11:32pm] lancepantz: we just have a great community 
[11:32pm] jlaskowski: it's not the first time I just enter the channel
[11:33pm] jlaskowski: and get an answer in secs
[11:33pm] jlaskowski: unbelievable
[11:33pm] jlaskowski: thanks again
[11:34pm] Luyt_: as long as you don't become a Help Vampire (http://slash7.com/2006/12/22/vampires/) it's allright 
[11:35pm] Luyt_: and you can always give back to the community, of course. Like lurking and answering questions from noobs, which are too tedious for the advanced clojurists in here. (Same works in #python)
I to było dokładnie to, czego potrzebowałem! Niecały kwadrans i odpowiedź już jest. W zasadzie odpowiedź była minutę po tym, kiedy skończyłem pisać - użyć tablicy zamiast po prostu przekazywać moduł. Ech, człowiek ślepnie na starość.

Wystarczy użyć operatora tablicowego i Guice będzie kontent.
user=> (Guice/createInjector [module])
configure called
#<InjectorImpl Injector[bindings=[ProviderInstanceBinding[key=Key[type=com.google.inject.Injector, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Injector>], ProviderInstanceBinding[key=Key[type=java.util.logging.Logger, annotation=[none]], source=[unknown source], scope=Scopes.NO_SCOPE, provider=Provider<Logger>], InstanceBinding[key=Key[type=com.google.inject.Stage, annotation=[none]], source=[unknown source], instance=DEVELOPMENT]]]>
Tylko, po co mi to było?! :)

25 grudnia 2010

Świąteczne próby z JRuby on Rails

27 komentarzy
Jeszcze przed wigilią udało mi się znaleźć chwilę, aby popróbować się z JRuby on Rails. Swoje doświadczenia oznajmiam na kanale @jaceklaskowski na twitterze i okazuje się, że stamtąd głównie czerpałem natchnienie do dalszych aktywności w temacie. Ech, gdyby tylko twitter pozwalał na dłuższe wypowiedzi...

Zająłem się Rails, głównie z powodu jego powszechnie znanego upraszczania tworzenia aplikacji webowych. Gdziekolwiek nie spojrzę widzę zestawienia, które świadczą o jego prostocie, co ma przekładać się na rzekome zwiększenie produktywności. Samodzielnie chciałem przekonać się, ile w tym prawdy i co takiego ma Rails czego nie mają inne rozwiązania na bazie JEE, a dokładniej rzecz ujmując, chciałem dowiedzieć się, jak zrealizowane jest tworzenie warstwy interfejsu użytkownika. Mam do dyspozycji Grails (wzorowany na Rails) i jest JSF z facelets, Wicket, GWT oraz nieznany mi Play Framework i Vaadin. Jest z czego wybierać, a chciałbym umieć wybierać właściwie. W JSP mamy HTML ze specjalizowanymi znacznikami, JSF to facelets i XHTML ze specjalizowanymi znacznikami, GWT oferuje HTML na podstawie kodu w Javie, a najmniej inwazyjnym rozwiązaniem pod względem możliwości użycia edytorów HTML do tworzenia UI wydają mi się Wicket i Tapestry, które po prostu wskazują na miejsca dynamicznie podstawiane przez specjalny atrybut, np. wicket:id. To ma dla mnie bardzo duże znaczenie, kiedy mogę wskazać osoby w zespole (którego nigdy jednak nie miałem na wyłączność, więc praktycznie nie mam praktycznego zweryfikowania tego postulatu), które mogą używać narzędzi właściwych dla obsługiwanego problemu - w tym przypadku edycji HTML.

Mam pewne doświadczenie z Grails - odpowiednikiem Rails na platformę Java, w którym językiem wiodącym jest Groovy, więc tym bardziej zachodziłem w głowę, czym mógłby mnie urzec Rails. Biorąc pod uwagę, że i Rails i Grails realizują te same koncepcje, a dokładniej rzecz ujmując Grails powstał jako odpowiednik Rails, przez co w zasadzie są bardzo zbliżone do siebie, nie mogłem znaleźć odpowiedzi na pytanie: "Dlaczego w ogóle miałbym chcieć spojrzeć na Rails, skoro mam Grails?" Pomijając zaletę poznawania nowego, jeśli owe nowe ma być jedynie nowym w sensie nomenklatury, a detale zostają te same, to szkoda czasu - są inne rzeczy, które czekają na mnie.

Z takim nastawieniem podszedłem do tematu poznania Rails z JRuby jako język programowania.

Zacząłem od instalacji JRuby, która sprowadziła się rozpakowania w odpowiednim katalogu i dodania podkatalogu bin do zmiennej PATH. Od tej pory polecenie jruby widoczne było z dowolnego katalogu. Super proste i w zasadzie niczego innego nie oczekiwałem. Zdecydowanie na plus i zachęca do dalszej lektury. Niestety nie można tego powiedzieć o stronie Getting Started na jruby.org, która po poinformowaniu użytkownika, że od tej pory polecenie jruby -v zwróci wersję, nic więcej nie przekazuje. Pozostawia nowicjusza we mgle i nie wprost każe mu z niej wyjść.
$ jruby -v
jruby 1.5.6 (ruby 1.8.7 patchlevel 249) (2010-12-03 9cf97c3) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_22) [x86_64-java]
W poszukiwaniu przewodnika, przejrzałem dostępne książki o Rails w books24x7 (jako pracownik IBM mam do niej wgląd bezpłatnie) i trafiłem na Building Dynamic Web 2.0 Websites with Ruby on Rails: Create Database-Driven Dynamic Websites With This Open-Source Web Application Framework z wydawnictwa Packt Publishing z roku 2008. Od razu przeszedłem do rozdziału Chapter 1: Getting Started with Ruby and RoR. Interesowało mnie, co należy dalej począć ze świeżo zainstalowanym JRuby. W końcu nie sam język JRuby był dla mnie interesujący, ale sposób, w jaki Rails korzysta z tego języka do budowania aplikacji webowych, a dokładniej, jak budowane są strony.

Pierwszy rozdział zaczyna się dokładnie tak, z jakim nastawieniem zabrałem się za Rails.

'Which is the best framework for web application development?' This question is asked in different ways and forms. The answer, however, always remains the same — 'The one that enhances productivity'. The next obvious query would be 'In that case which is the framework that enhances productivity?' After some debates and deliberations, we can conclude, 'A framework that reduces Boilerplate code and also reduces the learning curve is the one that increases productivity.'

Pojawia się polecenie gem, które dostarczane jest razem z JRuby.
$ type gem
gem is hashed (/Users/jacek/apps/jruby/bin/gem)
W książce wykonano gem update, więc i ja wykonałem. Nie spodziewałem się wielu poprawek, ale poniżej widać, jak bardzo się myliłem.
$ gem update
JRuby limited openssl loaded. http://jruby.org/openssl
gem install jruby-openssl for full support.
Updating installed gems
Updating columnize
Successfully installed columnize-0.3.2
Updating rspec
**************************************************

  Thank you for installing rspec-core-2.3.1

  Please be sure to look at the upgrade instructions to see what might have
  changed since the last release:

  http://github.com/rspec/rspec-core/blob/master/Upgrade.markdown

**************************************************
Successfully installed rspec-core-2.3.1
Successfully installed diff-lcs-1.1.2
Successfully installed rspec-expectations-2.3.0
Successfully installed rspec-mocks-2.3.0
Successfully installed rspec-2.3.0
Updating ruby-debug
Building native extensions.  This could take a while...
ERROR:  Error installing ruby-debug:
 ERROR: Failed to build gem native extension.

/Users/jacek/apps/jruby/bin/jruby extconf.rb
WARNING: JRuby does not support native extensions or the `mkmf' library.
         Check http://kenai.com/projects/jruby/pages/Home for alternatives.
extconf.rb:16: undefined method `create_makefile' for main:Object (NoMethodError)


Gem files will remain installed in /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/linecache-0.43 for inspection.
Results logged to /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/linecache-0.43/ext/gem_make.out
Updating ruby-debug-base
Building native extensions.  This could take a while...
ERROR:  Error installing ruby-debug-base:
 ERROR: Failed to build gem native extension.

/Users/jacek/apps/jruby/bin/jruby extconf.rb
WARNING: JRuby does not support native extensions or the `mkmf' library.
         Check http://kenai.com/projects/jruby/pages/Home for alternatives.
extconf.rb:16: undefined method `create_makefile' for main:Object (NoMethodError)

Gem files will remain installed in /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/linecache-0.43 for inspection.
Results logged to /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/linecache-0.43/ext/gem_make.out
Gems updated: columnize, rspec-core, diff-lcs, rspec-expectations, rspec-mocks, rspec
Installing ri documentation for columnize-0.3.2...
Installing ri documentation for rspec-core-2.3.1...
Installing ri documentation for diff-lcs-1.1.2...
Installing ri documentation for rspec-expectations-2.3.0...
Installing ri documentation for rspec-mocks-2.3.0...
Installing ri documentation for rspec-2.3.0...
Installing RDoc documentation for columnize-0.3.2...
Installing RDoc documentation for rspec-core-2.3.1...
Installing RDoc documentation for diff-lcs-1.1.2...
Installing RDoc documentation for rspec-expectations-2.3.0...
Installing RDoc documentation for rspec-mocks-2.3.0...
Installing RDoc documentation for rspec-2.3.0...
W końcu pojawia się sekcja Installing RoR - podobno wystarczy gem install rails --include-dependencies.
$ gem install rails --include-dependencies
JRuby limited openssl loaded. http://jruby.org/openssl
gem install jruby-openssl for full support.
INFO:  `gem install -y` is now default and will be removed
INFO:  use --ignore-dependencies to install only the gems you list

Successfully installed activesupport-3.0.3
Successfully installed builder-2.1.2
Successfully installed i18n-0.5.0
Successfully installed activemodel-3.0.3
Successfully installed rack-1.2.1
Successfully installed rack-test-0.5.6
Successfully installed rack-mount-0.6.13
Successfully installed tzinfo-0.3.23
Successfully installed abstract-1.0.0
Successfully installed erubis-2.6.6
Successfully installed actionpack-3.0.3
Successfully installed arel-2.0.6
Successfully installed activerecord-3.0.3
Successfully installed activeresource-3.0.3
Successfully installed mime-types-1.16
Successfully installed polyglot-0.3.1
Successfully installed treetop-1.4.9
Successfully installed mail-2.2.13
Successfully installed actionmailer-3.0.3
Successfully installed thor-0.14.6
Successfully installed railties-3.0.3
Successfully installed bundler-1.0.7
Successfully installed rails-3.0.3
23 gems installed
Installing ri documentation for activesupport-3.0.3...
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 /Users/jacek/apps/jruby-1.5.6/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 --title builder-2.1.2 Documentation
(continuing with the rest of the installation)
Installing ri documentation for i18n-0.5.0...
Installing ri documentation for activemodel-3.0.3...
Installing ri documentation for rack-1.2.1...
Installing ri documentation for rack-test-0.5.6...
Installing ri documentation for rack-mount-0.6.13...
Installing ri documentation for tzinfo-0.3.23...
Installing ri documentation for abstract-1.0.0...
Installing ri documentation for erubis-2.6.6...
Installing ri documentation for actionpack-3.0.3...
Installing ri documentation for arel-2.0.6...
Installing ri documentation for activerecord-3.0.3...
Installing ri documentation for activeresource-3.0.3...
Installing ri documentation for mime-types-1.16...
Installing ri documentation for polyglot-0.3.1...
Installing ri documentation for treetop-1.4.9...
Installing ri documentation for mail-2.2.13...
Installing ri documentation for actionmailer-3.0.3...
Installing ri documentation for thor-0.14.6...
Installing ri documentation for railties-3.0.3...
Installing ri documentation for bundler-1.0.7...
Installing ri documentation for rails-3.0.3...
File not found: lib
Uruchomiłem to polecenie jeszcze raz, bo ten komunikat na samym końcu - File not found: lib - mnie zaniepokoił i liczyłem na poprawę.
$ gem install rails --include-dependencies
JRuby limited openssl loaded. http://jruby.org/openssl
gem install jruby-openssl for full support.
INFO:  `gem install -y` is now default and will be removed
INFO:  use --ignore-dependencies to install only the gems you list
Successfully installed rails-3.0.3
1 gem installed
Installing ri documentation for rails-3.0.3...
File not found: lib
Niestety to samo. Na razie nieważne.

Kolejna sekcja Testing the Installation dotyczyła (jak tytuł wskazuje) sprawdzenia, że środowisko jest faktycznie gotowe. Pierwszy skrypt w Ruby.
$ echo "print 'Hello Ruby'" > first.rb
$ cat first.rb 
print 'Hello Ruby'
$ jruby first.rb
Hello Ruby
To było proste, aczkolwiek w książce wyświetliło się "Hello from Ruby" - intrygujące przeoczenie.

Kolej na głównego sprawcę całego zamieszania - Rails. Tutaj wystarczyć miało rails test_app, ale niestety doświadczyłem kolejnego błędu w książce - brakujące new. Zaczyna być irytujące.
$ rails test_app
Usage:
  rails new APP_PATH [options]

Options:
  -r, [--ruby=PATH]           # Path to the Ruby binary of your choice
                              # Default: /Users/jacek/apps/jruby/bin/jruby
  -d, [--database=DATABASE]   # Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite3/frontbase/ibm_db)
                              # Default: sqlite3
  -b, [--builder=BUILDER]     # Path to an application builder (can be a filesystem path or URL)
  -m, [--template=TEMPLATE]   # Path to an application template (can be a filesystem path or URL)
      [--dev]                 # Setup the application with Gemfile pointing to your Rails checkout
      [--edge]                # Setup the application with Gemfile pointing to Rails repository
      [--skip-gemfile]        # Don't create a Gemfile
  -O, [--skip-active-record]  # Skip Active Record files
  -T, [--skip-test-unit]      # Skip Test::Unit files
  -J, [--skip-prototype]      # Skip Prototype files
  -G, [--skip-git]            # Skip Git ignores and keeps

Runtime options:
  -f, [--force]    # Overwrite files that already exist
  -p, [--pretend]  # Run but do not make any changes
  -q, [--quiet]    # Supress status output
  -s, [--skip]     # Skip files that already exist

Rails options:
  -v, [--version]  # Show Rails version number and quit
  -h, [--help]     # Show this help message and quit

Description:
    The 'rails new' command creates a new Rails application with a default
    directory structure and configuration at the path you specify.

Example:
    rails new ~/Code/Ruby/weblog

    This generates a skeletal Rails installation in ~/Code/Ruby/weblog.
    See the README in the newly created application to get going.
Szczęśliwie Rails dba o takie szczegóły (zastanawiam się, czy nie mógłby jednak stworzyć tej aplikacji, skoro wiedział, że chodziło mi o rails new APP_PATH?!)

Podejście numer dwa - tym razem z new.
$ rails new test_app
      create  
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      ...
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
Pojawiły się kolorowe create, więc znowu jest kolorowo. Pora na uruchomienie świeżoutworzonej aplikacji. Zgodnie z książką wystarczy wykonać polecenie jruby script/server.
jacek:~/sandbox
$ cd test_app/
jacek:~/sandbox/test_app
$ jruby script/server
Error opening script file: /Users/jacek/sandbox/test_app/script/server (No such file or directory)
Ale cóż to?! No such file or directory?! Nadeszła chwila pierwszego samodzielnego rozwiązywania problemów w Rails.
jacek:~/sandbox/test_app
$ ls -l script/
total 8
-rwxr-xr-x  1 jacek  staff  296 Dec 23 21:12 rails
jacek:~/sandbox/test_app
$ jruby script/rails 
JRuby limited openssl loaded. http://jruby.org/openssl
gem install jruby-openssl for full support.
Could not find gem 'sqlite3-ruby (>= 0, runtime)' in any of the gem sources listed in your Gemfile.
Try running `bundle install`.
Niestety, uruchomienie script/rails to zdecydowanie za mało. Zainstaluję kilka gemów - ciągle pojawiający się jruby-openssl oraz sqlite3-ruby. Może pomoże.
jacek:~/sandbox/test_app
$ gem install jruby-openssl sqlite3-ruby
JRuby limited openssl loaded. http://jruby.org/openssl
gem install jruby-openssl for full support.
Successfully installed bouncy-castle-java-1.5.0145.2
Successfully installed jruby-openssl-0.7.2
Building native extensions.  This could take a while...
ERROR:  Error installing sqlite3-ruby:
 ERROR: Failed to build gem native extension.

/Users/jacek/apps/jruby/bin/jruby extconf.rb
WARNING: JRuby does not support native extensions or the `mkmf' library.
         Check http://kenai.com/projects/jruby/pages/Home for alternatives.
extconf.rb:9: undefined method `dir_config' for main:Object (NoMethodError)

Gem files will remain installed in /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.2 for inspection.
Results logged to /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.2/ext/sqlite3/gem_make.out
2 gems installed
Installing ri documentation for bouncy-castle-java-1.5.0145.2...
Installing ri documentation for jruby-openssl-0.7.2...
Installing RDoc documentation for bouncy-castle-java-1.5.0145.2...
Installing RDoc documentation for jruby-openssl-0.7.2...
I jeszcze raz - jruby script/rails.
jacek:~/sandbox/test_app
$ jruby script/rails
Could not find gem 'sqlite3-ruby (>= 0, runtime)' in any of the gem sources listed in your Gemfile.
Try running `bundle install`.
Znowu to samo?! I co oznacza "Try running `bundle install`"?! Zaczyna przypominać poznawanie każdego innego nowego rozwiązania, gdzie zamiast obiecywanego, gładkiego wejścia mam przejścia.

Teraz dopiero zauważyłem, że podczas instalacji sqlite3-ruby pojawiły się błędy, aczkolwiek sam komunikat świadczy, że został zainstalowany mimo to.
ERROR:  Error installing sqlite3-ruby:
 ERROR: Failed to build gem native extension.

/Users/jacek/apps/jruby/bin/jruby extconf.rb
WARNING: JRuby does not support native extensions or the `mkmf' library.
         Check http://kenai.com/projects/jruby/pages/Home for alternatives.
extconf.rb:9: undefined method `dir_config' for main:Object (NoMethodError)

Gem files will remain installed in /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.2 for inspection.
Results logged to /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.2/ext/sqlite3/gem_make.out
Wchodzę na rubyonrails.org, aby poszukać artykułu-przewodnika. I tu kolejne zaskoczenie - sama strona domowa wskazuje na książki Agile Web Development with Rails (4th edition) oraz Rails Recipes, z których pierwsza jest w fazie BETA (wyglada jednak interesująco i zaplanowałem już sobie jej lekturę), a druga jest starociem i sugeruje się jej całkowite zapomnienie na rzecz Advanced Rails Recipes: 84 New Ways to Build Stunning Rails Apps. Na chwilę obecną zostanę przy dokumentacji dostępnej publicznie.

Zaczynam od Getting Started with Rails.

Zaraz na początku, przy 3.1 Installing Rails, zwróciłem uwagę na "Usually run this as the root user". A po co mi root?! A co mi tam, zaryzykuję i sprawdzę instalację z konta roota.
jacek:~/sandbox/test_app
$ sudo gem install rails
Password:
Successfully installed rails-3.0.3
1 gem installed
Installing ri documentation for rails-3.0.3...
File not found: lib
Znowu to "File not found: lib"!

W przewodniku tworzy się aplikację blog, ale ja pozostaję przy książkowej test_app. W sekcji 3.3 Installing the Required Gems dowiaduję się o tym magicznym poleceniu bundle install. Uruchamiam.
jacek:~/sandbox/test_app
$ bundle install
Fetching source index for http://rubygems.org/
Using rake (0.8.7) 
Using abstract (1.0.0) 
Using activesupport (3.0.3) 
...
 from /Users/jacek/apps/jruby/lib/ruby/site_ruby/1.8/rubygems/installer.rb:445:in `each'
 from /Users/jacek/apps/jruby/lib/ruby/site_ruby/1.8/rubygems/installer.rb:445:in `build_extensions'
 from /Users/jacek/apps/jruby/lib/ruby/site_ruby/1.8/rubygems/installer.rb:197:in `install'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/source.rb:95:in `install'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/installer.rb:55:in `run'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/spec_set.rb:12:in `each'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/spec_set.rb:12:in `each'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/installer.rb:44:in `run'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/installer.rb:8:in `install'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/cli.rb:225:in `install'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/vendor/thor/task.rb:21:in `run'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/vendor/thor/invocation.rb:118:in `invoke_task'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/vendor/thor.rb:246:in `dispatch'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/vendor/thor/base.rb:389:in `start'
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/bin/bundle:13
 from /Users/jacek/apps/jruby-1.5.6/lib/ruby/gems/1.8/gems/bundler-1.0.7/bin/bundle:19:in `load'
 from /Users/jacek/apps/jruby/bin/bundle:19
To znowu nie wygląda zachęcająco. Dopiero teraz przypomniałem sobie tweeta od Artura Karazniewicza, w którym pisał:

@jaceklaskowski $ rails new mynewapp -m http://jruby.org and go ahead! #jruby

Próbuję tej ścieżki.
jacek:~/sandbox
$ rails new mynewapp -m http://jruby.org
      create  
      create  README
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      ...
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
       apply  http://jruby.org
       apply    http://jruby.org/templates/default.rb
        gsub      Gemfile
Podczas tworzenia aplikacji pojawił się plik README, więc zgodnie z jego nazwą zabieram się za niego. Podobno wystarczy:

1. At the command prompt, create a new Rails application:
rails new myapp (where myapp is the application name)

2. Change directory to myapp and start the web server:
cd myapp; rails server (run with --help for options)

3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding Ruby on Rails!"

4. Follow the guidelines to start developing your application. You can find
the following resources handy:

* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/

Teraz dostrzegam polecenie rails server.
jacek:~/sandbox/mynewapp
$ rails server
Could not find gem 'activerecord-jdbc-adapter (>= 0, runtime)' in any of the gem sources listed in your Gemfile.
Try running `bundle install`.
I znowu ten bundle install! Sprawdzam, co robi.
jacek:~/sandbox/mynewapp
$ bundle install
Fetching source index for http://rubygems.org/
Using rake (0.8.7) 
Using abstract (1.0.0) 
...
Using activerecord (3.0.3) 
Installing activerecord-jdbc-adapter (1.1.0) 
Using activeresource (3.0.3) 
Using bundler (1.0.7) 
Installing jdbc-sqlite3 (3.6.14.2.056) 
Using thor (0.14.6) 
Using railties (3.0.3) 
Using rails (3.0.3) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
W międzyczasie pojawił się tweet od Nicka Siegera, który doradził:

@jaceklaskowski try regenerating the app with "--template http://jruby.org" or change your Gemfile to use "activerecord-jdbcsqlite3-adapter"

Jestem wdzięczny za rady, ale będąc kompletnym laikiem w temacie nie mam bladego pojęcia, o czym się do mnie mówi. Doświadczam tego błogiego stanu bycia nowicjuszem, które miałem możliwość skosztować przy Clojure, a teraz pojawia się przy Rails. Wspaniała końcówka roku!

Sprawdzam, czy bundle install coś poprawił w mojej aplikacji.
jacek:~/sandbox/mynewapp
$ rails server
=> Booting WEBrick
=> Rails 3.0.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-12-23 21:56:36] INFO  WEBrick 1.3.1
[2010-12-23 21:56:36] INFO  ruby 1.8.7 (2010-12-03) [java]
[2010-12-23 21:56:36] INFO  WEBrick::HTTPServer#start: pid=24997 port=3000
Tak, to jest dokładnie to, czego oczekiwałem! Serwer HTTP nasłuchuje na porcie 3000. Otwieram przeglądarkę z adresem http://0.0.0.0:3000 i...

Jeszcze rzut oka na środowisko przez odnośnik "About your application’s environment".

Pierwsze doświadczenia, jakkolwiek w międzyczasie okraszone pewnymi nieprzyjemnościami, zakończyłem z sukcesem. Jeśli to ma się nazywać zwiększenie produktywności, to ja dziękuję - zwiększyło się, ale jeśli chodzi o rozwiązywanie problemów :) A tak poważnie, to chciałbym, aby tego typu doświadczenia nie miały już miejsca, jeśli mam okrzyknąć Rails produktywnym rozwiązaniem. Wejście powinno być bardziej gładkie. Pewnie zostanie mi przypomniane, że z Ruby nie byłoby tych problemów i wszystkiemy winny JRuby. Pożyjemy, zobaczymy.

23 grudnia 2010

Kolorowanie map z Clojure i Danielem Janusem - prezentacja-cudo

0 komentarzy
Ostatnie, 74. spotkanie Warszawa JUG zaczęło się z prawie 30-minutowym poślizgiem. Około 17:00 zaczął w Warszawie padać intensywny śnieg i zdecydowałem się na dojazd metrem, aby później przez Pola Mokotowskie dotrzeć do MIMUWu. Warto było, bo to, co działo się na ulicach, wołało o pomstę do nieba - wszystko stało, a to, co jechało, to w zasadzie wlekło się. Daniel zdecydował się na dojazd tramwajem i, ku jego zaskoczeniu, z nimi też nie było lepiej. W końcu prezentacja rozpoczęła się. Słuchaczy było 7 plus nasz prelegent.

Prezentację nagrałem i plik z nagraniem jest już gotów do wystawienia. Niestety nie zdążyłem go opublikować przed wyjazdem i zrobię to w nadchodzącym tygodniu. Widziałem, że Poznań JUG wystawił kilka prezentacji na blip.tv i pomyślałem, że może tam trafią i nasze. Usiądę nad tym w przyszłym tygodniu - teraz pora na święta i prezenty. Jeśli znalazłby się ktoś, kto zechciałby mi pomóc w temacie nagrań, ich obsługi i zarządzania ich publikacją, koniecznie niech się ze mną skontaktuje. Pomoc zawsze mile widziana.

Co można było zobaczyć na prezentacji? Było wprowdzenie do Clojure - slajdy poprzeplatane przykładami w REPL, praktycznie, aby ostatecznie całość wiedzy wykorzystać do stworzenia aplikacji webowej z wyświetlanym plikiem SVG z mapą Europy. Daniel pokazał Emacs z SLIME (upewnił mnie, że to nie jest narzędzie dla mnie i nie mam złudzeń, aby tego zestawu NIE dotykać), następnie wczytywanie i zapis plików XML, którego reprezentantem był właśnie SVG i na koniec Ring (nakładka funkcyjna na javowe Servlety w Clojure). Prezentacja-cudo. Interaktywnie zaprezentowany kawał dobrej wiedzy praktycznej i sam przykład przykuwał uwagę - pojawiające się i znikające kolory państw były dla mnie niezwykle interesujące. To jest ten rodzaj prezentacji, gdzie przy tworzeniu aplikacji poznajemy nowe rozwiązanie - tym razem język programowania funkcyjnego Clojure. Brakuje mi takich prezentacji, w których poznawanie nowego jest obok tworzenia interesującej wizualnie aplikacji (niekoniecznie funkcjonalnie, ale jeśli również, to tym lepiej).

Pamiętam podobny przykład z OSGi, w którym aplikacja okienkowa była rozbudowywana przy włączaniu/wyłączaniu kolejnych pakunków. Uważam, że dopasowana aplikacja demonstracyjna podczas prezentacji jest jej kluczowym elementem. Podczas mojego wykładu na PWSZ w Tarnowie udało mi się pokazać coś podobnego - tworzyłem aplikację okienkową w Clojure REPL i nie mogłem uwierzyć, jak wielkie zrobiło to wrażenie. Pamiętam, jaki zadowolony byłem, kiedy wpadłem na ten pomysł i nie inaczej było ze słuchaczami. Ciągle sobie obiecuję, żeby to nagrać, ale jakoś tak schodzi na innych aktywnościach. Brakuje jeszcze umiejętności tworzenia slajdów. Mimo, że zwykle uważa się je za niekonieczne przy prezentacjach technicznych, to ja uważam, że posiadanie ich może znacznie poprawić zrozumienie tematu. Wierzę, że kiedyś i mi się uda nabrać takiego doświadczenia, aby tworzyć przykuwające oko slajdy i dopasować do nich aplikację demonstracyjną. To jest ten moment, w którym życzenia nabierają szczególnej mocy :]

W przyszłym roku będzie kilka okazji, aby popróbować się z tematem - trwają rozmowy z uczelnią krakowską o moim wykładzie w marcu, będzie konferencja 33rd degree w Krakowie i już wiem, że pojawię się również na infoshare.pl w Gdańsku. Pojawił się również pomysł konferencji w Toruniu na UMK w Wydziale MiI w pierwszym kwartale 2011 (zgoda władz wydziału już jest, więc potrzeba jedynie zestawić agendę, czym zajmę się na początku 2011). Chciałbym również odcisnąć swoje piętno (w pozytywnym tego słowa znaczeniu) na jvarsovii 2011.

Tym samym zakończyliśmy spotkania WJUGa w roku 2010. Zapraszam na kolejne w 2011. Pierwsze spotkanie już 11.01.2011, w którym Maciek Próchniak przedstawi Activiti – BPMN 2.0 nadchodzi. Ten temat bardzo mnie interesuje służbowo - wiele czasu spędzam z rozwiązaniem konkurencyjnym - IBM WebSphere Process Server czy IBM WebSphere Business Modeler i ciekaw jestem, co oferuje Activiti. Mógłbym poznać na własną rękę, ale poczekam na prezentację. Będzie nagrywane.

Korzystając z okazji, chciałbym złożyć serdeczne życzenia świąteczne, dużo prezentów i pomysłów na nowe aplikacje z jeszcze bardziej nowatorskimi technologiami, np. Clojure. Nie zapomij o przesłaniu mi ich na priv :-)

20 grudnia 2010

EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0

3 komentarzy
Jest wiele sposobów na naukę nowych technologii i dobór odpowiednich narzędzi może znacząco usprawnić ten proces. W przypadku EJB 3.1 możemy skorzystać z projektu Apache OpenEJB 3.1, podpierając się NetBeans IDE 7.0 jako zintegrowanym środowiskiem programistycznym z asystentami tworzenia ziaren EJB z Apache Maven w tle.

Zastosowanie EJB 3.1 jest zwykle podyktowane względami praktycznymi, kiedy wybór serwera aplikacyjnego Java EE 6 mamy już za sobą i pozostaje wykorzystać jego usługi. Ich kompletność i gotowość do użycia najlepiej doświadczyć, kiedy konieczne jest wykorzystanie transakcji, podłączenia do bazy danych z możliwością przypisania komu i co wolno, udostępnić Web Service z wykorzystaniem REST w ramach aplikacji webowej czy podobne "deklaratywne czynności". Nie ma konieczności zestawiania gotowej konfiguracji usług, a konwencja ponad konfigurację znacznie przyspiesza dostarczanie kompletnych rozwiązań. Przenośność aplikacji jest również istotnym aspektem wyboru stosu technologicznego. Dodając do tego łatwość testowania aplikacji korporacyjnych i Java EE 6 (JEE6) wydaje się być idealną platformą aplikacyjną.

W tym artykule przedstawię uruchomienie bezinterfejsowego, niestanowego ziarna sesyjnego EJB (ang. no-interface stateless session bean) z użyciem projektu Apache OpenEJB 3.1.4, który stworzę w NetBeans IDE 7.0 (wersja rozwojowa z dnia 15.12.2010). Celem jest maksymalne zminimalizowanie czasu koniecznego do uruchomienia środowiska. Kolejną zaletą zastosowania OpenEJB jest możliwość wykonanywania wszystkich operacji projektowych (budowanie i testowanie) poza IDE, dzięki użyciu Apache Maven wspieranym przez NetBeans IDE 7 "z pudełka".

Więcej w artykule EJB 3.1 z OpenEJB 3.1 i NetBeans IDE 7.0.

18 grudnia 2010

Book review: WebSphere Application Server for Developers V7

0 komentarzy
Właśnie ukończyłem lekturę książki, a właściwie publikacji, jak to zwykle nazywa się IBM Redbooks - WebSphere Application Server for Developers V7. Publikacja jest całkowicie bezpłatna w formie elektronicznej i, jak to ująłem w recenzji, niestaty nie zasługuje na swój tytuł. Jest aż nadto skoncentrowana, aby wprowadzić czytelnika w aspekt administracji WASv7 niż na przedstawieniu Java EE 5 i niewiele można znaleźć informacji nt. czego oczekuje się od programisty, który ma wdrożyć taką aplikację na WAS7. Nie powiem, żeby było mało, ale zdecydowanie za mało, jak na książkę z takim tytułem. Dodatkowo, rozdział dotyczący EJB3 oraz JPA jest wręcz nie-JEE5.

Dla mnie osobiście było to swego rodzaju podsumowanie wiedzy nt. okiełznania WAS7, aby nie sprawiał problemów, kiedy przyjdzie mi wdrażać aplikacje korporacyjne. Nie całkiem niskopoziomowo, ot akurat, aby panować nad sytuacją. Książkę czyta się niezwykle szybko i wiedza sama wchodzi do głowy, zakładając, że WAS7 jest tym materiałem, który w głowie czytającego powinna się w ogóle znaleźć. Osąd pozostawiam Tobie.

Pełną recenzję w języku angielskim można przeczytać na moim Wiki w Book review: WebSphere Application Server for Developers V7.

15 grudnia 2010

74. spotkanie Warszawa JUG - Daniel Janus z "Jak Clojure koloruje mapy"

2 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 74. spotkanie, które odbędzie się w najbliższy wtorek, 21. grudnia o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: Jak Clojure koloruje mapy
Prelegent: Daniel Janus

Podczas prezentacji Daniel opowie o:

- co powstaje po przemieszaniu liter w słowie Clojure i co z tego wynika
- dlaczego programowanie w Clojure przypomina operowanie na żywym organizmie
- jak na różne sposoby pokolorować mapę Europy za pomocą Clojure
- jak skonstruować do tego interfejs webowy
- jak dorobić obsługę arkuszy kalkulacyjnych
- jak zbudować łatwo instalowalną aplikację w postaci jednego pliku .jar

A wszystko to podczas prezentacji przeplatanej z tworzeniem kodu "na żywo". Nie zakłada się żadnej znajomości Clojure -- objaśnienia kolejnych cech języka pojawi się w miarę jak będą potrzebne, bez wgłębiania się w szczegóły.

Daniel Janus zajmuje się językami funkcyjnymi od dziesięciu lat, programuje w językach z rodziny Lisp od czterech lat, a od ponad roku współtworzy firmę Fablo, w której Clojure jest główną używaną technologią. Na swoim blogu pisze m.in. o Clojure po polsku.

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

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

14 grudnia 2010

33rd degree i ja z "EJB 3.1 vs Contexts and Dependency Injection (CDI) and Dependency Injection for Java in Java EE 6"

5 komentarzy
Skoro większość z Was wskazuje na Java EE 6 jako temat przewodni grudnia, to może niech i tak zostanie w nadchodzącym roku 2011. Ot, taka mała zapowiedź dalszych poczynań w blogosferze oraz konferencyjnie.

W mojej skrzynce pocztowej znalazłem wiadomość o nadchodzącej konferencji 33rd degree. Niewiele o niej wiadomo, bo temat bardzo, bardzo świeży. Mógłbym założyć, że na tyle, że jestem pierwszym, który pisze o tym na blogu (poza zapowiedzią u samych organizatorów - Wymarzona konferencja nadchodzi).

Piszę o tym, gdyż jest to kolejna konfencja javowa w Polsce, obok JDD, NYAC, GeeCON, Javarsovia, warsjawa, java4people czy 4Developers. Mimo, że wiele z nich cieszy się renomą, widać, że wciąż jest miejsce dla kolejnej. Do grona "uczestników" sceny konferencyjnej dołącza 33rd degree. Jak na tak niewielki kraj, możemy powiedzieć, że tyle u nas konferencji co partii politycznych (!) Może kiedyś dojdzie do jakiś fuzji konferencyjnych?! Tak czy owak, będzie wiele okazji, aby się spotkać i wymienić doświadczeniami. Będę miał w tym swój wkład!

Należy dodać, że markę 33rd degree chce się zbudować na "Top quality speakers that usually talks at big conferences and were chosen many times as Rock Stars" oraz "All speakers were invited personally and validated in practice. No surprises expected. Only great talks." (za stroną domową konferencji).

I teraz o moim wkładzie, a raczej wykładzie. Tak, tak, będę miał swoje 60 minut na przedstawienie tematu EJB 3.1 vs Contexts and Dependency Injection (CDI) and Dependency Injection for Java in Java EE 6. Na razie mam jedynie szkic, co chciałbym przekazać słuchaczom i w jaki sposób, aby dotrzymać kroku innym wystąpieniom, gdzie slajdy należy potraktować za...relikt przeszłości i eksponat muzealny. Sprawa się będzie klarowała w kolejnych miesiącach.

Pora na rozlosowanie specjalnych kodów promocyjnych. Mam ich 10 (i nie zawaham się ich użyć pro publico bono). Niech jednak będzie to transakcja wiązana (bodaj jedyna legalna forma obdarowywania bezkosztowo w PL), gdzie ja Tobie, a Ty mi i jesteśmy kwita. Proszę o wyrażenie swojej opinii nt. połączenia wystąpienia z wcześniej przygotowanymi nagraniami (coś ala skrinkasty) i lokalnym repozytorium wersji kodów źródłowych, aby zamiast klepania (rękoma i ustami) interakcja między prelegentem a uczestnikami przebiegała znacznie szybciej i bez ryzyka utraty tempa czy toku rozumowania. Rola prelegenta sprowadziłaby się do zaprezentowania nagrań i uzupełniania ich słowno-muzycznie. Czy to ma rację bytu? Wsród osób, które wyrażą swój głos w komentarzu do tego wpisu rozlosuję po jednym specjalnym kodzie promocyjnym na konferencję 33rd degree.

09 grudnia 2010

Temat przewodni na grudzień - Java EE 6

3 komentarzy
Ankieta określająca temat przewodni na miesiąc grudzień 2010 dobiegła końca z 85 głosami, w których specyfikacja Java EE 6 zdobyła najwięcej głosów, nieznacznie więcej niż EJB 3.1 i JSF 2.0. Bardzo zdumiewające dla mnie było wskazanie na OSGi jako bardziej interesującego niż CDI. A może nie jest to wskazanie na bardziej interesującą technologię, ale na mniej rozpoznaną?!
Wyniki ankiety tematu przewodniego grudnia 2010
Tym samym rozpoczynam analizę JEE6, w której głównymi graczami będą - dokument standaryzacyjny JSR 316: Java Platform, Enterprise Edition 6 (Java EE 6), serwery aplikacyjne: GlassFish 3.1, Apache Geronimo 3.0, IBM WebSphere Application Server V8 ze zintegrowanymi środowiskami programistycznymi NetBeans IDE 7.0 i IBM Rational Application Developer V8.

Akurat teraz prowadzę 4-dniowe autorskie warsztaty dla programistów (korzystających z Java EE 5 z RAD8) i administratorów WAS7, w których staram się minimalizować przedstawienie tematu od strony teoretycznej, kładąc nacisk na praktyczną stronę pracy z w/w produktami. Skłamałbym, gdybym powiedział, że udało mi się odpowiedzieć na wszystkie pytania, a było również wiele niezwykle inspirujących. Zebrałem tym samym mnóstwo tematów do przyszłych skrinkastów, więc można spodziewać się ich jeszcze kilka w tym roku i wszystkie (a przynajmniej ich większość) wokół JEE. Końcówka 2010 zapowiada się pracowita nagraniowo. W końcu pojawiła się wena, z którą zamierzam wejść w 2011!

p.s. Uruchomiłem nową ankietę "Preferowany sposób nauki JEE6", w której badam zainteresowanie różnym sposobem prezentacji JEE6. Znajdziesz ją po prawej na moim blogu. Zapraszam.

06 grudnia 2010

Odkrywcze podobieństwo Java SE i Java EE z CDI na czele

5 komentarzy
Każdy, kto programuje w Javie "siedzi" na poziomie Java Standard Edition, w skrócie Java SE, czy wręcz JSE. Obecna wersja to 6.0. Mamy do dyspozycji cały zestaw interfejsów i klas - wszystko objęte terminem Java SE API. Dokumentacja do aktualnej wersji znajduje się na stronach Java Platform, Standard Edition 6 API Specification. To powinno być oczywiste i należy do podstawowej wiedzy programisty Java.

Co jednak nie jest już tak oczywiste, to jak niewiele różni obecnie JSE od kolejnego zestawu Java API o nazwie Java Enterprise Edition, w skrócie Java EE, albo po prostu JEE. Zwracam Twoją uwagę na termin "kolejny zestaw Java API". Od lat siedzę przy obu zestawach - JSE i JEE, a jednak dopiero teraz dotarło do mnie, jak niewiele je różni - wszystko za sprawą środowiska uruchomieniowego, które określa zachowanie naszej aplikacji.

Do wersji JSE 5.0 wcale nie było oczywistym, że umiejętność programowania na platformie JSE jest równoznaczna z JEE. Nie grzebiąc za długo w historii JEE postawię tezę, że umiejętność posługiwania się JSE była dalece niewystarczająca od posługiwania się JEE. Wiele się być może nie zmieniło chyba, że nie mówimy o właściwym użyciu API (semantyce), a jedynie umiejętności użycia konstrukcji (składni). Tu widzę duże uproszczenia.

Od wersji JSE5 mamy adnotacje. Możliwość dopisywania metainformacji na różnym poziomie naszych bytów javowych - interfejsów, klas, pól i metod. Szybko zauważono ich zaletę i zaraz wprowadzono na JEE. I jakkolwiek tworzenie aplikacji na poziomie JSE zmieniło się nieznacznie, to w przypadku JEE postęp jest ogromny.

Poniżej klasa do uruchomienia na platformie JSE.
package pl.jaceklaskowski.blog;

public class BlogEntry {
    private String title;

    public BlogEntry(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
    
    public BlogEntry create(String title) {
        return new BlogEntry(title);
    }
}
Od wersji JSE5 można dodawać do klasy metadane w postaci adnotacji. Dwoma z adnotacji dostarczanych w ramach zestawu JEE5 są @Entity oraz @Id.
package pl.jaceklaskowski.blog;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class BlogEntry implements Serializable {

    @Id
    private int id;
    private String title;

    protected BlogEntry() {
    }

    public BlogEntry(String title) {
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public BlogEntry create(String title) {
        return new BlogEntry(title);
    }
}
Poza dodaniem tych dwóch adnotacji pojawiły się również zmiany w samym kodzie klasy. I jakkolwiek samo użycie adnotacji nie wymaga ich, to użycie na platformie JEE może uczynić je obowiązkowymi do poprawnego użycia klasy. Aby ujawniła się ich obowiązkowość konieczne jest uruchomienie klasy w ramach platformy JEE, tj. serwera aplikacyjnego JEE (którego zadaniem jest udostępnienie usług respektujących wytyczne specyfikacji JEE) oraz użycie konstrukcji aktywujących daną funkcjonalność. Innymi słowy, samo uruchomienie w ramach serwera aplikacyjnego JEE nie jest równoznaczne z użyciem usługi, która interpretuje adnotacje. Nie zamierzam jednak tym razem wnikać w szczegóły i unikam wyjaśnień wskazując podręcznik The Java EE 6 Tutorial, a szczególnie rozdział Part VI Persistence. Obowiązkowa lektura dla każdego, któremu marzy się tworzenie aplikacji korporacyjnych w JEE, o których w kolejnych wpisach.

I te małe dodatki - metadane w postaci adnotacji - mnie dzisiaj zachwyciły. Podczas lektury artykułu w Sieci na temat tworzenia Web Services, olśniło mnie, że aplikując adnotacje do klasy i uruchamiając ją w ramach serwera aplikacyjnego dostajemy wiele przy tak niewielkim nakładzie pracy.

Przyjrzyj się poniższej klasie.
package pl.jaceklaskowski.blog;

public class BlogPanel {
    public Blog createBlog(String title) {
        return new Blog(title);
    }
}
Niewiele w niej cech aplikacji korporacyjnej, którą cechuje użycie bazy danych (często wielu równocześnie), dostęp do innych zasobów transakcyjnych, różne protokoły dostępowe (wszechobecny HTTP może być uzupełniany przez chociażby FTP czy IMAP) czy bezpieczeństwo. To tylko niektóre z możliwych usług serwera aplikacyjnego JEE.

Przyjrzyjmy się kolejnej wersji wcześniejszej klasy BlogPanel, która różni się jedynie adnotacją @Stateless.
package pl.jaceklaskowski.blog;

import javax.ejb.Stateless;

@Stateless
public class BlogPanel {
    public Blog createBlog(String title) {
        return new Blog(title);
    }
}
Tym razem, poza @Stateless, nic więcej się nie zmieniło. Czyżby?

Jeśli uruchomisz tę klasę na serwerze aplikacyjnym JEE, okaże się, że wykonanie metody createBlog(String title) pociągnie za sobą wzbudzenie monitora transakcji i uruchomienie dedykowanej transakcji, która rozpocznie się i zakończy z rozpoczęciem i zakończeniem wykonania ciała metody. Dodatkowo, każdemu będzie wolno wykonać tę metodę, ale samo sprawdzenie zostanie wykonane. Jak widać, użycie tak niewinnie wyglądającej adnotacji @Stateless może odmienić zachowanie aplikacji, a jej czas wykonania wydłuży się kosztem opakowania jej usługami serwera.

Tak wiele, tak niewielkim kosztem - odkrywcze podobieństwo między JSE a JEE.

W JEE6 pojawiło się rozszerzenie oferowanego API o pakiety javax.enterprise.inject, javax.enterprise.context oraz javax.enterprise.event, które materializują wytyczne specyfikacji JSR 299: Contexts and Dependency Injection for the Java EE platform, w skrócie CDI. Sama specyfikacja jest częścią Java EE 6 i przez to obowiązkowa w ramach serwerów aplikacyjnych JEE6 (tu należy zwrócić uwagę na wersję wspieranego zestawu JEE - musi być 6).

I tutaj było moje największe odkrycie, a w zasadzie faktyczne przetrawienie wszystkiego, co do tej pory usłyszałem na temat JEE6, EJB 3.1, JSF 2.0, JPA 2.0, Servlets 3.0 i kilku innych.

Wszystkie byty na platformie JEE6 są opisywalne przez adnotacje.

Z tego płynie bardzo istotna wiedza pozwalająca zrozumieć sedno działania serwera aplikacyjnego JEE i związywania usług do odpowiednich składowych (komponentów) naszej aplikacji. Wystarczy zaaplikować adnotację i jak za dotknięciem czarodziejskiej różdżki pojawi się automagicznie pożądana funkcjonalność (ortogonalna do funkcjonalności biznesowej, którą oprogramowujemy i tu jest właśnie miejsca dla naszej inwencji twórczej).

Skoro CDI to specyfikacja odnosząca się do definiowania kontekstu funkcjonowania bytu zwanego ziarnem zarządzanym (ang. managed bean) - wcześniej termin zarezerwowany przez specyfikację JSF) i to właśnie kontekst wyznacza jego cykl rozwojowy (ang. lifecycle) - przejścia między stanami, w których wyróżnionymi są utworzenie i zniszczenie obiektu, wtedy można postawić tezę, że wszystko, co mamy do dyspozycji jako programiści JEE6 można oprzeć na CDI.

W ten sposób Resin - kontener webowy - oferuje EJB 3.1 przez CanDI. Pewnie będzie można zauważyć podobny trend w innych serwerach aplikacyjnych.

CDI jest również możliwe do uruchomienia na platformie JSE6, ale w takiej konfiguracji będziemy musieli rolę serwera przejąć na siebie i oprogramować w ramach aplikacji. Nawet, jeśli CDI i JEE6 nie są doskonałe, to są standardem, który zmierza w dobrym kierunku. Po czasach rozterek JEE vs Spring Framework+Hibernate mam wrażenie, że wybór staje się bardziej oczywisty. Mnie to cieszy.

02 grudnia 2010

73. spotkanie Warszawa JUG - Andrzej Salwicki z "O obiektach aktywnych, obcym wołaniu metod takich obiektów i problemie otwartym?"

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)Warszawska Grupa Użytkowników Javy (Warszawa JUG) zaprasza na 73. spotkanie, które odbędzie się w najbliższy wtorek, 7. grudnia o godzinie 18:00 w sali 5440 Wydziału MIM UW przy ul. Banacha 2 w Warszawie.

Temat: O obiektach aktywnych, obcym wołaniu metod takich obiektów i problemie otwartym?
Prelegent: prof. dr hab. Andrzej Salwicki

Podczas prezentacji omówię obiekty aktywne (rodzaj wątków) i oryginalną, obiektową koncepcję komunikacji/synchronizacji obiektów aktywnych zaproponowaną przez Bolka Ciesielskiego w 1988. Metody obiektu aktywnego mogą dynamicznie zmieniać swój status:
prywatny -> publiczny -> prywatny -> publiczny -> ...
enable m disable m
Wywołanie z obiektu Y metody m w obiekcie X wygląda zwyczajnie (* call *) X.m(...). Różnice sprowadzają się do kilku punktów:
- chociaż obiekt aktywny Y wywołuje metodę m w obiekcie X, to obiekt X ma ją wykonać,
- aby mogło do tego dojść, metoda m obiektu X musi być publiczna (ang. enabled),
- takie obce wołanie metody może być zrealizowane w sposób synchroniczny, spotkanie instrukcji wywołania (w Y) z instrukcją accept (w X), lub w sposób asynchroniczny (wywołanie metody PRZERYWA wykonywanie wątku X'a - X wykonuje metodę m - i wraca do dalszego ciągu swego wątku.

Odczyt przedstawi szczegóły i omówi zalety takiego rozwiazania. Pomysł ten jest wykonalny (sprawdzono w Loglanie'82).

Na zakończenie przedstawimy interfejs AO (obiekt aktywny) i sformułujemy wyzwanie: zaimplementować ten interfejs w Javie lub udowodnić, że nie mozna tego zrobić bez modyfikacji JVM. Za rozwiązanie problemu przysługuje nagroda!

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

Wstęp wolny

Zapraszam w imieniu prelegenta i grupy Warszawa JUG!

01 grudnia 2010

Java EE 6 webapp development with CDI, GlassFish and NetBeans 7

9 komentarzy
Próbowałem się z NetBeans IDE 7.0 (wersja rozwojowa z dzisiaj) i kiedy sprawdzałem możliwości CDI z przekazywaniem (aka wstrzykiwaniem) zależności do servletu przyszło mi do głowy, aby nagrać moje doświadczenia. Nie są one wyrafinowane, ale chodziło mi raczej o popróbowanie się ze skrinkastami w kwadrans, aby nabrać większej umiejętności w tego typu przekazie niż na samej oprawie czy treści. Chciałem również sprawdzić, czy uda mi się opublikować nagranie na YouTube w formacie 1080p.

Zero podkładu głosowego, zero muzyni, niewiele treści merytorycznej, ale nagranie w Full HD jest. Tym samym 3-minutówka znalazła się na YouTube do oceny publiczności.

Teraz kolej na Ciebie. Zadanie na dziś to obejrzenie filmiku i ocena jego przydatności, a właściwie wskazanie niedoskonałości i tym samym zagwarantowanie sobie bardziej przyzwoitej treści w kolejnych odsłonach.

Zapraszam na swój kanał na YouTube do obejrzenia Java EE 6 webapp development with CDI, GlassFish and NetBeans 7.

p.s. Uruchomiłem ankietę "Temat przewodni na grudzień", której celem jest określenie tematyki, którą chciał(a)byś, abym rozpracowywał w ostatnim miesiącu tego roku - grudniu 2010. Zainteresowanych wyrażeniem swojego zdania zapraszam na blog, gdzie po prawej u góry znajduje się ankieta. Sugestie w postaci odpowiedzi "Inne?!" proszę o rozwinięcie na priv, albo w komentarzu do tego wpisu.