Рубрики
4. Полезняшки Java

Установка и настройка Apache Tomcat под Linux

Tomcat-logo

Причины.

Замысел написать эту статью про установку и настройку, наверное, одного и самых популярных веб-серверов на Java возник уже давно. Одной из причин было желание сделать небольшую заметку "для себя" с подробной инструкцией. Возможно эта статья также пригодится другим java программистам. Пользы для кого-нибудь ещё, например для системных администраторов в ней будет не так много. Скорее всего они просто сделают так: apt-get install tomcat8 и затем потребуют у программиста war-ик для развертывания. Программист же часто хочет чуть большего — например, возможности работать с различными версиями серверов (которых может даже ещё нет в официальном репозитории) или наоборот откатиться к какой-то специфичной версии. Системному администратору такие исследования, как правило, не нужны. По-хорошему, у него должна стоять просто стабильная работающая версия, на которую периодически он будет накатывать обновления и лишний раз на неё не дышать.

В общем, это статья про то, как программисту установить Apache Tomcat под Linux чтобы "поиграться" с ним, но при этом ничего сильно не сломать.
Также эта статья может быть полезна в тех случаях, когда начинающий java программист отладив свое веб-приложение Tomcat запущенным на Windows, сталкивается со жгучим желанием развернуть свой сайт на какой-нибудь недорогой VPS-ке с Ubunt-ой.

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

Итак, поехали!

Подготовка

Исходные данные.
Linux. Debian 9. 64bit.

1. Устанавливаем JDK.
Почему JDK, а не JRE? По-факту достаточно JRE, но лично мне приятно иметь возможность в случае необходимости по-быстрому скомпилировать программку на java прямо на сервере.
Вы не поверите, но жизнь такая интересная штука, никогда не угадаешь когда тебе может понадобится скомпилировать и запустить что-то на Java. Лично мне запуск javac из консоли на сервере помогал несколько раз.

Далее, я предпочитаю ставить Oracle JDK. Собственно OpenJDK тоже неплох и устанавливается гораздо проще (sudo apt-get install default-jdk). Просто я отдаю предпочтение оригинальной Sun/Oracle. Тем не менее, ставить Oracle JDK, OpenJDK или какую-либо другую версию - личное дело каждого. Лично я отношусь к пользователям Open JDK без предубеждения. Более того, сам часто использую версии Open JDK (например Java 9) для того, чтобы ознакомиться с их новыми возможностями.

Установка Oracle JDK под Windows и Linux сильно отличаются. Под Windows проще установить Oracle JDK проще простого (скачать и запустить), а сборку Open JDK под Windows нужно ещё поискать.
С Linux-ом всё наоборот. Open JDK как я писал ставится очень просто через apt, с Oracle JDK чуть сложнее.

В интернете существует совет, что для установки нужно добавить ещё один apt-репозиторий. Я так не делаю. Возможно это лично моя паранойя, но я стараюсь так не делать и делаю установку руками. Особенно если учесть, что установка заключается в том, чтобы скачать и распаковать архив.

Для этого заходим на сайт загрузки Oracle.

Выбираем jdk-XYZ-linux-x64.tar.gz файл. Правой кнопкой - сохранить ссылку.

Далее скачиваем архив:

$wget --header "Cookie: oraclelicense=accept-securebackup-cookie" [ссылка]

Например так:

$wget --header "Cookie: oraclelicense=accept-securebackup-cookie" 
    http://download.oracle.com/otn-pub/java/jdk/8u73-b02/jdk-8u73-linux-x64.tar.gz

Специально для параноиков, нужно проверить SHA-1 сумму (поскольку выкачиваем-то по голому http).

Проверяем:

$sha256sum jdk-8u73-linux-x64.tar.gz

Смотрим что показалось на экране и сверяем значение, с тем что опубликовано на официальном сайте.

Рубрики
4. Полезняшки Java

Заметка об экспериментах со SnappyDB (NoSQL KeyValue DB под Android)

Небольшая заметка про SnappyDB. Это NoSQL база данных под Android, которая базируется на LevelDB и алгоритме сжатия Snappy.

LevelDB - это key-value база данных. Написана Google-ом для каких-то своих мега проектов.
Snappy - метод сжатия данных, сбалансированный на скорость (т.е. приоритет быстрота, а не степень сжатия). Также написана Google-ом.

Авторы SnappyDB на своем блоге приводят очень привлекательный график сравнивая скорость работы SnappyDB с SQLite.

Все это конечно очень и очень заманчиво, но лично меня она заинтересовала не поэтому. Дело не в скорости и даже не в том, что какие-то части этой БД делал Сам Google, а в более-менее нормальном API.

На практике у меня пока не возникали задачи, в которых нужно было обрабатывать на мобильных устройствах (а я напомню это именно БД для Android) терабайты данных. При этом хранить различные небольшие справочники, настройки, профили и прочую ерунду приходится регулярно.

Конечно по-хорошему можно использовать API Preferenes или SQLite, но в некоторых случаях это не очень удобно.
В частности у SQLite несколько громоздкий API, а в preferences нет удобных методов для сложных выборок по ключам.

Упоминая более-менее нормальное API я имел в виду следующее. Вот что нужно сделать чтобы получить значение по ключу в Preferences (Android API).

  SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
  String username = sharedPref.getString("name", "");

Вот что нужно сделать чтобы получить значение по ключу в Snappy DB.

  DB db = DBFactory.open(context); 
  String username =  db.get("name");

Другими словами, API не такое "многословное" как стандартное Android API.

При этом если есть несколько записей ("name:0","name:1","name:2" и т.д.), то их можно получить как-то так:

  db.findKeys("name:");

Такое "из коробки" в Preferences сделать пока невозможно.

Поэтому мне показалось, что Snappy DB это удобно. Можно использовать например в таких задачах как:
- Сохранить справочников кодов и их описание
- Запоминать время работы каких-то специальных команд или хранить данные по мониторингу
- Идентификатор пользователя и его профиль (например в XML или JSON формате)

В общем все было хорошо, пока не наткнулся на одну приставку под Android TV, на которой был установлен Android M. Так вот, на этом устройстве Snappy DB внезапно стала работать с ошибками. Поскольку БД нативная, а желания дебажить сишный код у меня в последнее время нет, пришлось отказаться от ее использования в текущих проектах.

Рубрики
3. Инструментарий 4. Полезняшки Java

Android Design Support Library

Наконец Google сделал эту библиотеку с материальными виджетами!

Важно!
Возможно в официальной документации developer.android.com ошибка.
Вместо:
'com.android.support:support-design:22.0.0'

нужно указывать:
'com.android.support:design:22.2.0'

Рубрики
4. Полезняшки

Умножаем на пи (π = 3,14159265...)

Около месяца назад мне попался на глаза шедевральный пост, в котором приводится гениальное по простоте, остроумное и изящное математическое доказательство теории: "при оценки сроков и объема работы над проектом желательно умножать исходную оценку на Пи". Оригинальный труд находится по следующей ссылке: http://www.altdevblogaday.com/2013/11/15/always-multiply-estimates-by-pi/. В этой статье хотел изложить краткий пересказ доказательства.

Допустим у вас есть какой-то исходный план действий.
Обозначим его вектором направленным из точки A в предполагаемую точку B0.
blog-1

Времена меняются. Цель из точки B0 отодвигается под фактором различных обстоятельств в точку B.
blog-2

Естественно не бывает так, что всё идет гладко, возникают трудности, которые приводят к отклонению от прямой. В итоге путь, по которому вы прибываете к цели является кривой.
blog-3

Рубрики
4. Полезняшки

Комиксы

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

1. CommitStrip

Французские авторы. Про жизнь небольшой команды занимающейся веб-разработкой.

Рубрики
4. Полезняшки

Уменьшение размеров JavaScript и CSS файлов.

В данном случае идет речь о минификации, т.е. например удалении лишних пробельных символов и комментариев. Часто используется при подготовки и развертывании систем готовых к промышленной эксплуатации. Конечно, также с целью экономии трафика имеет смысл включать GZIP compression в настройках сервер, но данная статья не об этом.

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

Рубрики
3. Инструментарий 4. Полезняшки

Число прописью (обновление).

В добавок к английскому и русскому языку в моем проекте "число прописью на Java" появился новый язык - узбекский.
Всё благодаря помощи Беки из солнечного Узбекистана.
Большое спасибо за участие в проекте!

Исходники можно взять как и прежде из GitHub-a.
Все свободное и открытое, лицензия GPL (т.е. без изменений).

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

Рубрики
4. Полезняшки

Отрисовка SVG внутри HTML5 Canvas.

Года два назад в интернете начали появляться статьи, в которых сравнивали SVG и Canvas. В итоге сейчас не составляет особого труда найти сайт, на котором популярно объясняются плюсы и минусы использования SVG-изображений или отрисовки напрямую в Canvas.

Здесь я хотел обозначить совсем другую задачу - отобразить картинку в SVG-формате с помощью API Canvas-a. Другими словами, тема статьи не "SVG против Canvas", а как рисовать SVG картинки внутри Canvas. Подобного рода задача возникнет, например, в случае, если у вас уже есть небольшой набор не слишком сложных SVG-файлов, и вы хотели бы их использовать, при этом ваш графический javascript-овый движок базируется на Canvas-e.

Можно выделить два основных похода:
1. Первый подход.
Парсить SVG файл JavaScript-ом и руками рисовать его в канву.
Один из самых популярных движков, которые реализуют подобный функционал это: http://code.google.com/p/canvg/

2. Второй подход.
На самом деле, многие браузеры умеют рисовать SVG файлы непосредственно в канву методом drawImage. Точно также как обычные растровые изображения (PNG, JPG и т.д.) - https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Using_images.
Проблемы заключаются как всегда в том, что разные браузеры могут делать это по-разному.
В итоге пришлось провести небольшую работу для проверки отображение SVG внутри Canvas-a для различных браузеров. На момент публикации этой статьи получилась следующая картинка:

Рубрики
1. Языки программирования 4. Полезняшки

Тренды программистских вакансий на indeed.com

Пару дней назад прочитал интересную статью на dzone.com с занятными графиками, которые показывали количество вакансий для программистов.

В статье были опубликованы данные с сайтов: indeed.com и simplyhired.com

Оба сайта имеют русскоязычный интерфейс, поэтому надеюсь, что приведенные графики отображали не только данные по США (как часто бывает), а мировые тренды.
Хотя может быть это и не так. К сожалению, не нашел способа получить картинки локализованные под Россию (или Москву).

Меня в первую очередь конечно интересовала java, а также близкие или "конкурирующие" языки программирования.
Поэтому в отличие от оригинальной статье на dzone я оставил в графике от indeed.com только такие языки как: java, C++, C#, objective c (убрал Perl и Visual Basic).

Получилась такая картинка:

Рубрики
4. Полезняшки Java

Про интерфейс: Map<K,V>

Недавно от товарища пришел вопрос на засыпку: "Почему в интерфейсe java.util.Map метод get в качестве ключа принимает Object, а метод put использует женерики?"

    V get(Object key);
    V put(K key, V value);

Сходу ответить не смог, пришлось разбираться.