Как вы можете сделать Java лучше

aa4c61c8c5cca13bea59239e6af6d2f8.png

Многие люди жалуются, что в Java чего-то не хватает, что-то глючит или медленно работает. Хорошая новость: у вас есть возможность не жаловаться, а своими силами сделать Java лучше. Java практически полностью открыта в виде проекта OpenJDK. У этого проекта есть свои особенности, но в целом вам ничего не мешает самим сообщать о проблемах, исправлять их и даже разрабатывать новый функционал. В этой статье я немного расскажу, как это делать новичку.

У проекта OpenJDK есть багтрекер — JIRA. Там вы можете поискать и проверить, известна ваша проблема или она новая. Однако человек с улицы не может там зарегистрироваться и писать туда. Официальный способ сообщить о проблеме в Java (или даже предложить улучшение) — это воспользоваться формой Java Bug Report. Эта форма создаёт тикет в JIRA с префиксом JI (Java Issue, номер тикета придёт вам на указанный e-mail). На время премодерации ваш тикет скрыт от посторонних глаз. Если премодерация проходит успешно, тогда ваша проблема мигрирует в публичный проект (например, с префиксом JDK), и её смогут увидеть все. Плюс этой формы в том, что это относительно несложно, не требует регистрации и вообще каких-то персональных данных. Минус в том, что эти формы просматривают не прямо разработчики Java, а специальная команда webbug group. Есть риск, что ваше сообщение будет долго болтаться нерассмотренным (даже если с точки зрения разработчиков оно важно). Вот этот мой тикет месяц болтался в премодерации, пока я не попросил хорошего знакомого из Oracle подопнуть людей. Может даже случиться, что по недосмотру ваш тикет вообще отклонят, как случилось, например, с моим знакомым здесь. Проблема проявлялась только в OpenJDK, но не проявлялась в OracleJDK, и webbug group посчитала, что проблема не стоит внимания. Опять удалось разобраться только благодаря хорошему знакомому.

Также случается, что тикет успешно прошёл премодерацию и попал в публичный проект, но вам об этом не сообщили. Поэтому можно время от времени проверять URL вида https://bugs.openjdk.java.net/browse/JI-xxxxxxx, подписывая в конце JI-номер, который у вас есть. Если премодерация пройдена, вас перенаправит на публичный тикет, иначе вы увидите сообщение об ошибке.

Во всяком случае, обязательно чётко описывайте проблему и приводите минимальный пример, который её воспроизводит. Чем проще он будет, тем больше шансов, что на него обратят внимание.

Как видим, с этой формой бывают проблемы. Зачастую лучше сообщить о проблеме в соответствующий mailing-list. OpenJDK поддерживает множество списков рассылки и вам обязательно стоит подписаться на списки в сфере ваших интересов. Полистайте архивы списков, чтобы понять, мертвы они или нет. Например, если у вас какая-то проблема с лямбдами, вряд ли стоит сейчас писать в lambda-dev, потому что проект lambda завершён с выходом Java-8 и список неактивен. Скорее всего вам подойдёт compiler-dev, так как обычно проблемы с лямбдами — это проблема компилятора Java.

Подписаться на список и писать в него может любой желающий, здесь проблем нет. Будьте только внимательны с аттачами: большинство типов файлов режется. Я для надёжности не посылаю ничего кроме *.txt и проверяю по архиву, попало ли сообщение на самом деле в список (в нормальной ситуации оно отображается в архиве сразу после отправки). Эти списки читают реальные разработчики, поэтому если вы столкнулись с интересной проблемой, путь до её решения будет короче.

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

Более экзотический вариант — пожаловаться о своей проблеме на StackOverflow. Там бывают разработчики OpenJDK и даже сотрудники Oracle, но, конечно, они не читают всё подряд и вполне возможно, что ваше сообщение просто не заметят. А если заметят, то не захотят этим заниматься. У меня это сработало один раз и то только после объявления bounty. Мне ответил Brian Goetz, признав мою проблему багой. Разработчики сами завели тикет и исправили. Конечно, полагаться на успех в данном случае не стоит.

Ещё более экзотический вариант — пожаловаться о проблеме на Java-конференции. На последнем JPoint cheremin рассказывал об escape-анализе и привёл пример интересного случая с Arrays.asList, где он ломается (презентация, слайды 69 и ниже). Прослушав его доклад, я не поленился исправить эту проблему. Конечно, успех в этом случае тоже никто не гарантирует.

Теперь у вас есть много способов сообщить о баге. Но что если руки чешутся самим пописать код? Для начала стоит разобраться с инфраструктурой.

Все OpenJDK проекты хранятся в Mercurial-репозиториях, доступных здесь. Сейчас разрабатывается jdk9 и обычно вам потребуется подрепозиторий dev. Там дальше выбор из нескольких отдельных репозиториев вроде jdk (библиотека классов), hotspot (виртуальная машина) и т. д. Если проблема обнаружена в текущей версии Java (например, в java8), но осталась и в java9, то исправлять её сперва будут в java9, а потом уже портировать в обновления java8 (если предполагаемая польза от портирования перевешивает риск внесения изменений). Большинство проблем восьмёрки всё-таки только исправляют в девятке, но в восьмёрку не переносят. Выкачивайте нужный вам репозиторий и потратьте время на изучение его устройства. Если вы собрались исправлять библиотеку классов, вам потребуется путь вроде /src//share/classes/ в репозитории jdk9/dev/jdk.

Если вы исправили код, хорошо бы убедиться, что ваш патч работает, как надо. Я, если честно, так и не разбирался с тем, как правильно собрать OpenJDK с нуля. Вместо этого я устанавливаю последнюю готовую сборку Java-9 из проекта Kenai. Я копирую в отдельный каталог только изменённые java-файлы затем компилирую их как-нибудь так (пример для изменений в пакете java/util из модуля java.base):

$ javac -Xmodule:java.base -d out/java.base src/java/util/*.java

А потом запускаю какое-нибудь тестовое приложение с помощью такой команды:

$ java -Xpatch:out MyTest.java

Опции -Xmodule и -Xpatch появились в проекте Jigsaw. До этого работало -Xbootclasspath/p:, в Java-9 этой опции нет.

Хорошо бы однако написать нормальный юнит-тест, прямо в репозитории. Для запуска тестов в OpenJDK используется специальный инструмент jtreg. К сожалению, готовые сборки уже полгода как не обновлялись, а это критично, потому что изменения, связанные с Jigsaw, вызывают проблемы в старых версиях jtreg. Так что придётся разобраться, как самим собрать jtreg.

Вообще сами тесты сейчас пишут обычно с помощью TestNG, но есть и junit, и множество старых тестов, когда просто запускается некий класс с неким методом main, который не должен упасть с исключением. Инструмент jtreg позволяет абстрагировать весь зоопарк и содержит много полезных настроек.

Если вы всё-таки сделать вклад в Java, вы попадаете на нижнюю ступеньку иерархии OpenJDK. На ней вы можете посылать исключительно простые патчи (скажем, тривиальная опечатка в документации). Для этого вы собираете patch-файл (например, с помощью hg diff -g) и посылаете его в соответствующий список рассылки со словом [PATCH] в теме. Маленький патч лучше послать прямо в теле письма вместе с объяснением. Если под ваш патч есть тикет в JIRA, номер тикета тоже обязательно укажите в теме. Далее следует ждать, пока кто-нибудь из разработчиков не согласится спонсировать патч. Если вам совсем ничего не отвечают, можно вежливо подпинывать людей раз в пару недель. Возможно, вы ошиблись мейлинг-листом, но тогда вам скорее всего скажут, куда следует на самом деле переслать патч.

Если ваш патч не совсем тривиален, вы можете пойти этим же путём, но его не смогут закоммитить, пока вы не подпишите Oracle Contributor Agreement. Естественно, раз большая корпорация стоит за проектом, без юридических вопросов не обойтись. Вы соглашаетесь, что посылаете код вашего личного авторства и передаёте его в совладение Oracle (но при этом не лишаетесь прав на него и можете сами делать с ним что хотите, а Oracle будет делать, что он хочет). Распечатываете соглашение, читаете его (там немного), подписываете, сканируете и посылаете на указанный e-mail. Будьте готовы, что обработка займёт не меньше недели. В случае успеха вас известят по e-mail, и ваше имя появится в длинном списке. В этот момент вы получаете статус OpenJDK Contributor, и ваши патчи могут спонсировать.

Когда вы успешно пропихнёте 2–3 не самых тривиальных патча, вы можете просить о статусе OpenJDK Author. Для этого вы пишете письмо лидеру проекта (в jdk9 это Mark Reinhold) и перечисляете свои патчи со ссылками на коммиты. В случае успеха вам открываются новые возможности. Во-первых, sftp-доступ на сервер cr.openjdk.java.net (потребуется SSh public key), где вы сможете публиковать запросы на code review. Во-вторых, вы наконец-то получаете учётную запись в JIRA. Теперь можно радоваться и забыть о первой половине статьи: вы можете сами нормально сообщать о багах, причём не только в том компоненте, в который вы посылали патчи. Также можно голосовать за баги, подписываться на уведомления и так далее. Ещё с этого момента ваше имя появится в этом списке. Тут можно посмотреть статусы людей в разных проектах.

Однако на уровне OpenJDK Author вам всё ещё требуются спонсоры для ваших патчей. Теперь вы должны не посылать патч в мейлинг-лист, а генерировать специальный набор HTML-ек с помощью инструмента webrev (это ksh-скрипт и ради него мне пришлось водрузить виртуалку с Ubuntu, под виндой я его не смог запинать). Выглядит это примерно так. Сгенерировав webrev, вы посылаете ссылку на него в список рассылки на code-review и готовитесь к замечаниям. Кто-то всё ещё должен согласиться закоммитить ваш код, но автором коммита уже будете числиться вы сами.

Следующий уровень — это OpenJDK Committer. Чтобы им стать, вас должен выдвинуть на это звание какой-нибудь коммитер в основном списке проекта (например, jdk9-dev). Для этого, как правило, требуется иметь хотя бы 8 нетривиальных изменений в проекте. Голосование очень простое — никто не должен быть против. С этим званием вам уже не потребуется спонсор. Вы сможете сами коммитить свои изменения и даже спонсировать чужие. Но, разумеется, это не отменяет code review.

Наконец, вы можете достичь уровня OpenJDK Reviewer. Тут примерно то же самое — выдвижение, голосование, но требования уже строже. Выдвигать и голосовать могут только ревьюверы, требуется минимум три голоса «за» при отсутствии голосов «против». Этот статус позволит вам формально рецензировать чужие изменения. Подробнее о статусах и порядке их приобретения можно почитать здесь.

Исправлять баги в Java в принципе не очень сложно, если проявить достаточно терпения и усидчивости, чтобы со всем разобраться. Гораздо сложнее продвигать новые возможности, меняющие публичный API. Здесь ваши гениальные идеи могут легко завернуть. Чтобы выглядеть весомее, я рекомендую не начинать с фич, а стать хотя бы автором на каких-нибудь простых багах. Можно просто порыть в открытых тикетах в JIRA и найти что-нибудь, что вам покажется несложным. Такого довольно много, у продвинутых разработчиков не всегда есть время разгребать мелочи. Если вы всё-таки предлагаете фичу, не поленитесь изучить историю вопроса: поищите в архивах списков рассылки. Возможно, она обсуждалась и по какой-то причине решили её не делать. Подумайте, есть ли у вас новые доводы.

Программируйте с удовольствием и делайте Java лучше!

© Habrahabr.ru