Джавист Роман ☕️
Open in Telegram
Авторский канал Java разработчика с более, чем 9-летним опытом. GitHub: https://github.com/romankh3 Библиотека: https://t.me/romankh3books Чат: https://t.me/romankh3_chat
Show more1 602
Subscribers
No data24 hours
-17 days
-130 days
Posts Archive
1 602
jenv и три места, где живёт версия Java (часть 4)
Практический вывод: чем закрывать каждый из трёх
Собираю всё вместе.
1. Терминал —
jenv (или SDKMAN!, или что тебе ближе). Обязательно с jenv enable-plugin export, иначе первый пункт ты не закрыл, а только думаешь, что закрыл.
2. Сборка — toolchains в Gradle или Maven, зафиксированные в проекте. Единственное место, где версия принуждается, и вот почему: требование к JDK лежит в закоммиченном скрипте сборки, а билд-тул проверяет его сам, до компиляции. Не нашёл подходящую — падает: Gradle пишет No matching toolchains found for requested specification, Maven — Cannot find matching toolchain definitions. Собраться на случайной Java он в этом случае не может. .java-version и SDK в IDEA так не умеют — там договорённость, которую можно молча не соблюсти, и никто ничего не скажет.
3. IDE — Project Structure → SDK, руками, и следить, чтобы совпадало. Автоматизации тут я не нашёл.
Проверка, что всё сошлось, — три команды подряд, тридцать секунд:
jenv which java # что реально запустится в терминале
echo $JAVA_HOME # что из этого увидят mvn и gradle
mvn -version # или ./gradlew -version — чем собирается
И последним шагом — глазами в Project Structure. Да, глазами. Ничего лучше я пока не нашёл.
Вместо вывода
Серебряной пули не вышло. Вышел узкий инструмент, который честно делает свою треть работы, — при условии, что ты знаешь про `export`-плагин и не ждёшь, что он поставит тебе Java.
А самое ценное для меня оказалось не в утилите, а в том, что она заставила меня разложить по полочкам вещь, которой я много лет пользовался на автомате. Погружение в технику до руды, так сказать.
Всем добра!1 602
jenv и три места, где живёт версия Java (часть 3)
jenv или SDKMAN!
Раз уж мы про выбор — рядом стоит [SDKMAN!](https://sdkman.io/), и это первое, что мне скажут в комментариях. Разложу честно.
jenv
Плюсы:
— Узкий и предсказуемый, делает одну вещь.
— .java-version на проект, коммитится в репозиторий.
— Shim-ы и три уровня приоритета — механика простая, её видно насквозь.
— Не лезет туда, куда не просили.
Минусы:
— Не ставит JDK.
— JAVA_HOME — только через плагин, и об этом надо догадаться.
— Молчит на неизвестной версии.
— Документация на сайте отставала от README.
SDKMAN!
Плюсы:
— Ставит SDK сам, одной командой.
— Не только JDK: Maven, Gradle, Kotlin, Scala, Groovy.
— Живёт с 2012 года, вырос из GVM — Groovy enVironment Manager. Зрелость.
Минусы:
— Берёт на себя больше, чем «переключалка версий».
— Своя инфраструктура дистрибутивов, в которую надо вписаться.
Я пришёл к jenv случайно и остался — мне хватает узкой утилиты, а ставить JDK руками меня не раздражает. Если раздражает тебя — бери SDKMAN!, спорить не буду.
Есть ещё mise и asdf — универсальные менеджеры, один инструмент на все языки сразу. Я их не щупал, поэтому оценивать не берусь, просто знай, что они есть.
Кстати, про «а он вообще живой»: у jenv ~6,6k звёзд на GitHub, последний релиз 0.6.0 вышел 5 декабря 2025 года.
«А зачем всё это, если есть toolchains?»
Справедливый вопрос, и он самый частый. Отвечаю: это другой слой.
Toolchains отвечают на вопрос «чем собирать проект», а jenv — на вопрос «что у меня в терминале». В Gradle это разведено прямо в документации: JDK, на которой работает сам Gradle, и JDK, которой компилируется код, — две разные вещи. Появились toolchains в Gradle 6.7.
Больше того, Gradle умеет скачать JDK сам — auto-provisioning через toolchain resolver plugins, типовой пример это Foojay Toolchains Plugin. Ограничение: качает только GA-релизы, early access не качает.
Следствие: если у тебя Gradle с настроенными toolchains, версия сборки уже зафиксирована в репозитории и от твоей локальной переключалки не зависит вообще. Менеджер версий тебе нужен для другого — для того, что ты набираешь руками.
А что у Maven? Механизм есть, но устроен иначе, и я бы не сказал, что он закрывает вопрос так же плотно. Требования пишутся в pom.xml через maven-toolchains-plugin, а пути к JDK лежат в toolchains.xml — по умолчанию в ~/.m2/. То есть на машине, а не в репозитории: файл машинно-зависимый и не коммитится. И JDK Maven за тебя не скачает — установи руками и пропиши <jdkHome>. Так что «зафиксировали версию в репе» в мавеновском случае получается наполовину.
продолжение ниже
1 602
jenv и три места, где живёт версия Java (часть 2)
Три уровня приоритета — и грабля вторая
Разобравшись с
export, я полез настраивать проекты. Здесь всё логично, но знать надо заранее.
Уровней три, приоритет такой: `shell` > `local` > `global`.
Команда — Область — Приоритет
jenv global <версия> — вся система, умолчание — низкий
jenv local <версия> — текущий каталог, пишет .java-version — средний
jenv shell <версия> — текущая сессия терминала — высокий
И вот вторая грабля, на которой спотыкаются все: `jenv local` не меняет версию в уже открытой сессии. Ты стоишь в каталоге, выполнил jenv local 17.0.8, набираешь java -version — а там прежняя. Классическое «я же настроил, почему не работает». Для текущей сессии нужен jenv shell.
Грабля третья: он молчит
Самая неприятная из трёх.
Если в .java-version записана версия, которой нет в jenv versions, jenv её просто игнорирует. Не ругается. Не предупреждает и не подсказывает, что версию надо сначала добавить через jenv add. Ты уверен, что репозиторий сам всё настроил. Он не настроил ничего.
Мне такое поведение не нравится — лучше бы падал. Поэтому сверяй .java-version со списком jenv versions руками: сам jenv о расхождении не скажет.
Диагностика, если что-то не сходится: jenv doctor и jenv which java — покажет, какой бинарник реально дёргается.
Зачем `.java-version` в git
Это, пожалуй, лучшее, что jenv даёт команде. Версия перестаёт быть знанием в чьей-то голове и становится частью репозитория. Новый человек делает git clone и получает версию вместе с кодом.
Пара практических деталей:
— В файле может быть номер (`17.0.8`) или имя из jenv versions (`openjdk-17.0.8`). Второе стабильнее.
— Оговорка честная: это конвенция, а не принуждение. Работает при условии «у коллеги стоит jenv и нужная JDK». У коллеги без jenv это просто текстовый файлик в корне, который ничего не делает.
Узел: три места, где живёт версия Java
Когда я закончил разбираться с JAVA_HOME, до меня дошло, что «версия Java на проекте» — это три разных настройки:
1. Что запускается, когда ты набираешь `java` в терминале. Скрипты, jshell, разовые прогоны, утилиты.
2. Чем собирается проект. JDK, на которой стартуют mvn и gradle, — а если в проекте настроены toolchains, то ещё и отдельная JDK, которой компилируется код.
3. Чем компилирует IDE. Project Structure → SDK.
Со вторым пунктом я сам сначала запутался, поэтому проговорю отдельно. Плагин export его частично закрывает: он выставляет JAVA_HOME, а от JAVA_HOME стартуют и Maven, и Gradle. Пока toolchains в проекте нет, эта же JDK код и компилирует — переключил версию через jenv, поменялась и сборка.
Связь рвётся в тот момент, когда toolchains появились. Дальше компилятор выбирается по правилам toolchain-резолвинга, и JAVA_HOME на него уже не влияет: за ним остаётся только вопрос, на какой JVM запустился сам билд-тул. В документации Gradle это разведено прямым текстом, к ней вернусь ниже. То есть export закрывает второй пункт ровно до первого проекта с toolchains, а дальше перестаёт.
Между тремя пунктами нет никакой связи. Никто не сверяет их между собой, ошибки не будет — всё просто работает по-разному в трёх местах. А наружу это вылезает самой дорогой фразой в командной разработке: «у меня собирается, у тебя нет».
jenv закрывает пункт первый и только его. Продавать его как решение «проблемы версий Java» — врать, поэтому и не получается написать про него простой гайд «поставь и пользуйся».
продолжение ниже1 602
Shadow AI — почему инженеры скрывают, что пользуются ИИ
Доброго дня, инженеры и те, кто инженеров ведёт.
Слушал подкаст Code of Leadership, выпуск про AI-assisted engineering. Полтора часа про то, как правильно встроить ИИ в разработку: копайлоты, MCP, метрики, место ИИ в SDLC. Разговор хороший, по делу. И где-то в середине проскочил термин, за который я зацепился и с которым хожу уже неделю — shadow AI. Проскочил сноской, в ряду прочих ИБ-рисков, между утечками и комплаенсом.
А я на этой сноске завис. Потому что мне кажется, что она интереснее основного разговора.
Полный текст — в файле ниже.
1 602
Самая сложная задача в разработке не писать код, а назвать его 😁
...или сказ о том, как я час сижу придумываю новое название сервиса так, чтобы оно и смысл имело и чтобы не конфликтовало с названиями других сервисов...
1 602
Практически это значит: смена инструмента стоит переписывания тонкой обёртки, а не переноса всей методологии. Отвалится доступ, выйдет что-то лучше, работа потребует другого стека — база останется. Толстый скилл в такой момент придётся разбирать вручную, вспоминая, что там накопилось за полгода.
Та же логика работает в команде. Правила и промпты, лежащие в репозитории рядом с кодом, а не в личных настройках каждого, — это тот же принцип на другом масштабе: артефакт общий, инструмент у каждого свой.
Всем добра! Да прибудет с вами AI.
1 602
Obsidian + Claude: Принцип тонких скиллов: контекст-оунером остаётся vault.
—-
Всем привет! Последние полгода года я погружаюсь со скафандром в мир Obsidian, а также в мир AI-агентов, от этого есть мысли, которые хотелось бы закрепить. Поэтому следующие серии заметок буду выносить мысли обо всем этом.
—-
Сегодня хочу поговорить над тем, какие лучше использовать скилы в клоде в контексте работы со своим личным хранилищем. Да, достаточно большой ЦА, но что делать, сейчас это меня интересует, дивный новый мир дает о себе знать.
Продолжим...
Скилл — это инструкция, которую ассистент подгружает себе сам, когда узнаёт задачу. Соблазн — записать в него всё: процедуру, форматы, правила, контекст, если используешь Obsidian как основное место хранения всего, то так делать не надо.
Скилл должен быть тонким. В нём — только триггер, пути к заметкам, механика внешних источников и несколько правил, которые нельзя потерять. Содержательная часть — порядок шагов, форматы, банки вопросов, эталоны, антипаттерны — живёт в vault.
Иначе знание раздваивается: одна версия в заметке, другая внутри скилла. И вторая устаревает молча — ты правишь заметку в Obsidian, а ассистент продолжает работать по своей копии.
Толстый и тонкий — разница
Толстый скилл содержит всю процедуру целиком. Работает автономно, даже если vault недоступен. Но каждая правка требует отдельного действия: «обнови скилл». Через месяц уже не помнишь, где актуальная версия.
Тонкий скилл начинается со строки «прочитай в vault такие-то файлы и следуй им». Дальше — только то, что физически не может жить в заметке: как искать гугл-таблицу, что делать при превышении лимита контекста, какие правила критичны настолько, что их нельзя оставлять на волю чтения.
Проверка: если я правлю заметку в Obsidian и поведение ассистента меняется без дополнительных действий — скилл тонкий.
Плюсы и минусы такого подхода
Плюсы
• Один источник истины. Правишь в Obsidian — работает сразу. Не нужно помнить о втором месте.
• Знание видимо. Заметка в графе, с бэклинками, доступна поиску. Скилл — чёрный ящик: чтобы узнать, что внутри, надо спросить ассистента.
• Версионирование бесплатно. Vault в git — видно, когда и зачем менялась процедура. У скилла истории нет.
• Связность. Заметка линкуется через [[...]] с людьми, проектами, другими промптами и становится частью системы. Скилл — изолированный текст.
• Читается человеком. Ритуал открывается в Obsidian и работает как обычный чеклист, даже когда ассистента рядом нет.
• Дешевле контекст. Ассистент подтягивает только нужные разделы, а не тащит весь процесс каждый раз.
• Проверяемость. Видно, чему именно он следовал: файл открыт, можно ткнуть пальцем в строку.
Минусы
• Зависимость от доступности vault. Нет подключённой папки — скилл превращается в оглавление без содержания.
• Лишний шаг чтения. Пара обращений к диску перед стартом; на длинных заметках заметно.
• Дисциплина формулировок. Заметка теперь не только для тебя, но и для машины: расплывчатое «подвести итоги» надо превратить в конкретные шаги.
• Риск разъезда всё же остаётся. Если в скилле продублировать хоть кусок процедуры — он устареет. Дублировать нельзя вообще, только ссылаться.
• Хрупкость путей. Переименуешь заметку — скилл сломается молча. Пути стоит держать в одном разделе, чтобы чинить в одном месте.
• Труднее поделиться. Толстый скилл отдаётся целиком; тонкий без vault бесполезен.
Главное следствие: работа портируется
Пока знание лежит в vault, оно не привязано к конкретному ассистенту.
Ритуал недели, промпт дайджеста, банк вопросов — обычные markdown-файлы. Их читает Cursor, открыв ту же папку. Их можно вставить в чат ChatGPT. По ним можно работать руками, без всякого AI. Claude в этой схеме — не владелец процесса, а один из исполнителей: тонкий скилл лишь описывает, когда взяться за инструкцию, а сама инструкция общая.
1 602
Милости из прошлого open source. Придется сходить и зарелизить новую версию, раз уж пользуются люди 😁
1 602
Отдал перплексити на аутсорс сгенерировать поздравление на основе моих текстов на канале. Вышло неплохо:
С наступающим 2026 годом.
Пусть в новом году всё, что действительно важно, наконец перестанет откладываться «на потом».
Пусть задач меньше, чем ресурсов, а энергии больше, чем дедлайнов.
Чтоб люди вокруг были как хороший код‑ревью: честные, внимательные и по делу.
Желаю:
• дохода, который растёт быстрее инфляции;
• проектов, за которые не стыдно;
• решений, после которых не хочется переписывать всё с нуля.
Берегите себя, своё здоровье и своё внимание.
Остальное как‑нибудь прикрутим по дороге.
С наступающим 2026‑м.
1 602
Вот это пригорело у ребят, что даже сделали сайтик:
https://neprivet.com 😂
В целом ноль осуждения, реально бесит
1 602
Кстати, кому понравилась статья - человек таки решился открыть свой канал после реакции на его запись. Причем даже не забросил сразу, пишет в том же духе.
Кому интересно - залетайте @thegodproduct)
1 602
Начало выше 👆
## Второй этап: найм бизнесовых и системных аналитиков
Как только команда обоснована и согласована у руководства, а также PO и TL провели ревью бэклогов и роадмапа, тогда можно начинать смотреть в сторону того, чтобы формировать уже более приземленные данные по необходимым для реализации требований.
Работа по каждому из анализов начинается сразу же, как только появится аналитик, так как нужно разбирать как продуктовый, так и технический бэклог.
Аналитики в тесной кооперации с продактом и тимлидом расширяют, дополняют и проводят более глубокую детализацию в ходе которой можно уже наверняка сказать кто и в каком объеме будет нужен для решения поставленных задач.
Также, стоит провести еще раз пересмотр состава команды на уже более детализированных данных после просмотра тимлида, продакта и аналитиков. *Здесь важно понять, что работа тимлидом и аналитиков начинается заранее, чтобы более правильно подготовить понятный и ожидаемый процесс разработки, в котором минимизированы проблемы переделок из-за изменяющихся планов.*
## Третий этап: найм разработчиков и тестировщиков
Далее, на основе оценок по необходимым работам от аналитиков уже можно строить мысли над тем, чтобы начать нанимать в команду разработчиков и тестировщиков.
На этом этапе уже можно более детально ответить на вопрос сколько именно нужно разработчиков и тестировщиков. Обычно берут одного тестировщика на 3 разработчиков.
Команда должна быть пропорциональна, чтобы не создавать бутылочное горлышко в процессе разработки с одной стороны или неэффективного использования капасити с другой.
Если хочется большей оптимизации, то приоритет в том, кого именно лучше взять сперва тестировщиков и разработчиков, выбрать в сторону первого, так как до старта разработки уже с готовым системным анализом можно смело проводить тестирование документации и написание тест-кейсов.
Чтобы избежать проблемы того, что анализ и тестирование могут не поспевать за разработкой, стоит сделать фору для анализа и тестрования, чтобы они успели подготовить почву для разработки.
## Вместо вывода
Разумеется это лишь мнение и может быть оспорено в комментариях, если у вас есть что добавить - смело пишите об этом.
Набрасывал свои мысли по этому поводу без гугления лучших практик специально для того, чтобы сфокусироваться на своей позиции.
-----
Это была первая статья, которую отсмотрели еще до публикации, интересный опыт, продолжим. Кто хочет попробовать себя - пишите, будем создавать комьюнити внутри комьюнити.
Всем добра 👍
