Coding with Titans

so breaking things happens constantly, but never on purpose

Jetty na Debian 5.05 Lenny

Kolejny dzień, kolejny problem z serii, “bo coś jest zepsute u podstaw” konfiguracji systemu… Zawczasu ostrzegam, że wpis ten jest wybitnie rozwlekły i nie jest przeznaczony dla osób niecierpliwych.

Zatem po kolei. Będąc zafascynowany “nowymi” rozwiązaniami, postanowiłem w ramach testów uruchomić przykłady z pakietu CometD i zapoznać się nieco z protokołem Bayeux (zainteresowanych tematem odsyłam do dokumentacji projektu). Oczywiście nic prostszego - wchodzimy na stronę projektu, pobieramy odpowiednie źródła, wypakowujemy CometD i uruchamiamy Jetty, które instaluje w sobie odpowiednie rozszerzenie. Wszystko bardzo ładnie w kilku zdaniach opisane jest tutaj.

Jakież wyrazy cisną nam się na usta, gdy ściągane są kolejne pakiety idące już prawie w gigabajty (do Javy, Apache, Maven2, itp…). Mija w końcu to niesłychanie długie 20 minut i oczom naszym ukazuje się Jetty w pełnej krasie. Ostrzegam, że jeszcze nawet nie zaczęliśmy grzebać w naszym testowym Debianie, a przecież chwilkę temu pobraliśmy najnowsze wersje całego oprogramowania na świecie.

~/cometd-2.0.0/cometd-demo$ mvn jetty:deploy-war
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'jetty'.
[INFO] ------------------------------------------------------------------------
[INFO] Building CometD :: Demo
[INFO] task-segment: [jetty:deploy-war]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing jetty:deploy-war
[INFO] [enforcer:enforce {execution: enforce-plugin-versions}]
[INFO] [jetty:deploy-war]
[INFO] Configuring Jetty for project: CometD :: Demo
[INFO] Context path = /
[INFO] Tmp directory = /home/pawel/cometd-2.0.0/cometd-demo/target/tmp
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] Web overrides = none
[INFO] Starting jetty 7.1.5.v20100705 ...
2010-09-05 01:29:34.971:INFO::jetty-7.1.5.v20100705
2010-09-05 01:29:37.803:WARN::EXCEPTION
java.lang.NullPointerException
    at javax.naming.spi.NamingManager.getPlusPath(libgcj.so.90)
    at javax.naming.spi.NamingManager.getStateToBind(libgcj.so.90)
    at org.eclipse.jetty.jndi.NamingContext.bind(NamingContext.java:337)
    at org.eclipse.jetty.jndi.NamingContext.bind(NamingContext.java:415)
    at org.eclipse.jetty.jndi.java.javaRootURLContext.(javaRootURLContext.java:78)
    at java.lang.Class.initializeClass(libgcj.so.90)
    at org.eclipse.jetty.jndi.java.javaURLContextFactory.getObjectInstance(javaURLContextFactory.java:63)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.90)
    at javax.naming.spi.NamingManager.getURLContext(libgcj.so.90)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(libgcj.so.90)
    at javax.naming.InitialContext.lookup(libgcj.so.90)
    at org.eclipse.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:202)
    at org.eclipse.jetty.plus.webapp.EnvConfiguration.preConfigure(EnvConfiguration.java:62)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:378)
    at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:114)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
    at org.eclipse.jetty.server.Server.doStart(Server.java:242)
    at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:67)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:437)
    at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
    at org.mortbay.jetty.plugin.JettyRunWarMojo.execute(JettyRunWarMojo.java:68)
    at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:512)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:482)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
    at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
    at java.lang.reflect.Method.invoke(libgcj.so.90)
    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)

A później jest już prościej, bo co sekundę wyskakuje wyjątek (co zdecydowanie lepiej rzuca się w oczy):

2010-09-05 01:38:42.200:WARN::EXCEPTION java.lang.ClassCastException: gnu.java.nio.ServerSocketChannelImpl cannot be cast to java.nio.channels.SocketChannel
    at org.eclipse.jetty.io.nio.SelectorManager$SelectSet.doSelect(SelectorManager.java:708)
    at org.eclipse.jetty.io.nio.SelectorManager.doSelect(SelectorManager.java:195)
    at org.eclipse.jetty.server.nio.SelectChannelConnector.accept(SelectChannelConnector.java:134)
    at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:793)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:436)
    at java.lang.Thread.run(libgcj.so.90)

Jednym słowem czad!

No niby prosty przykład, a ile radości. Cóż, znowu ktoś zawinił. Tym bardziej ciekawe jest kto oraz że na forum projektu milczą o tym błędzie, jakby się wszyscy pod ziemię zapadli. Podpowiem, że projekty (CometD oraz sam Jetty) dostępne sąt od kilku ładnych lat i na pewno ktoś by się z tym problemem zetknął. Chyba nie jestem aż takim szczęściarzem. A może jednak to jest jakaś niszowa przypadłość? Bynajmniej. Troszkę szperania i co się okazuje. Otóż ani PATH ani JAVA_HOME nie pokazują lokalizacji JVM (Java Virtual Machine). Dokumentacja do Jetty mówi o tym wyraźnie. Ustawiamy ścieżkę do /usr/lib/jvm/java-1.5.0-gcj-xxx i wszystko powinno ruszyć. Teoretycznie. W praktyce, dostajemy dokładnie ten sam błąd. No jakoś się całe środowisko pokumało, że tylko jedna wersja Javy była zainstalowana i nawet bez JAVA_HOME udało się ją załadować. No to może jeszcze inaczej, może gdzieś, jakiś przełącznik, jakaś aktualizacja, patch rejestru (dobra to nie Windows), symlink? wrr, cokolwiek.

Otóż nie. To, co zazwyczaj okazuje się poprawne, zazwyczaj też siedzi na samym szarym końcu rozwiązań i ostatnie wpada do głowy. Cały JVM jest do wyrzucenia :) No bo przecież GNU Java nie jest zgodna z Sun Java (tu wstaw dowolną wersję), bo i po co? Jakichże to kolorów nabiera wtedy życie…

Tak, ale instalacja oryginalnej ‘sunowskiej’ Javy też nie jest wcale taka prosta. Aby uzyskać dostęp do wersji Javy (Sun JDK 1.5 i JDK 1.6), niezbędny jest na początku dodatkowy wpis w konfiguracji apt-get. Te JDK-i oznaczone są bowiem jako “non-free” i musimy zaakceptować dodatkową licencję zanim będziemy mogli z nich skorzystać.

  • Dopisujemy więc na końcu pliku konfiguracyjnego apt-get (/etc/apt/sources.list) następującą linijkę:
deb http://ftp.debian.org/debian lenny main contrib non-free
  • Odświeżamy listę dostępnych pakietów:
apt-get update
  • Instalujemy Javę (kawę i kolejne 20 min mamy już tym razem w pogotowiu):
apt-get install sun-java6-jdk
apt-get install sun-java5-jdk
  • Na koniec, ustawiamy ją jako domyślną w systemie:
update-java-alternatives -s java-6-sun 
echo 'JAVA_HOME="/usr/lib/jvm/java-6-sun"' | tee -a /etc/environment
  • Gotowe! Uruchamiamy ponownie skrypt Maven, który uruchamia Jetty i instaluje w nim CometD. Tym razem z powodzeniem pod adresem http://localhost:8080/ mamy już działające przykłady i użycie Bayeux! Nic dodać nic ująć.

Jednak wieczór można uznać za udany. Szkoda tylko, że nie to mi go skradło, na co chciałem go przeznaczyć…

Dziękuję za uwagę.