Пролог. Исходные данные.
По историческим причинам работа моя связана с сервером приложений
JBoss, конкретнее - с 4.0.х его версией (впрочем, другой приличной версии все равно нет). В частности, имеем
JSF 1.1 и, в качестве реализации,
Apache MyFaces. Увидев некоторое время назад сообщение о том, что в версии 1.1.6 этой чудесной библиотеки была исправлена одна проблема, которая меня несколько беспокоила, я решил испытать эту самую новую версию, для начала - на своем домашнем компе. Никаких особых отличий я обнаружить не ожидал, так как, являясь исключительно реализацией спецификации, релизы MyFaces серии 1.1.х содержат в основном только исправления найденных ошибок. Так что предполагаемой последовательностью моих дествий было проверить корректность исправления интересовавшей меня проблемы, проверить, что все остальное работает в штатном режиме, и распространить новую версию на все наши сервера.
Часть 1. Их лица.
Этому плану не суждено было осуществиться.
После запуска сервера приложений с единственным приложением, использующим JSF, я заглянул в лог с целью проверить, нормально ли прошло разворачивание. Как и следовало ожидать, никаких проблем не возникло. Была мной отмечено, однако, одна дополнительная строчка в логе, а именно:
No context init parameter 'org.apache.myfaces.CONFIG_REFRESH_PERIOD' found, using default value 2
"Ага," - подумал я, - "эти парни решили ввести динамическое подхватывание изменений в конфигурации. Что, теоретически, может иметь смысл при разворачивании приложения в виде распакованного архива в процессе отладки, не имеет смысла при разворачивании приложения в виде стандартного архива (как в моем случае), и является вредным при разворачивании на продакшне (поскольку наверняка создает дополнительный поток, следящий за потенциальными изменениями и потребляющий дополнительные ресурсы сервера). Странно, что функция, которая должна быть отключена на продакшне, включена по умолчанию - обычно все наоборот. Кстати, в чем измеряется этот период - в секундах или в минутах? И что нужно указать, чтобы эту гадость отключить - '0' или '-1'?"
Таким образом, отложив на время исходный план и вооружившись браузером, я принялся за выяснение вышеназванных вопросов. Поиск в гугле по названию контекстного параметра никакой полезной информации не принес. Тогда, изучив changelog этой версии, я нашел
запись, которая, по идее, описывает введение этой новой функции отслеживания изменений конфигурации. Здесь, однако, кроме указания на то, что период вычисляется в секундах, ничего полезного так же не нашлось. Последней надеждой на цивилизованное решние проблемы была возможность того, что, с момента моего последнего исследования, авторы MyFaces резко превратились в приличных людей и выложили описание всех контекстных переменных, которые они ввели (а их что-то около десятка) в какое-нибудь подходящее место типа их официального сайта или Вики. Увы. Ничего подобного там и близко нет. Официальный сайт MyFaces вообще не содержит никакой документации по MyFaces, а их Вики если и содержало когда-то актуальную информацию, то было это года три назад. Убидившись в отсутствии улучшений в данном вопросе и помянув незлым тихим словом ответственных за этот чудо-проект, я прибегнул к нецивилизованному способу - а именно, к просмотру исходного кода. В котором и обнаружилось указание, что для отключения этой функции указывать нужно '-1'.
С горем пополам разобравшись с этим вопросом, я вернулся к первоначальному плану. Открыл в браузере первую JSF-страничку и опять, на всякий случай, заглянул в лог. И увидел там нечто совершенно неожиданное, а именно, около 15 одинаковых записей вида
No context init parameter 'javax.faces.PARTIAL_STATE_SAVING_METHOD' found; no partial state saving method defined, assuming default partial state saving method off.
Это было уже хамством. Мало того, что кто-то додумался использовать в своих личных целях префикс "javax.faces", который любой вменяемый разработчик оставляет за теми параметрами, которые определены в спецификации JSF; так еще и , вместо того, чтобы один раз прочитать значение параметра и вывести соответствующее сообщение при инициализации, эта штука гадит в лог при обработке каждого компонента на странице!
В раздраженном состоянии я опять обратился к гуглу. Обнаружился прелюбопытнейший
mail thread в девелоперском списке рассылки MyFaces. В котором было сказано буквально следующее:
"partial state saving" is a performance-enhancement feature that was added in myfaces. But it is entirely optional; it defaults to off (as the message says). And actually, as it was never properly documented (sigh) almost no-one (including me) knows what it really does or how to really use it.
So in short, just ignore this message. Probably myfaces should not log anything here, as no-one ever has this enabled (except maybe the author of the code) due to the lack of info about it.
Великолепно. Добавить к этому нечего. После этого JBoss был выключен, а новая версия отправилась в условное мусорное ведро. Судьба вопроса, ради которого, собственно, и затевалось обновление, так и осталась невыясненной.
Часть 2. Альтернативы.
Тут самое время меня оборвать и гневно указать на то обстоятельство, что в мире Open Source нельзя ругать авторов проектов, а нужно, если что-то не нравится, самому это исправить и выложить в проект для блага всего сообщества. А то критиковать, мол, каждый умеет, а ты попробуй сам сделать что-нибудь полезное.
Но этот номер не пройдет. Во-первых, я никого не ругаю. Я просто пытаюсь понять логику людей. Ведь в том же Apache релизы просто так не делаются, за них должно проголосовать определенное количество людей обладающих определенными полномочиями. Предполагается, что, прежде чем голосовать, они всесторонне тестируют версию, которую предполагается опубликовать... И вот, через некоторое время после релиза, выясняется, в релизе находится нечто, о чем почти никто ничего не знает, никто не использует, но зато это нечто постоянно пишет в лог никому не нужные сообщения. Ничего страшного, говорят нам, просто игнорируйте их...
Затраты ресурсов на постоянную запись в файл огромного количества текста, видимо, тоже предлагается игнорировать.
И вот при этом эти люди, очевидно, гордятся своим проектом (что следует на основе изучения их девелоперской рассылки за последние несколько лет). Есть ли в этом логика? Буду счастлив, если мне на нее укажут.
Но это еще не все. Не секрет, что многим людям, которые занимаются подобного рода проектами, платят за это их работодатели (есть и такие модели построения процессов). Мой работодатель к таким не относится. В этой связи предложение мне исправить то, что они там напортачили, выглядит несколько странно.
Тут самое время опять меня прервать и
послать напомнить, что никто не заставляет меня использовать такую отстойную, на мой взгляд, библиотеку, и что недовольные могут поискать что-нибудь получше.
Но мне не нужно ее искать. Я ее уже нашел. Собственно, я жду только перехода на
другой сервер приложений, чтобы одновременно перейти и на
другую реализацию JSF. Она тоже, кстати, open source. Более того, это вообще Reference Implementation (что еще несколько лет назад звучало, скорее, как ругательство). Тем не менее, во всех мало-мальски приличных серверах приложений, поддерживающих Java EE 5, она стоит по умолчанию (даже в JBoss'e, исключение составляет разве что Geronimo, но его приличным назвать можно только с очень большого пере
пояпугу).
Для того, чтобы оценить разницу между MyFaces и JSF RI достаточно взглянуть на
changelog версии JSF RI 1.2_05. Особый интерес представляют эти сообщения:
This release includes a major rewrite of the configuration and managed bean sub systems.
...
A positive side effect of this rewrite is that the RI no longer has any dependencies on Jakarta Commons libraries. This makes the RI very lightweight and easy to integrate.
Что-то из внутренней реализации было переписано. В частности, была убрана зависимость от некоторых левых библиотек. Изменилось ли что-то внешне для конечного пользователя? Нет. Повысилось ли качество проекта? Конечно!
И я имею основания (опять же на основе трехлетнего изучения девелоперского списка рассылки) утверждать, что в MyFaces внесение таких изменений в проект невозможно. За эти три с лишком года мною был отмечен единственный раз, когда был произведен некоторый рефакторинг (несколько похожих методов были заменены одним). Причем проводил его сторонний человек, а постоянные участники проекта занимались тем, что настоятельно требовали от него подписать соглашение о передаче авторских прав, прежде чем он получит возможность закоммитить что-то в их проект.
Все остальные релизы - это внедрение новых фич, которые кому-то показались полезными (не факт, что кто-то их потом когда-то использовал) и исправление совсем уж критических багов.
Как-то раз я и сам написал запрос в Jira одного из родственных проектов. Запрос был принят, обсужден, назначен ответственный за исправление ошибки. И все. За последующие два года ничего для исправления сделано не было (и явно уже не будет сделано никогда). Человек, который в основном занимался данным конкретным компонентом, по всей видимости, более не является активным участником проекта. А всех остальных этот компонент не интересует, равно как и исправление ошибок в нем.И вот мы имеем, с одной стороны, проект, состоящий из довольно большого количества людей, каждому из которых интересно сделать какой-то интересующий именно его кусок функциональности. При этом, естественно, никто не заботится о стройности общей архитектуры, о документации, о чистоте кода и тому подобных мелочах, равно как и по поддержке ранее написанного (кем-то другим) кода. Главные лица проекта очень гордятся открытостью и позитивной атмосферой. А с другой стороны - проект с не менее открытым кодом, но поддерживаемый сравнительно небольшим количеством людей, и, что самое главное, поддерживаемый и направляемый одной конкретной компанией, которая хочет сделать качественный продукт. Релиз какого проекта вы бы выбрали для использования в своих проектах? А к какому из проектов вы бы присоединились, если бы захотели внести свою лепту?
Часть 3. Поиски.
Как все уже догадались, речь не о MyFaces. Подавляющее большинство OSS, как минимум, не лучше. И причина фантастической убогости всех этих проектов одинакова - отсутствие внутреннего стержня, которым может быть или компания (как в случае с проектами Sun), или человек (как Gavin King в случае
Hibernate). То есть лидера, которого волновало бы в первую очередь качество конечного продукта, а не количество фич, каждая из которых нужна только ее создателю (ну, может быть, еще его друзьям и близким родственникам).
Возьмем то же
Apache Software Foundation, содержащее десятки, если не сотни, проектов, и попытаемся найти там хоть что-нибудь стоящее (ну, не считая http-сервера, конечно). Вот, что припоминается лично мне:
- Ant. Ant был всегда и до сих пор используется всеми (кроме горстки подозрительных любителей Maven). Возможно, он появился еще раньше Apache. В любом случае, он родился за пределами Apache и был позже подарен. К настоящему времени это уже давно государство в государстве, живущее по своим законам, редко выдающее релизы и отшлифовывающее свой продукт до степени абсолютной незапятнанности.
- Log4J - также используется повсеместно, но особой активности в последние годы не наблюдается. К тому же, постепенно сдает позиции в пользу стандартного API для логгирования, введенного в JDK 1.4.
- HTTP Components, вероятно. Вероятно - потому что их использование можно было бы сделать более простым.
- CXF - неплохо, хотя Metro все равно лучше :). В любом случае CXF появилось в результате слияния двух проектов, рожденных за пределами Apache.
- .. хмм... есть идеи?
Все остальное - более или менее прогнивший хлам. Некоторые проекты (вроде
Avalon) осознали собственную бесполезность и закрылись. К сожалению, это единичные случаи.
Наиболее одаренные парни из Apache решили сделать
свою реализацию Java SE. Правда, за несколько лет они так и не смогли доделать реализацию Java 5. При этом они регулярно что-то тявкают в общем направлении Sun по поводу каких-то проблем с лицензированием. В Sun в это время заняты созданием Java SE 7, поэтому времени на удовлетворение странных желаний этих странных людей у них нет (да и не больно-то хотелось). Что приводит в еще большее возмущение господ из Apache, которые бойкотируют принятие решений в
JCP и пытаются как-то возмутить общественность. "
Та подивиться на себе, кому ви нужнi!".
В целом, конечно, неудивительно, что кучка восторженных фанатиков, собравшись вместе, не смогла произвести на свет ничего путного. Удивительно другое: во-первых, гордость этой кучки за то, что они сотворили; а во-вторых - наличие большого числа программистов, готовых без малейших угрызений совести засунуть в свое приложение любую 0.0001-prebeta-alfa-unstable-snapshot-nightly-dontusethisshit версию первой выданной гуглом хрени только потому, что оно вроде бы делает то, что нужно сделать в этом месте моего кода, а мне лень написать самому метод в 5 строчек, поэтому я присобачу пару мегабайт сторонней библиотеки потому что там есть похожая функция. Врочем, это тема для отдельного исследования.
Эпилог. Нужна ли жизнь на Марсе?
И все-таки некоторая польза от всего этого бывает. Случается, что в том или ином проекте возникают некоторые полезные идеи, которые могут быть использованы на общее благо людьми, которые могут их эффективно реализовать. Классический пример -
Tapestry. Использовать невозможно, но некоторые идеи очень привлекательны и будут учтены при разработке JSF 2.0.
P.S. К чему это я все? Собственно, к тому, что если вы хотите создать качественный продукт, нужно очень ответственно подходить к выбору его зависимостей.