суббота, марта 26

JSP и вывод таблиц с "отсутствующими" строками

написание поста навеяно следующим комментарием:
на практике часто возникает задача отображать данные в виде списка или таблицы, но случай, когда данных нет, требуется обрабатывать особо. Например, в случае с Java и JSTL код темплейта оказывается весьма тяжеловесным, и я, признаться, не встречал особенно выдающихся альтернатив

Приведу как минимум 2 примера, на вскидку, для решения вышеозвученной "проблемы".

Исходные данные:
<java>
Class Row{
private int id;
private String text;
... вырезанные getters & setters ...
}

List rows; // Количество элементов от 0 до n
</java>

Способ первый: "прямой" вывод данных с помощью смеси JSTL+HTML
<jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<table>
 <thead>
  <tr>
   <th>id</th>
   <th>text</th>
  <tr>
 </thead>
 <tbody>
  <c:choose>
   <c:when test="${fn:length(rows)>0}">
    <c:forEach var="row" items="${rows}">
     <tr>
      <td>${row.id}</td>
      <td>${row.text}</td>
     </tr>
    </c:forEach>
   </c:when>
   <c:otherwise>
    <tr>
     <td colspan="2">Нет данных для вывода</td>
    </tr>
   </c:otherwise>
  </c:choose>
 </tbody>
</table>
</jsp>

Способ второй: с помощью DisplayTag
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://displaytag.sf.net" prefix="display"%>
<display:setProperty name="basic.empty.showtable" value="true"/>
<display:setProperty name="basic.msg.empty_list" value="Нет данных для вывода"/>
<display:table name="rows">
 <display:column property="id" />
 <display:column property="text" />
</display:table>



Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

четверг, марта 17

Lotus Notes/Domino & XStream

Настройка Lotus Domino для работы с библиотекой XStream.

1) копируем файлы xstream-{version}.jar и xpp3_min-{version}.jar (это на тот случай, если вместо DomDriver вы хотите использовать XppDriver) в каталог {DOMINO_BIN}/jvm/lib/ext
2) в файле {DOMINO_BIN}/jvm/security/java.policy в блоке "grant" дописываем строку (не наступите на грабли) :
grant { ... permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; }
3) перезагружаете сервер Lotus Domino

Для возможности использования подсказок в Lotus Domino Designer на базе Eclipse, потребуется положить библиотеки и на рабочей станции разработчика в каталог {NOTES_BIN}/jvm/lib/ext и перезапустить клиента

ЗЫ: Если что-то настроено неправильно, то в логах буду сыпаться сообщения похожие на это:
... Agent error: java.lang.ExceptionInInitializerError: Cannot access defaults field of Properties Agent error: java.lang.NoClassDefFoundError: com.thoughtworks.xstream.converters.collections.PropertiesConverter (initialization failure) Agent error: at java.lang.J9VMInternals.initialize(J9VMInternals.java:140) Agent error: at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:647) Agent error: at com.thoughtworks.xstream.XStream.(XStream.java:445) Agent error: at com.thoughtworks.xstream.XStream.(XStream.java:385) Agent error: at com.thoughtworks.xstream.XStream.(XStream.java:342) ...

ЗЫЫ: при разработке под Lotus Domino 8.x уже можно использоваться аннотации (в eclipse-based редакторе, при сохранении, будет предложено повысить версию java-проекта до 1.5 для компиляции)


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

понедельник, марта 14

Lotus Domino & java.policy

мелкие баги бывают такие разные и противные...

вот например, стабильно в консоли получал на любой "чих" ошибку "error: java.security.AccessControlException: Access denied (java.lang.RuntimePermission setContextClassLoader)"
Перековырял всё, а ошибка всё не уходит...

В какой-то момент осенило - проблема может быть не в нехватке прав, а в самом проблемном файле java.policy. Беру "эталонный" файлик с другого сервера, подставляю и вуаля - всё работает!

беглый анализ произошедшего нашел и виновника возникшей оказии: сервер расположен на Windows, файлик правился из Linux, в итоге в файле образовались иные "переносы строк" - вот на этом IBM JDK и запнулась и перестала и вовсе читать конфигурацию. А внешне файл выглядел нормально что в Windows (блокнот), что в Linux


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

понедельник, февраля 14

Все дни программиста/интернета в одном флаконе

По поводу такого праздника как день программиста существует масса домыслов. Потому что день программиста в году не один. Вообще-то, каждый рабочий день (особенно пятница) является днём программиста. Но всё же вот более-менее полный список подходящих дат, отмечаемых энтузиастами в разных странах.

14 февраля. День запуска компьютера ENIAC (1946)

4 апреля. День Сети. 4.04 можно прочитать как 404 - номер самой популярной в Интернет ошибки протокола HTTP ("Страница не найдена"). В католической церкви, кроме того, 4 апреля - день святого Исидора, неофициально считающегося покровителем компьютеров и Интернета. Исидор был, возможно, первым энциклопедистом в мире (20-томная Etymologiae).

7 апреля. Иногда празднуется, как День рождения Рунета. В этот день в 1994 г. был зарегистрирован российский домен ru.

22 апреля. Прежний советский код специальности "программист" был именно 2204 ("Программное обеспечение вычислительной техники и автоматизированных систем").

17 мая. Этот день Генеральная Ассамблея ООН утвердила как день информационного сообщества (2006). В настоящее время официально называется всемирным днём электросвязи и информационного общества.

19 июля. Неофициальная дата написания первой программы (1843). Написала её Ада Лавлейс (см. 10 декабря).

Последняя пятница июля. День системного администратора - придуманный американскими сисадминами неофициальный праздник.

Первая пятница сентября. Неофициальный "День компьютерщика", придуманный издательским домом "Компьютерра" (1996). С праздником связан ритуал "чистой пятницы" - то есть, удаления ненужных файлов.

256-й день года (13 сентября в обычные годы, 12 сентября в високосные). Официально объявлен днём программиста указом президента Д. Медведева (2009)

30 сентября. День интернета, известный только в России. Приурочен к 1-й "переписи" населения Рунета (1998, придумано IT Infoart Stars).

4 декабря. День регистрации изобретения цифровой электронной вычислительной машины в СССР (1948). Неофициальная дата рождения советской информатики.

10 декабря. День рождения Ады Лавлейс, первого программиста (точней, программистки) в мире (1810). Кстати, графиня Лавлейс была единственной дочерью "того самого" Байрона.

Таким образом, имеем минимум 0b1100 поводов выпить.)

©тыбрено тут

воскресенье, января 30

SSH и шифрованный known_hosts

Какое-то время "ругался" на то, что в Ubuntu файл known_hosts по-умолчанию шифрует имена доменов - любил совмещать строчки, когда несколько доменов на одном IP, ибо было удобно (хотя и крайне редко требовалось) обновлять ключ.
А тут наткнулся на такую же "проблему" и на её решение через команду и мои "проблемы" сняло как рукой :)

В общем, что мы вокруг да около.
Для того, чтобы удалить из known_hosts устаревший ключ, выполняем команду "ssh-keygen -R host_name|IP", после чего повторно пробуем зайти на удалённый сервер.

там же, есть ссылка на интересную статью Максима Коновалова с писанием поддержки отпечатков SSH в DNS (RFC-4255).

среда, января 19

VirtualBox 4.0 и поддержка плагинов

Начиная с версии 4.0 многоуважаемая компания Oracle добавила поддержку плагинов в VirtualBox и вынесла поддержку USB 2.0 в отдельный плагин. Плагин "Oracle VM VirtualBox Extension Pack" добавляет поддержку "USB 2.0 Host Controller, VirtualBox RDP, PXE ROM with E1000 support"

Не, моя конечно понимай, что плагины это удобно, но... моя долго думать нафига вынесли в плагин, который нужно качать отдельно, то, что раньше работало "изкаропки"?

понедельник, января 10

Ubuntu Desktop + LVM. Умный в гору не пойдёт...

Можно пойти так, как "нашпиговано" в ентом вашем ынтырнете и через всякие Ubuntu LiveCD и прочую хрень из консоли хреначить сперва ручками весь LVM, потом на него "натягивать" Desktop.
А можно пойти ПРОЩЕ:
1) качаем Ubuntu Server
2) устанавливаем дистрибутив через его стандартный GUI с разметкой LVM
3) Сразу после загрузки (предполагаем, что у нас тырнет ужо настроен) выполняем команду "apt-get install ubuntu-desktop"
4) перезагружаемся и... вах, шайтан - да перед нами обычный Ubuntu Desktop!

ЗЫ: я, правда, после этого ещё ядро переставил с серверного на десктопный) но это кому какие фломастеры нужны. Да ещё парочку PPA добавил, чтоб некоторый софт посвежее был)


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

четверг, декабря 30

Tomcat и JSESSIONID

Для того, чтобы изменить имя переменной сессии с "JSESSIONID" на, к примеру, "SID", достаточно в файле $CATALINA_HOME/bin/setenv.sh прописать следующую строчку:
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.SESSION_COOKIE_NAME=SID -Dorg.apache.catalina.SESSION_PARAMETER_NAME=sid"

ЗЫ: не забудьте перезапустить Tomcat
ЗЫЫ: в браузерах с залогиненными пользователями кука JSESSIONID не переименуется :) Просто добавится ещё одна с тем же значением

пятница, декабря 10

Tomcat и виртуальный хостинг. часть 2: добавление виртуального хоста

Ранее мы настроили связку Nginx+Tomcat для хостинга. Давайте теперь добавим виртуальный домен example.org

Шаг 1: настраиваем nginx

создаём файл /srv/nginx/vhost_01_example.org.conf:
server { listen 80; server_name example.org *.example.org location / { proxy_pass http://127.0.0.1:8080; include /srv/nginx/proxy.conf; } }

Теперь вы можете выполнить команду "service nginx reload" и, открыв в браузере адрес http://example.org, увидеть домашнюю Tomcat-страницу

Шаг2: настраиваем Tomcat

# cd /srv/tomcat
# mkdir webapps/example.org
# sed -e 's/localhost/example\.org/g' conf/server.d/vhost-localhost.xml > conf/server.d/vhost-example.org.xml

правим server.xml, добавляя новые строки:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE server-xml [ <!ENTITY vhost-localhost SYSTEM "server.d/vhost-localhost.xml"> <!ENTITY vhost-example.org SYSTEM "server.d/vhost-example.org.xml"> ]> ... &vhost-localhost; &vhost-example.org; </Engine> ...

Теперь нужно настроить пользователя для менеджера виртуального хоста.

Добавим нового пользователя manager-example.org с новой одноимённой ролью в /srv/tomcat/conf/tomcat-users.xml:
<role rolename="manager-example.org" />
<user username="manager-example.org" password="12345678" roles="manager-example.org" /&rt;
и внесём изменения в конфигурационный файл Manager-приложения:
# cp -R webapps/localhost/manager webapps/example.org/
# cd webapps/example.org/manager/WEB-INF
# sed -i.bak 's/<role-name>manager<\/role-name>/<role-name>manager-example.org<\/role-name>/g' web.xml

Перезапускаем томкат:
# chown -R tomcat:tomcat /srv/tomcat
# service tomcat6 stop
# tail -f /srv/tomcat/logs/catalina.out ;Ждём остановки Tomcat и жмём Ctrl+C
# service tomcat6 start

Открываем в браузере адрес http://example.org/manager/html и на запрос авторизации вводим логин/пароль для пользователя manager-example.org.

На этом базовая настройка виртуального хоста example.org завершена.


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!

Tomcat и виртуальный хостинг. часть 1: связка Nginx + Tomcat

Рано или поздно приходишь к тому, что на сервере Tomcat хочется держать не только один сайт. можно конечно же разные сайты делить за тем же Nginx по запросам к подкаталогу "/domain-name", но правильнее будет сделать разнесение по виртуальным хостам. ещё правильнее - разнести "клиентов" ещё и по разным инстансам tomcat (чтобы они "соседей" не "завалили"), но это покажу как-нибудь в другой серии постов.
Итак, наша задача - настройка Tomcat на работу с виртуальными хостами

С чего мы начнём? с базового задела Tomcat под поставленную задачу - со связки Nginx+Tomcat (помимо плюсов самого Nginx, нам не придётся думать об уровне доступа Tomcat для прослушки 80-го порта)

Настройка производится на сервере CentOS 5.5 (но думаю, что и на других версиях не будет отличий ;) ). Так же на сервере должен быть открыт 80-й порт

Устанавливаем nginx "по умолчанию":
# yum install nginx

создаём каталог /srv/nginx и меняем ему владельца и группу на nginx (в этом каталоге мы будем хранить настройки виртуальных хостов для nginx):
# mkdir -p /srv/nginx
# chown nginx:nginx /srv/nginx


правим файл /etc/nginx/conf.d/virtual.conf
# mv /etc/nginx/conf.d/virtual.conf /etc/nginx/conf.d/virtual.conf.orign
# echo "include /srv/nginx/vhost_*.conf;" > /etc/nginx/conf.d/virtual.conf

создаём файл /srv/nginx/proxy.conf со следующим содержимым:
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;

это общие настройки для всех виртуальных хостов. В последующем можно будет дописать или поправить его содержимое.

создаём хост "по-умолчанию", для этого создаём файл /srv/nginx/vhost_00_default.conf:
server { listen 80 default; location / { proxy_pass http://127.0.0.1:8080; include /srv/nginx/proxy.conf; } }

Теперь переходим к базовой установке и настройке Tomcat
Скачиваем и распаковываем дистрибутив Apache Tomcat (повествую на примере версии 6.x)
# cd /srv
# wget http://www.sai.msu.su/apache/tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.tar.gz
# tar xvf apache-tomcat-6.0.29.tar.gz
# mv apache-tomcat-6.0.29 tomcat
# useradd -d /srv/tomcat -s "/sbin/nologin" tomcat

для запуска демона Tomcat от пользователя tomcat можно скомпилировать jsvc, но мне больше нравится нижеприведённый скрипт /etc/init.d/tomcat6:
#!/bin/sh # # /etc/init.d/tomcat6 # # This is the init script for starting up the # Jakarta Tomcat Server # # chkconfig: 234 20 80 # description: Starts and stops the Tomcat daemon # processname: tomcat # # source functions library for 'daemon' function . /etc/init.d/functions TOMCAT_HOME=/srv/tomcat TOMCAT_START=$TOMCAT_HOME/bin/startup.sh TOMCAT_STOP=$TOMCAT_HOME/bin/shutdown.sh TOMCAT_USER=tomcat start() { echo -n $"Starting Tomcat service: " daemon --user $TOMCAT_USER $TOMCAT_START RETURN_CODE=$? echo $? } stop() { echo -n $"Stopping Tomcat service: " daemon --user $TOMCAT_USER $TOMCAT_STOP RETURN_CODE=$? echo $? } status() { ps aux | grep tomcat | grep -v grep } # Handle the different input options case "$1" in start) start ;; stop) stop ;; status) status ;; *) echo $"Usage: $0 {start|stop|status}" exit 1 esac exit 0

Теперь переходим к небольшому "тюнингу" Tomcat, для дальнейшего удобства его администрирования

Для начала, поправим файл /srv/tomcat/conf/server.xml (далее просто server.xml) для работы с Nginx. Для этого найдём
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"redirectPort="8443" />
и заменим её на
<Connector address="127.0.0.1" port="8080" protocol="HTTP/1.1" connectionTimeout="20000"redirectPort="8443" />
тем самым мы укажем Tomcat, чтобы он слушал порт 8080 только локально

Перейдём к настройке хостов.

удобнее всего править настройки хостов не выискивая их в "портянке" файла server.xml, а вынеся настройки каждого хоста в отдельный файл. Для этого произведём некоторые изменения в файле server.xml

изменяем "шапку" файла, дописав блок DOCTYPE:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE server-xml [ <!ENTITY vhost-localhost SYSTEM "server.d/vhost-localhost.xml"> ]>

создадим подкаталог server.d, в котором будут лежать конфигурационные файлы наших виртуальных хостов:
# cd /srv/tomcat/conf
# mkdir server.d

Вынесем в отдельный файл настройки для localhost... Для этого найдём в server.xml блок "<Host>...</Host>" и сохраним его в server.d/vhost-localhost.xml:
# cd /srv/tomcat/conf
# echo "<?xml version='1.0' encoding='utf-8'?>" > server.d/vhost-localhost.xml
# sed -n -e '/[[:space:]]*<Host.*/,/[[:space:]]<\/Host>/p' server.xml >> server.d/vhost-localhost.xml
# sed -i.bak -n '1h;1!H;${x;s/<Host.*<\/Host>/\&vhost-localhost;/;p}' server.xml

Для работы Tomcat требуется установленная на сервере Java-машина. Путь до неё прописывается в файле /srv/tomcat/bin/setenv.sh:
# echo "JAVA_HOME=/usr/java/default" > /srv/tomcat/bin/setenv.sh

Следующий наш шаг - настройка каталога webapps для будущих виртуальных каталогов
# cd /srv/tomcat
# sed -i 's/webapps/webapps\/localhost/' conf/server.d/vhost-localhost.xml
# mv webapps localhost
# mkdir webapps
# mv localhost webapps/

и заваршающее действие:
# chown -R tomcat:tomcat /srv/tomcat

Готово. теперь можно запускать созданный web-сервер:
# service tomcat6 start
# service nginx start

Зайдите в браузере по адресу http://ваш_сервер - вы должны увидеть Tomcat-страницу по-умолчанию.

Если всё правильно настроено и вы увидели страницу Tomcat, то можно установить автозапуск для демонов:
# chkconfig nginx on
# chkconfig --add tomcat6
# chkconfig tomcat6 on

ЗЫ: комментарии и замечания приветствуются :)

UPD: изменил немного скрипты - местами удалил "ручную" работу и описал для Tomcat 6 вместо Tomcat 7


Если вам пригодилась статья, то отправьте 5 рублей автору. Спасибо!