пятница, апреля 23, 2010

Apache cassandra map/reduce на windows

В последнее время присматриваясь к апачевскому проекту Cassandra. Думаю о продакшене там говорить пока рано, по крайней мере в 0.6.1, но посмотреть на возможности интересно. Особенно интересен map/reduce (MR).
Классический пример MR - word count, наличествует в contrib\word_count\ дистрибутива кассандры. Запустить его под windows можно либо написав свой батник, либо установив cygwin с bash. В обоих случаях есть нюансы, связанные с тем что Cassandra эксплуатирует MR из Apache Hadoop, а тот в свою очередь при мэпе и редьюсе использует файловую систему и консольные команды posix, которых в windows нет. В частности, когда Hadoop будет писать в файловую систему результаты, будет вызываться chmod, и вы обязательно словите
Exception in thread "main" java.io.IOException: Cannot run program "chmod": CreateProcess error=2, ........................................
at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
at org.apache.hadoop.util.Shell.runCommand(Shell.java:149)
at org.apache.hadoop.util.Shell.run(Shell.java:134)

что значит "на вижу chmod".
Лучше всего chmod видеть в составе cygwin. Устанавливаете bash в cygwin, обязательно дополняете path переменных окружения путем к папке инсталлированного cygwin (path+=C:\cygwin\bin) и вперед!
В варианте запуска через стандарный sh-скрипт из bash (bin/word_count_setup и bin/word_count) нужно иметь ввиду, что в cygwin надо преобразовывать пути с помощью cygpath. Поэтому перед строчкой
$JAVA -Xmx1G -ea -cp $CLASSPATH WordCount
надо обязательно вставить
# Special-case path variables.
case "`uname`" in
CYGWIN*) 
CLASSPATH=`cygpath -p -w "$CLASSPATH"`
;;
esac


Что еще надо помнить - хадуп использует org.apache.commons.logging для логирования, так что качайте и кладите commons-logging-1.1.1.jar в папку lib. А MapReduce использует org.apache.commons.httpclient для общения с нодами, поэтому берите именно commons-httpclient-3.1.jar, поскольку в 4.0 этот проект ушел из коммонс и начал собственную жизнь в http://hc.apache.org.

И еще небольшое замечание - если хотите запускать касандру из cygwin не забудьте установить пакет util-linux в cygwin. Там getopt, который вызывается в 129 строчке bin/cassandra.

четверг, апреля 15, 2010

Spring, JSP и Caused by: org.apache.tiles.util.TilesIOException: ServletException

Допустим мы имеем:
IDE: Eclipse+Jetty Plugin
Build manager:Maven
Приложение - типа jpetstore из семплов спринга, но с тайлсами. Ну то есть Spring MVC 3.0.x, Tiles 2 как template engine, JSP как view.

И вот правишь на живую JSP с ожданием традиционного хотсвопа, а тебе в ответ:

[btpool0-2] DEBUG o.s.web.servlet.DispatcherServlet - Could not complete request
org.apache.tiles.impl.CannotRenderException: ServletException including path '/WEB-INF/layouts/base.jsp'.
Caused by: org.apache.tiles.util.TilesIOException: ServletException including path '/WEB-INF/layouts/base.jsp'.
Caused by: java.lang.LinkageError: loader constraint violation: when resolving field "deferredExpression" the class loader (instance of runjettyrun/ProjectClassLoader) of the referring class, javax/servlet/jsp/jstl/core/LoopTagSupport, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the field's resolved type, javax/el/ValueExpression, have different Class objects for that type

Дебажишь в tomcat - все нормально, хотсвоп работает как надо - никаких эксепшенов. А именно с Eclipse Jetty plugin проблема. После небольшого исследования все встало на свои места.
Оказывается что в плагине используется Jetty 6.1.6 и в jsp-2.1.jar наличествует org\apache\taglibs\standard - то есть jstl. И в типовом pom.xml (из того же jpetstore) для мавена также имеются строчки зависимости:
        <dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>

В итоге мы получаем дублирование jstl и проблему класслоадинга. Так что если вы правите JSP в Jetty, убирайте jstl.

Мой список блогов