Показаны сообщения с ярлыком Java. Показать все сообщения
Показаны сообщения с ярлыком Java. Показать все сообщения

28 июня 2016 г.

Как отсыпать совсем немножечко рута для Java и разрешить захватывать сетевые пакеты

В различных дистрибутивах Linux такие программы, как tcpdump и wireshark, использующиеся для анализа сетевого трафика, обычно требуют прав суперпользователя для получения доступа к возможностям захвата пакетов. Точно также дело обстоит и с Java-программами, которые используют системную библиотеку libpcap. Причем в этом случае вам придется запустить с неограниченными правами саму виртуальную машину Java, которая уже в свою очередь будет исполнять ваш код. Я думаю, мало кто любит лишний раз сорить суперправами направо и налево, поэтому в Linux, начиная с ядра 2.2 появилась такая штука, как Linux Capabilites, которая позволяет наделить непривилегированные процессы только необходимыми возможностями суперпользователя. В данном случае, например, нас интересует только возможность перехвата и отправки сетевых пакетов. Для установки и просмотра Linux Capabilites необходимы программы setcap и getcap, соответственно. У меня в openSUSE эти утилиты находятся в пакете libcap-progs, а в Ubuntu в пакете libcap2-bin.

Установка возможности захвата и отправки сетевых пакетов и возможности изменения конфигурации интерфейсов выглядит так:
setcap cap_net_raw,cap_net_admin=eip /usr/local/lib64/jdk1.8.0_77/bin/java
Просмотр установленных возможностей:
getcap /usr/local/lib64/jdk1.8.0_77/bin/java
/usr/local/lib64/jdk1.8.0_77/bin/java = cap_net_admin,cap_net_raw+eip
Всё просто, но если после установки этих возможностей попробовать запустить программу java из под обычного пользователя, то это не очень получится:
java -version
java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
Это происходит из-за того, что при наличии у непривилегированного процесса возможностей, которыми он вроде как обладать не должен, загрузчик динамических библиотек запрещает загрузку библиотек из недоверенных каталогов. Доверенными каталогами по умолчанию являются /lib и /usr/lib (а также /lib64 и /usr/lib64).

С помощью утилиты ldd посмотрим, какие динамические библиотеки использует java: 
ldd /usr/local/lib64/jdk1.8.0_77/bin/java
        linux-vdso.so.1 (0x00007ffc91ffd000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc3dc124000)
        libjli.so => /usr/local/lib64/jdk1.8.0_77/bin/../lib/amd64/jli/libjli.so (0x00007fc3dbf0d000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fc3dbd09000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fc3db961000)
        /lib64/ld-linux-x86-64.so.2 (0x00005584e041d000)
Как видно из вывода команды ldd, при запуске java не удалось загрузить как раз ту самую библиотеку, которая находится в недоверенном каталоге ../lib/amd64/jli/.

Это можно легко пофиксить, добавив файл с расширением .conf  в каталог /etc/ld.so.conf.d, в котором перечислить все необходимые пути. В случае с java это всего лишь один каталог:
echo /usr/local/lib64/jdk1.8.0_77/lib/amd64/jli > /etc/ld.so.conf.d/java.conf
После изменения файлов в /etc/ld.so.conf.d может потребоваться перестроить кэш библиотек, для этого нужно выполнить:
ldconfig
Проверяем, что загрузчик видит нашу библиотеку:
ldconfig -v |grep jli
/usr/local/lib64/jdk1.8.0_77/lib/amd64/jli:
     libjli.so -> libjli.so
Ну и на всякий случай, команда для удаления всех дополнительных возможностей у программы:
setcap -r /usr/local/lib64/jdk1.8.0_77/bin/java
Ещё хотелось бы отметить, что не стоит без лишней необходимости добавлять нестандартные возможности вашей глобальной системной Java-машине, потому что в этом случае любая запущенная Java-программа сможет ими воспользоваться. Для разработки и запуска программ с завышенными потребностями лучше завести отдельный экземпляр Java-машины.

Где отрыто

Как приструнить Wireshark
Небаг в багтрекере Java
Куришка: man capabilities


28 марта 2016 г.

Установка Java Development Kit в Linux из архива tar.gz

Данный пост, это просто обновление поста 2010 года, который до сих пор пользуется довольно большой популярностью, а так как с тех времен уже немало воды утекло, то я посчитал своим долгом актуализировать эту информацию. По пути также кое-что было переработано, надеюсь, в сторону понятности.
Если вам потребовался стандартный JDK от Oracle, вместо OpenJDK, который поставляется с современными свободными дистрибутивами Linux, то его можно скачать либо с дополнительных сторонних репозиториев для вашего дистрибутива, либо напрямую с сайта www.oracle.com. Если ставить Java из репозиториев для вашего дистрибутива, то скорее всего всё само настроется и заработает, и ни о чем беспокоится вам не придется, но если вы скачали JDK или JRE в виде архива tar.gz с сайта Oracle, придется совершить несколько дополнительных телодвижений.

На данный момент скачать JDK с сайта Oracle можно в двух видах: это RPM-пакет и вышеупомянутый архив tar.gz. Про то, на сколько удачно ставится JDK из RPM-пакета, мне сказать нечего - не пробовал. Я предпочитаю устанавливать JDK именно из архива, потому что так я получаю полное управление и понимание того, что и откуда у меня будет запускаться, а также универсальное решение, которое подойдет для всех дистрибутивов, а не только для RPM-based.

План действий
  1. Скачать нужную версию JDK (архив tar.gz)
  2. Распаковать архив
  3. Настроить переменные окружения
  4. Настроить update-alternatives
Куда распаковать?

Итак, скачали JDK. Распаковываем. Но куда? Вроде бы тупой вопрос, но я далеко не сразу пришёл к правильному  для себя  решению. Сейчас я все JDK распаковываю в каталог /usr/local/lib64 и там у меня одновременно живёт несколько версий JDK. Например, на данный момент, там у меня есть каталоги jdk1.7.0_79 и jdk1.8.0_77. В дополнение к этим каталогам, в /usr/local/lib64 у меня находится симлинк с именем jdk, который сегодня чаще всего указывает на каталог jdk1.8.0_77. К такой конфигурации я пришел, когда потребовалось периодически переключаться между различными версиями JDK, причем переключаться нужно было глобально во всей системе. Каким образом такая конфигурация помогает переключаться между версиями, станет понятно ниже.

29 октября 2013 г.

Выбор года и месяца в GWT DatePicker с помощью ListBox

Стандартный DatePicker в GWT очень неудобный. Для выбора нужного года и месяца пользователь вынужден кликать по соответствующим стрелочкам и перемещаться на один месяц вперед или на зад. Например, если пользователю необходимо выбрать свою дату рождения, скажем, 29 февраля 1980 года, а в календаре по умолчанию установлена текущая дата 25 октября 2013 года, то представьте сколько раз нужно будет кликнуть бедняге по стрелочке, чтобы добраться до дня своего рождения!
Стандартный DatePicker в GWT
Конечно, в качестве простого решения, можно просто дать пользователю возможность ввести дату самому в текстовое поле. И в общем-то нет, наверное, ничего плохого в таком решении. Но иногда просто хочется сделать немного более красиво. В этом смысле Datepicker из jQuery UI вполне себе красив и позволяет выбирать год и месяц с помощью выпадающих списков, что очень сокращает путь до необходимой даты.

jQuery Datepicker
На самом деле, такую же возможность очень несложно реализовать и в GWT DatePicker. Для этого нужно просто написать свою собственную реализацию абстрактного класса MonthSelector, который представляет из себя визуальный компонент, отвечающий за установку текущего года и месяца в DatePicker. 

15 ноября 2012 г.

Сборка jNetPcap из исходников в openSUSE 12.1

Набрел тут на интересную java-обёртку для libpcap. Называется она jNetPcap. По описаниям и примерам выглядит достойно. Но главное, что в отличие от Jpcap, с которой я как-то давненько имел интимные отношения, jNetPcap продолжает развиваться.

Если кто не в курсе, кратко поясню, что libpcap это библиотека для захвата и анализа пакетов, проходящих через сетевые интерфейсы. Её, например, используют такие программы, как wireshark, tcpdump, nmap, ipcad и многие другие.

На сайте разработчиков, есть готовые сборки для Ubuntu, RedHat Enterprise, Fedora и Windows. Архив сборки содержит два интересующих меня файла jnetpcap.jar и libjnetpcap.so. Сборка для Fedora сомнительно, но гордо называется Linux (Generic). Сначала я попробовал именно её. При запуске примера она искала libpcap.so.0.9, но ничего не нашла, т.к. у меня стоит версия 1.3.0. В принципе, простой симлинк в /usr/lib libpcap.so.0.9 -> libpcap.so.1.3.0 решает проблему, и пример начинает работать, но что-то меня смущает такая большая разница в версиях libpcap. Поэтому пришлось собирать jNetPcap из исходников.

Сборка прошла не совсем гладко, поэтому оставлю тут для себя, а может и ещё для кого, заметку поэтому поводу.

Теперь кратко о проблемах:
  1. При попытке собрать jnetpcap.jar (команда ant build-jar):
    [taskdef] Could not load definitions from resource cpptasks.tasks. 
    It could not be found.
    
    [typedef] Could not load definitions from resource cpptasks.types.
    It could not be found.
    
    build.xml:119: taskdef class org.vafer.jdeb.ant.DebAntTask cannot be found 
    using the classloader AntClassLoader[]
    
  2. При попытке собрать libjnetpcap.so (команда ant comp-jni-linux):
    [cc] /home/eqlbin/SRC/jnetpcap-src-1.3.0-1/src/c/jnetpcap.cpp:996:6: 
    error: invalid suffix "xpackage" on integer constant
    
    [cc] :0:1: error: "not" cannot be used as a macro name as it is an
    operator in C++
    
Я, честно говоря, не совсем понял, как надо правильно настраивать сборку по мнению самих разработчиков, и в документации ничего путного не нашлось, а долго ковырять чужой билд-скрипт и проперти-файлы желания большого не было, поэтому проблемы решил так как получилось :)

Для сборки, помимо JDK, понадобятся такие естественные штуки, как gcc, gcc-c++, libpcap-devel, ant, ant-junit, ant-contrib. Возможно я что-то упустил, но это основное.

Поехали:
  1. Качаем и распаковываем исходники jNetPcap в гипотетический каталог ~/jnetpcap-src
  2. Качаем cpptasks для ant и кладём файл cpptasks.jar например в ~/jnetpcap-src/lib
  3. Дальше, если у вас есть желание создать из всего хозяйства файл deb, то понадобится найти библиотеку jdeb.jar с соответствующими тасками для ant. Её можно найти уже собранную или же собрать самому. У меня такого желания не образовалось, поэтому я просто  закомментировал строку в файле build.xml:
  4. Теперь необходимо подправить build.xml, чтобы ant смог найти cpptasks.jar и jdeb.jar (если вы, используете jdeb и не закомментировали строку, как в п.3): Вот это: Надо привести к виду, вроде этого: Всё, конечно, зависит от того, как называются ваши jar-файлы и где они лежат... Короче, думаю, что и так тут всё ясно.
  5. Добавить в файл Linux.properties строку compiler.LIBPCAP_VERSION = 100
  6. Запустить ant clean comp-jni-linux build-jar
  7. Забрать из ~/jnetpcap-src/build/lib вожделенные jnetpcap.jar и libjnetpcap.so (там еще у меня появился файл libjnetpcap.so.1.3.0, но судя по его размеру, это тот же libjnetpcap.so)

P.S. - Если build.xml кажется вам страшным и непонятным, почитайте это.

28 апреля 2012 г.

Автоматическое создание Runnable JAR в Eclipse и ресурсы

Когда разрабатывается относительно небольшое десктопное приложение на Java, частенько возникает вполне, на мой взгляд, естественное желание запихать все классы, библиотеки и ресурсы в один исполняемый JAR-файл. В некоторых случаях именно такое решение является предпочтительным.

В Eclipse IDE это можно сделать очень легко и, кроме того, автоматизировать это действие, чтобы в дальнейшем делать сборку JAR одной кнопкой.

Сборка 

Кликаем правой кнопкой по проекту, который надо упаковать в исполняемый JAR и нажимаем Export.

В окне выбираем Java -> Runnable JAR и жмём Next

11 апреля 2012 г.

Установка Magnolia Community Edition из WAR-файла

Magnolia Community Edition на первый взгляд очень достойная современная WCMS с открытым исходным кодом. Для её познания есть довольно неплохая документация и wiki. Однако, есть у меня подозрения, что эта штука не относится к числу простых и легкоподнимаемых CMS. Но выглядит, повторюсь, очень достойно. Пока что просто установим её под Linux.

Установка Magnolia CMS

1. Скачать и распаковать Apache Tomcat в какой-либо каталог, который далее будет обозначаться [tomcat]
2. В каталоге [tomcat]/bin создать исполняемый файл setenv.sh, со строкой export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxPermSize=256m -Xms128M -Xmx768M -Djava.awt.headless=true"
Файл setenv.sh будет автоматически выполнен при запуске tomcat и JVM будет запущена с аргументами, которые указаны в файле. Кратко о каждом:
  • -Xms128M и -Xmx768M устанавливают, соответственно, минимальный и максимальный размер кучи. Параметр -Xms128M не особо обязательный, если речь не идёт о повышении производительности, а вот без -Xmx768M установка Magnolia скорее всего будет падать с java.lang.OutOfMemoryError: Java heapspace.
  • -XX:MaxPermSize=256m увеличивает размер области памяти, которая называется Permanent Generation. Эта память не относится к куче, в ней хранятся классы, методы и другие полезные вещи. Если до установки Magnolia не увеличить эту область памяти, то установка будет валиться с java.lang.OutOfMemoryError: PermGen space.
  • -Djava.awt.headless=true пригодится, если Magnolia будет запускаться на сервер, на котором не запущены Иксы.
После завершения установки, выделяемую память, вероятно, можно немного уменьшить, но это надо проверять.
3. Скачать WAR-файл с Magnolia. На данный момент последний доступный это magnolia-bundled-webapp-4.5.2.war.

4. В каталог [tomcat]/webapps положить две копии этого файла под именами magnoliaAuthor.war и magnoliaPublic.war.
При запуске tomcat magnoliaAuthor будет автоматически сконфигурирована как приватная авторская часть CMS, а magnoliaPublic как публичная. Авторская часть, как и в любых других CMS, используется для подготовки публикаций, которые могут создаваться постепенно и во время создания быть недоступны публично. При этом сам автор может просматривать то, что у него получается в ходе работы над контентом. Как только работа над контентом завершена, автор публикует его и контент становится доступным через публичную часть CMS.
5. Запустить Tomcat ([tomcat]/bin/startup.sh) и подождать пока распакуются оба WAR'а.

6. В браузере сначала постучаться по адресу http://localhost:8080/magnoliaAuthor, нажать "Start install", дождаться завершения и нажать "Start up Magnolia". Потом тоже самое проделать для http://localhost:8080/magnoliaPublic.

На этом установка завершена. Для доступа к http://localhost:8080/magnoliaAuthor введите superuser в качестве логина и пароля.По адресу http://localhost:8080/magnoliaPublic по умолчанию будет доступен демонстрационный сайт, над которым можно поиздеваться через magnoliaAuthor.



Возможные проблемы

Если установка или работа Magnolia CMS вдет себя странно, то гляньте в логи Tomcat:
  • Если увидите в логах java.lang.OutOfMemoryError, то попробуйте ещё увеличить размеры Heap или Permanent Generation.
  • Если обнаружите исключения с припиской "Too many open files", то нужно увеличить лимит на количество открытых файлов в Linux
Общее количество файлов
  • Установить в файле /etc/sysctl.conf параметр fs.file-max = 400000, и для обновления параметра в системе выполняем sysctl -p
  • Проверить можно так: sysctl -a |grep fs.file-max
Количество файлов на пользователя
  • В файле /etc/security/limits.conf написать eqlbin hard nofile 50000 и eqlbin soft nofile 10000, только вместо eqlbin, естественно, ваш пользователь, ну или символ * для любого пользователя
  • Файл limits.conf читается при загрузке. Чтобы сразу установить новое значение лимита выполните: ulimit -n 50000 из под того пользователя, под которым запускается Tomcat. Если эта операция запрещена в вашем дистрибутиве для обычного пользователя, то проще установить значение в limits.conf и перезагрузиться
  • Проверить: ulimit -n

5 апреля 2012 г.

Список CMS на Java

Давно хотел найти для себя какую-нибудь удобную CMS, а точнее WCMS, которая:
  1. Создана на стеке Java-технологий
  2. Open Source
  3. Легко разворачивается
  4. Имеет развитую и относительно простую систему шаблонов
  5. Более или менее легко интегрируется с другими веб-приложениями
  6. Проста в освоении для "нетехнических" людей, которые будут наполнять контент 
Понятное дело, что ничего идеального не бывает, поэтому просто хочется найти компромиссное решение. Это будет непросто, т.к. я никогда ни с какими CMS не общался достаточно тесно и знаю о них не особо много.

В качестве первого шага на пути к поиску наиболее подходящего кандидата, я поспрашивал у могучего Интернета, какие вообще есть открытые CMS, на Джаве писанные. Оказалось, что как и любых других CMS, решений на базе Java уже вагон и маленькая тележка, причем открытых. Этот список найденных CMS я тут и оставлю. В первую очередь это, конечно, для себя любимого, но может он будет полезен и ещё кому-нибудь.

Список я разделил на две части. В первом списке главные кандидаты. Это те CMS, с которыми я уже успел немного познакомиться: какие-то разворачивал и тыкал ранее, а какие-то просто внимательно изучал на официальных сайтах и они мне на первый взгляд понравились. Во втором списке системы, в которых я не особо уверен, потому что пока не уделил им достаточно внимания. Возможно, с течением времени эти списки будут пополняться или между ними будут происходить перестановки.

Также, вероятно, я буду периодически писать в блог различные заметки об опробованных CMS, а на этой странице повтыкаю ссылки на эти заметки.

Итак, списки.

Главные претенденты:

Запасной состав:

Многие CMS из этих списков имеют версии Enterprise и Community, которые, соответственно, распространяются под разными лицензиями: закрытой и открытой. Также, некоторые кандидаты являются не только WCMS, а большими разухабистыми ECMS (как, например, Alfresco) с возможностями WCMS. А вот в запасной список наоборот могли закрасться те, которые вообще не умеют WCMS, а являются к примеру только DMS.



11 октября 2011 г.

Плагин Google для Eclipse: обновления о которых не просят

Обнаружил интересную особенность у плагина Google для Eclipse, позволяющего разрабатывать приложения с использованием GWT и App Engine.

После очередного перезапуска контейнера сервлетов Jetty, который используется плагином для запуска GWT приложений на локальном хосте, он как-то необычно призадумался на старте. Вывел мне на консоль "Initializing App Engine server" и замолчал. Понимаю, что тужится, но не понимаю с чего это вдруг. Подождал я его несколько минут и он выдавил на консоль что-то вроде этого:
INFO: Unable to access http://appengine.google.com/api/updatecheck?runtime=java&release=1.5.4×tamp=1315604504&api_versions=['1.0']
Оказалось, что этот негодяй при каждом старте проверяет наличие обновлений, а у меня тут как раз отвалился интернет. Мне в принципе не жалко, пусть проверяет, но ждать его по несколько минут при каждом перезапуске когда нет сети как-то не особо хочется.

Первым делом я, конечно, полез в настройки Eclipse (Window -> Preferences -> Google) и убрал галку с пункта "Notify me about updates", но ничего не изменилось. Немного пошарив по интернету, я наткнулся на забавное описание метода allowedToCheckForUpdates() класса UpdateCheck в пакете com.google.appengine.tools.info. По названию пакета можно сделать некоторые выводы о том, для чего он нужен. Вот описание этого метода:
Returns true if the user wants to check for updates even when we don't need to. We assume that users will want this functionality, but they can opt out by creating an .appcfg_no_nag file in their home directory.
В общем, надо или не надо, этот метод все равно возвращает true, т.к. разработчики уверены что, если пользователь даже отключил проверку обновлений, то он всё равно хочет обновлений. Как-то так получается :) Однако, всё-таки можно эту проверку отключить, создав в домашнем каталоге пользователя, под которым запускается контейнер, файл .appcfg_no_nag. После того, как я это сделал, "задумчивость" контейнера на старте прошла, но tcpdump показывает, что он всё равно продолжает стучаться на appengine.google.com.

29 сентября 2011 г.

Основы использования системы сборки Apache Ant

Когда ведется разработка программного продукта, он может состоять из множества исходных частей. Например, разработка может вестись несколькими людьми практически независимо друг от друга, а файлы с исходным кодом, за который они отвечают, могут находится в совершенно разных местах файловой системы и даже на разных машинах. Кроме файлов исходного кода, в проекте могут использоваться также и готовые библиотеки от сторонних разработчиков (например, файлы jar, dll или so), файлы конфигурации, различные картинки и иконки, звуковые файлы и куча всего остального. Все эти штуки могут так же изменяться в ходе разработки проекта другими людьми.

А теперь представьте, что из всего этого безобразия необходимо собрать всего один файл сжатого архива, который пользователь мог бы скачать с вашего сайта, распакавать и сразу же запустить ваш продукт. Вам нужно будет собрать вместе все файлы с исходным кодом Java и скомпилировать их, прогнать тесты, чтобы убедиться что проект никто не поломал, полученные class-файлы упаковать в JAR (или несколько JAR'ов), для которого ещё необходимо сгенерировать правильный манифест, содержащий CLASSPATH, имя главного класса, номер версии и т.п., затем собрать вместе все остальные файлы вроде библиотек, картинок и конфигов, распихать это все в правильные каталоги, сгенерировать документацию, создать из всего этого архив и залить его на ваш вэб-сервер, а всё произошедшее записать в лог и сохранить его в базе данных, которая хранит информацию о различных сборках. Делать всё это руками довольно уныло, да и не должен психически здоровый человек этим заниматься.

Системы сборки, такие как Apache Ant, были созданы для того, чтобы автоматизировать весь этот порой достаточно сложный и рутиный процесс по сборке проекта. Причем, в случае с Apache Ant проект не обязательно должен быть на Java, и не обязательно должен быть вообще программным обеспечением. Это может быть что угодно, хотя ориентирован он, конечно же, в первую очередь на Java. В данной статье я хочу на очень простом примере показать, как можно облегчить себе жизнь с помощью Apache Ant.

14 августа 2011 г.

Вычисление БПФ на GPU с использованием Java и CUDA

В последнее время у меня на работе встала задача создания спектрограмм для довольно большого объема данных. Главным инструментом для этого является алгоритм Быстрого Преобразования Фурье. На сегодняшний день для Java написано уже множество библиотек, реализующих вычисление БПФ и другие математические инструменты, например, мне нравится Commons Math от Apache project. Но для того, чтобы обрабатывать большие объемы данных с помощью этой библиотеки за более или менее разумное время, нужна довольно мощная и недешевая машина, которой у меня нет. Поэтому я и обратил свой взор на технологию NVIDIA CUDA, которая позволяет очень шустро производить расчеты с плавающей точкой на чипе видеокарты. А, как известно, БПФ это очень даже плавающая точка :) Вдвойне приятно то, что хорошие люди уже давно написали Java-интерфейс JCuda для нативной библиотеки CUDA. И ещё больше я обрадовался, когда обнаружил, что библиотека CUDA имеет в своем составе модуль CUFFT, который предоставляет средства для расчета БПФ, использующие по полной программе возможности видеокарты для выполнения параллельных вычислений с плавающей точкой.

CUDA поддерживается видеокартами NVIDIA GeForce начиная с чипа G80, т.е. с восьмой серии. Машина, на которой я тестирую в данный момент связку Java + CUDA довольно старенькая и имеет на борту процессор AMD Athlon X2 4200+, видеокарту NVIDIA GeForce 8800 GTS 640 Mb, всего 2 Gb оперативной памяти и управляется операционной системой openSUSE 11.4.

11 марта 2011 г.

JDOM: работа с XML на Java - проще простого

JDOM – это максимально упрощенная open source Java-библиотека для создания, парсинга, изменения и сериализации XML-документов. В отличие от других подобных DOM APIs, JDOM ориентированна на язык Java, а не на спецификации XML, что очень упрощает код и облегчает его интуитивное понимание. При этом JDOM не является "велосипедом" и не содержит в себе свой собственный парсер, а использует уже существующие наработки – стандартные пакеты javax.xml и org.xml.sax. Если вам понадобилось работать с XML, то обратите сначала внимание именно на эту библиотеку, скорее всего вам она понравится.

Краткое описание модели библиотеки JDOM

Так же, как и сам XML, JDOM APIs являются древовидными. Для представления XML в библиотеке, главным образом, используются классы Document, Element и Attribute.

Документ XML в JDOM представляет из себя дерево, корнем которого является объект класса Document. Экземпляр Document является контейнером для всех остальных элементов и обязательно содержит один корневой элемент (экземпляр Element). Главной характеристикой объекта Element является его содержание (Content) и список атрибутов (Attribute). Класс Content является родительским для классов Element, Comment и Text (а так же для некоторых других), поэтому экземпляры перечисленных классов могут быть содержимым объекта Element. Объект Element есть ничто иное как XML-тег, у которого обязательно должно быть имя и могут быть атрибуты. Классы Comment и Text соответственно представляют комментарий и текст внутри тега. Экземпляры Attribute, Comment и Text не могут содержать внутри себя никаких элементов и по сути являются объектами, которые содержат только текстовые значения. Значение экземпляра Attribute может быть получено по имени в отличие от Comment и Text, у которых имени нет.

1 февраля 2011 г.

Работа со звуковыми WAVE-файлами на Java

Мне на работе иногда приходится иметь дело с WAVE-файлами (или WAV по расширению) по той причине, что в них довольно удобно хранить научные данные и не надо выдумывать формат. Решил написать маленькую заметку о работе с этим форматом на Java. Сразу оговорюсь, что речь тут пойдет не о воспроизведении звуковых файлов с помощью Java, а о том как можно их создавать, изменять, и читать из них данные.

26 ноября 2010 г.

Создание документа ODF с помощью ODFDOM Simple Java API

Документ ODF, как известно, представляет из себя ZIP-архив, который содержит xml-файлы и различные ресурсы документа, например картинки. Наиболее значимые xml-файлы это content.xml, который содержит по сути весь текст документа и его структуру, и styles.xml, который хранит стили документа.

Элементы файла content.xml, содержащие текст, могут использовать стили, описанные в файле styles.xml, обращаясь к ним по имени. Проще говоря, в элементе файла content.xml указывается имя стиля из styles.xml, которое должно применяться для текста, параграфа и т.п. Стили так же представляют из себя набор XML-элементов.

Изучать стрктуру и все элементы ODF дело скучное да и мало кому, я думаю, нужное. Для того, чтобы работать с форматом ODF на высоком уровне существует библиотека ODFDOM. На самом деле эта библиотека не такая уж и простая, и чтобы ею пользоваться нужно все же понимать устройство ODF и уметь работать с XML при помощи Apache Xerces-J. Но для действительно простой работы с ODF теперь есть надстройка над ODFDOM, которая называется Simple Java API for ODF. Раньше я писал о том, как можно работать с документами ODF из Java-программы используя OpenOffice. Использование библиотеки ODFDOM Simple Java API намного удобнее как с точки зрения написания кода, так и тем, что вам теперь не нужен установленный OpenOffice. Благодаря этой библиотеке вы сами легко можете создавать программы работающие с ODF.

22 сентября 2010 г.

Запуск внешней программы на Java

Удобным средством для запуска внешних программ из java-кода является класс ProcessBuilder. С помощью экземпляра этого класса можно указать программу для запуска, параметры её запуска, переменные окружения, рабочий каталог и включить перенаправление потока вывода ошибок на стандартный вывод.

Ниже приведу простой пример использования ProcessBuilder с комментариями.

17 сентября 2010 г.

Плагин Java и Firefox 3.6 в Linux

Оказывается, что с каких-то пор для того, чтобы прикрутить Java к Firefox 3.6 надо создать символьный линк в каталоге firefox/plugins на файл jdk/jre/lib/i386/libnpjp2.so вместо привычного jdk/jre/plugin/i386/ns7/libjavaplugin_oji.so

Когда чего кто поменял не понятно, но я этот момент упустил из виду и в результате пол дня прокопался прикручивая Java к Firefox...

7 мая 2010 г.

Java и MongoDB вместе

Сегодня стало очень модным использование нереляционных баз данных. Вот и мне захотелось такое подергать. Мой выбор пал на MongoDB просто потому что слышал о этой штуке много положительных отзывов. Для себя сделал эту заметку, что бы потом не пришлось все изучать по второму разу, если ещё кому-нибудь пригодится, то и замечательно.
Всё, что здесь написано, основывается на документации с официального сайта MongoDB и конкретно на разделе посвященному Java, а кое-что и вовсе является просто переводом. Некоторые примеры из документации я немного переделал для более ясной, на мой субъективный взгляд, демонстрации возможностей.

4 мая 2010 г.

Хитрости Apache Tomcat: Кодировка

При разработке сервлетов, которые на основе запроса от HTML или JSP-страницы генерируют другую страницу, можно натолкнуться на некоторые трудности с кодировкой данных, отправляемых на сервер (request) и получаемых от него (response).

Для определения кодировки данных ответа необходимо использовать метод setCharacterEncoding объекта класса HttpServletResponse. Например, для установки UTF-8:
public class FooServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        
        response.setCharacterEncoding("UTF-8");
        
        // далее остальной код...
    }
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        doPost (request, response);
    }
}
А вот с кодировкой данных, которые будут отправлены в запросе на сервер есть небольшая хитрость. Казалось бы, если страница сформирована, допустим, в кодировке UTF-8, то и данные запроса должны обрабатываться сервером, как UTF-8. Однако, этого не происходит, потому что в запросе браузер не передает информацию о кодировке данных. Если для отправки данных формы используется метод POST, то все просто - можно точно так же вызвать метод setCharacterEncoding, только для объекта класса HttpServletRequest:
request.setCharacterEncoding("UTF-8");
Проблема возникнет, если для отправки данных формы будет использоваться метод GET. В таком случае request.setCharacterEncoding("UTF-8") уже не сработает и Tomcat будет обрабатывать строку запроса так, как-будто она в кодировке ISO8859-1.

Для решения этой проблемы необходимо подправить конфигурационный файл Apache Tomcat server.xml и в тег Connector добавить параметр useBodyEncodingForURI="true":
<Connector connectionTimeout="20000" 
      port="8081" protocol="HTTP/1.1" 
      redirectPort="8443" useBodyEncodingForURI="true"/>
После этого перезагружаем Tomcat и для метода GET можно будет также использовать request.setCharacterEncoding("UTF-8") для указания кодировки запроса:
public class FooServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        
        response.setCharacterEncoding("UTF-8"); // кодировка ответа
        request.setCharacterEncoding("UTF-8");  // кодировка запроса; необходимо указать до
                                                // вызова request.getParameter()
        
        // далее остальной код...
        String param1=request.getParameter("param1");  
        String param2=request.getParameter("param2");
      
        // ...
    }
 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {
        doPost (request, response);
    }
}
В том же теге Connector, используя параметр URIEncoding вместо useBodyEncodingForURI, можно явно установить нужную для вас кодировку, например URIEncoding="UTF-8", решайте сами, что для вас удобнее.

22 апреля 2010 г.

Формирование отчетов в OpenOffice.org Calc и Writer из Java-программы

При создании прикладных программ, работающих с базой данных, довольно часто возникает необходимость выгрузки данных в какой-нибудь текстовый редактор, который может быть использован для корректировки информации и печати получившегося документа. В этой статье я расскажу, как решил эту задачу для себя, используя язык программирования Java и офисный пакет OpenOffice.org, что позволило обеспечить кроссплатформенность этого решения.
Для начала необходимо, что бы был установлен OpenOffice.org 3 версии, ну и разумеется JDK со средой разработки, или кому как нравится.
Для разработки понадобятся следующие библиотеки OpenOffice.org:
  • juh.jar, jurt.jar, ridl.jar, unoloader.jar из каталога /opt/openoffice.org3/basis-link/ure-link/share/java (если OpenOffice.org установлен не из официальных репозиториев) 
  • unoil.jar из каталога /opt/openoffice.org3/basis-link/program/classes
  • bootstrapconnector.jar, который можно скачать здесь
Можно скопировать данные библиотеки в директорию jre/lib/ext, но лучше подключить их в своей среде разработки, как User Libraries.
Библиотеки juh.jar, jurt.jar, ridl.jar, unoil.jar и unoloader.jar представляют собой необходимый набор классов API OpenOffice.org.
Библиотека bootstrapconnector.jar необходима для решения некоторых проблем, которые могут возникнуть во время подключения приложения к работающему экземпляру OpenOffice.org при определенных условиях. Подробнее об этих проблемах можно почитать здесь (на англ. яз), там же есть ссылка на саму библиотеку.
Когда всё установлено и все библиотеки подключены можно приступать к разработке. Приведу пример рабочих классов и методов для работы с OpenOffice.org Calc и OpenOffice.org Writer.

Интеграция Apache Derby в Java-приложение

При создании небольших прикладных программ, решающих относительно простые задачи, очень часто приходится использовать базы данных для хранения информации, потому что это очень удобно. Так же, обычно, у таких программ не предполагается обработка и хранение больших объемов информации, работа в сети и многопользовательский доступ к базе данных. В таком случае зачастую очень не хочется заморачиваться с использованием таких СУБД, как PostgreSQL или MySQL, т.к. при установки такой программы необходимо, что бы либо пользователь обладал определенными знаниями в этой области и смог настроить СУБД для работы с созданной нами программой, либо для программы придется писать дополнительную программу-установщик, что бы избавить конечного пользователя от совершенно ненужных ему плясок вокруг установки и настройки сервера базы данных.
Но есть более простой выход - использование СУБД Apache Derby, которая может быть интегрированна в Java-приложение. В этой статье я кратко расскажу как можно реализовать такой подход.
При разработке я использовал ОС Linux и среду разработки Eclipse, поэтому статья ориентированна на эти системы, но точно так же всё написанное можно переоформить для MS Windows и любой другой среды разработки.