Блеск и нищета джавовых веб-фреймворков

в 10:10, , рубрики: java, jbreak, jbreak2018, jsf, web, wicket, Блог компании JUG.ru Group, Разработка веб-сайтов

Привет! Помоги выбрать веб-фреймворк? Требования: модный, молодежный, популярный, качественный фреймворк для соло-технономада.

Надо ли нам каждый месяц читать очередной пост про это?

Блеск и нищета джавовых веб-фреймворков - 1

Несколько лет участия в проектах на границе энтерпрайза и системщины окончательно отбили нюх. Чтобы разобраться в вопросе, я заглянул в топ гугла и обнаружил там кучу однобоких рейтингов. Наверное, самым лучшим оказался Java Web Frameworks Index от ZeroTurnaround.

Хорош он тем, что

  • создатели основательно погулили, а также притащили туда статистику StackOverflow, LinkedIn, GitHub — примерно то же самое, что сделали бы и мы;
  • очевидно, что для ZeroTurnaround верное понимание расклада по фреймворкам — это основа для зарабатывания бабла.

Вот как рейтинг выглядит на момент написания статьи:

Rank Framework Popularity
1 Spring MVC 28.82
2 JSF 15.2
3 Spring Boot 13.35
4 GWT 7.74
5 Grails 6.35
6 Struts 5.4
7 Dropwizard 4.9
8 Play framework 3.26
9 JHipster 2.49
10 JAX-RS 2.44
11 Vaadin 2.15
12 Seam 1.94
13 Wicket 1.91
14 Tapestry 1.9
15 Sparkjava 0.77
16 Vert.x 0.76
17 Rapidoid 0.25
18 Lagom 0.24
19 Ratpack 0.13

Стойте, там Struts в первой десятке? Серьезно? Кажется, я ничего не потерял за эти несколько лет. Точнее, даже начиная с раннего средневековья.

Давайте пробежимся по списку.

Оу, Spring MVC и Spring Boot — это два разных элемента списка? Наверное, это можно понять и простить? (напишите в комментариях!). Не имеет смысла спрашивать, при чем тут Spring — он, как и Docker, всегда при чем.

Блеск и нищета джавовых веб-фреймворков - 2

Вот что страшно, это то, что между ними (то есть по сути, на первом месте) находится JSF. Когда-то я делал на ЛОРе несколько обсуждений на тему, какой шаблонизатор для Java лучший. Годы шли, но всегда находилась половина треда с универсальным ответом: зачем тебе шаблонизатор, когда есть JSF? Вначале был просто JSP/JSTL, но потом они потихоньку сдали позиции, и остался один JSF.

Давайте глянем, что есть нового в JSF. Да, теперь мы можем больше не писать FacesContext facesContext = FacesContext.getCurrentInstance();. Можно сделать @Inject FacesContext facesContext;. Или если ты EL-камикадзе, то можно даже #facesContext. В нужных местах можно навешать @FlowMap или достать настроечку через @ManagedProperty ("#{bean.property}") private String stringProperty; Имхо, всё это совершенно очевидные рефакторинги, в соответствии с текущей модой на синтаксис. То же касается валидации в форме <f:convertDateTime type="localDate" pattern="MM/dd/yyyy"/> — ну запилили в Восьмерке Date-Time API, пришлось отреагировать, чтобы люди не писали бесконечных конвертеров самостоятельно. Список можно продолжить. Так и представляешь, как архитекторы Oracle пилили эти фичи за один вечер, батон колбасы и бутылку водки.

Интересная фича — это тэг <f:websocket>, который можно юзать вот так:

<h:body> 
   <f:websocket channel="jaxArticle"
    onmessage="function(message){alert(message)"} /> 
</h:body> 

В целом, прогресс с 2009 года (наш эквивалент «XV века») не перестает поражать воображение.

Дальше по рейтингу — Grails и PlayFramework. Grails — это, строго говоря, вообще не Java, а JVM. C PlayFramework под Java API не встречался со времен Play 1, поэтому — можете рассказать об этом в комментариях? Пока условно будем считать PlayFramework вторым годным фреймворком из списка, просто по причине наличия чудесного Scala API (за который можно простить ему историю с ORM и прочие мелкие ляпы).

Grails. Ну, допустим. Закроем глаза, тем более что Барух обещал, что Groovy — это круто. Но у них до сих пор открыты тикеты против Java 9! Ничего личного, чуваки, но это никуда не годится. В самом Groovy тоже какая-то фигня творится с поддержкой модулей и Java 9: насколько понял, --add-opens=java.base/* с нами навечно.

Wicket, Vaadin и GWT хотелось бы выделить в отдельную группу. С Vaadin и GWT я встречался только в смысле правки багов в чужих проектах. Но с Wicket у меня давний и болезненный опыт. Не знаю, кто первый притащил Wicket в Новосибирск, но он как эпидемия прошелся по нашим Java-компаниям. Мы писали на Wicket систему для управления профсоюзами в США. Мы писали мобильную MMO-игру. И для российских государственных компаний тоже писали разное, так что если заходите вылечиться от насморка в соседнюю больницу — осторожней, возможно, там в компьютерах полный неоперабельный Wicket. Каждый раз меня не оставляло ощущение, что Wicket не нужен вообще никогда и нигде. Может быть, про это стоит написать отдельную статью или даже целую книгу?

Давайте посмотрим еще раз на стартовую картинку. (Не знаю, кто настоящий автор, я ее нагуглил вот здесь).

Блеск и нищета джавовых веб-фреймворков - 3

Wicket появился в том же году, что и термин AJAX. В свою очередь, AJAX спас веб, благодаря этому мы все с вами такие богатые и знаменитые, хе-хе. В свою очередь, Wicket появился как средство управления Аяксом и как эксперимент был очень удачным. Потом он пошел в продакшн, и это история, полная боли и фейлов. С точки зрения архитектуры, он так никогда и не стал кластерным, и в некоторых компаниях стал причиной полного отсутствия горизонтального масштабирования. С перфомансом у него очень плохо — просто гляньте, сколько он весит в памяти и как медленно отвечает на запросы. Ну или просто откройте wicket.apache.org и посчитайте, за сколько загрузится страница.

С AJAX у него тоже так и не вышло: в 2017 году нас все еще преследуют оптимизации в названиях параметров. Пожалуйста, поднимите руки все, кто с первого раза догадается о назначении следующих параметров запроса: m, mp, e, f, sc, dt, wr, ch, bh, pre, bsh, ah, sh, fh, coh, ep, dep, rt, ad, sp, tr.

Ответы на задачку находятся здесь. Спойлер: АД расшифровывается как «allow default». Это булевский флаг, который показывает, разрешать ли исполнение поведения по умолчанию для того элемента HTML, который слушает данное событие.

Да, многие из нас работают в банках, и там всё на GWT. Но, оглядываясь назад на этот долгий-долгий путь, давайте честно признаем: управлять JavaScript из Java — наиболее дурацкая и деструктивная идея, которая когда-либо приходила в голову.

Если посмотреть на репозиторий Wicket, становится очевидно, что в период с 2007 по середину 2010 он был скорее мертв, чем жив, и далее возродился силами всего одного пользователя GitHub — Martin Grigorov, который сделал туда около четырех тысяч коммитов.

Блеск и нищета джавовых веб-фреймворков - 4

Картинка хороша, но давайте обратим внимание на конкретные циферки.
git clone https://github.com/apache/wicket.git
cd ./wicket

И теперь долбанём адским однострочником:

git log --shortstat --pretty="%cE" | sed 's/(.*)@.*/1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/1 0 insertions(+), 2/;s/(+)$/(+), 0 deletions(-)/;s/insertions?(+), //;s/ deletions?(-)//' | awk 'BEGIN {name=""; files=0; insertions=0; deletions=0;} {if ($1 != name && name != "") { print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net"; files=0; insertions=0; deletions=0; name=$1; } name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net";}'

Или можно получить еще более подробную кумулятивную статистику:

sudo gem install git_fame
git fame

Более подробная статистика займет минут 30 (на SSD, на новеньком макбуке с мобильным i7).

Statistics based on master
Active files: 5,407
Active lines: 578,441
Total commits: 15,600

name loc commits files distribution (%)
martin-g 161,089 98 2,898 27.8 / 0.6 / 53.6
Igor Vaynberg 67,983 2,872 1,993 11.8 / 18.4 / 36.9
Juegen Donnerstag 66,234 1,867 2,250 11.5 / 12.0 / 41.6
andrea del bene 58,583 5 654 10.1 / 0.0 / 12.1
Eelco Hillenius 30,287 2,932 1,051 5.2 / 18.8 / 19.4
svenmeier 28,504 307 1,130 4.9 / 2.0 / 20.9
Martijn Dashorst 22,470 1,089 727 3.9 / 7.0 / 13.4
Frank Bille Jensen 19,854 235 1,403 3.4 / 1.5 / 25.9
Johan Compagner 17,637 1,484 1,503 3.0 / 9.5 / 27.8
Jonathan Locke 14,257 1,321 437 2.5 / 8.5 / 8.1
Jean-Baptiste Quenot 14,022 277 448 2.4 / 1.8 / 8.3
Gerolf Seitz 13,189 205 1,041 2.3 / 1.3 / 19.3
Matej Knopp 8,565 963 291 1.5 / 6.2 / 5.4
Peter Ertl 8,281 354 417 1.4 / 2.3 / 7.7
Pedro Henrique Oliveira d... 7,474 98 169 1.3 / 0.6 / 3.1
Tobias Soloschenko 6,373 100 161 1.1 / 0.6 / 3.0
Emond Papegaaij 4,624 168 207 0.8 / 1.1 / 3.8
Alastair Maw 3,257 422 172 0.6 / 2.7 / 3.2
Carl-Eric Menzel 2,338 36 112 0.4 / 0.2 / 2.1
Jesse Long 2,230 12 261 0.4 / 0.1 / 4.8
Jeremy Ryan Thomerson 2,146 51 84 0.4 / 0.3 / 1.6
Andrea Del Bene 1,999 46 450 0.3 / 0.3 / 8.3
bitstorm 1,972 14 116 0.3 / 0.1 / 2.1
Michael Mosmann 1,397 43 31 0.2 / 0.3 / 0.6
Felipe Campos de Almeida 1,396 4 24 0.2 / 0.0 / 0.4
klopfdreh 1,329 39 27 0.2 / 0.2 / 0.5
Janne Hietamaki 996 218 46 0.2 / 1.4 / 0.9
Timo Heikki Rantalaiho 883 42 105 0.2 / 0.3 / 1.9
Maurice Marrink 784 12 28 0.1 / 0.1 / 0.5
Bertrand Guay-Paquet 773 1 3 0.1 / 0.0 / 0.1
John Sarman 767 8 21 0.1 / 0.1 / 0.4
Maxim Solodovnik 716 26 38 0.1 / 0.2 / 0.7
sourceforge-skipoles 605 40 42 0.1 / 0.3 / 0.8
manuelbarzi 476 2 5 0.1 / 0.0 / 0.1
Domas Poliakas 432 9 9 0.1 / 0.1 / 0.2
Alexander Morozov 412 4 16 0.1 / 0.0 / 0.3
Thomas Götz 403 1 13 0.1 / 0.0 / 0.2
Martin Funk 313 3 20 0.1 / 0.0 / 0.4
Gwyn Richard Evans 249 62 67 0.0 / 0.4 / 1.2
admin 247 3 13 0.0 / 0.0 / 0.2
kensakurai 208 5 3 0.0 / 0.0 / 0.1
Michael Haitz 207 1 2 0.0 / 0.0 / 0.0
Guillaume Smet 204 3 7 0.0 / 0.0 / 0.1
Cedric Gatay 185 9 13 0.0 / 0.1 / 0.2
Thomas Matthijs 185 3 12 0.0 / 0.0 / 0.2
Roman Grigoriadi 169 1 12 0.0 / 0.0 / 0.2
Artur Michałowski 156 4 6 0.0 / 0.0 / 0.1
Martin Grigorov (Netwalk) 149 4 12 0.0 / 0.0 / 0.2
Robert Gruendler 127 6 8 0.0 / 0.0 / 0.1
Matthias Metzger 122 5 2 0.0 / 0.0 / 0.0
René Dieckmann 119 1 3 0.0 / 0.0 / 0.1
Ate Douma 114 14 15 0.0 / 0.1 / 0.3
Pedro Santos 110 2 4 0.0 / 0.0 / 0.1
Sebastien Briquet 110 3 3 0.0 / 0.0 / 0.1
Manuel Barzi 105 5 6 0.0 / 0.0 / 0.1
jac-czerwinski 94 4 4 0.0 / 0.0 / 0.1
Sven 82 1 8 0.0 / 0.0 / 0.1
ozeray 79 1 11 0.0 / 0.0 / 0.2
Thomas Heigl 75 1 4 0.0 / 0.0 / 0.1
Sebastien 71 2 4 0.0 / 0.0 / 0.1
Fridolin Jackstadt 42 2 6 0.0 / 0.0 / 0.1
meno 37 3 8 0.0 / 0.0 / 0.1
Thibault Kruse 33 2 2 0.0 / 0.0 / 0.0
Vit Rozkovec 24 1 1 0.0 / 0.0 / 0.0
Tim Fleming 16 2 5 0.0 / 0.0 / 0.1
Luke Niesink 13 2 4 0.0 / 0.0 / 0.1
Jan Blok 10 8 1 0.0 / 0.1 / 0.0
Nils Schmidt 9 1 1 0.0 / 0.0 / 0.0
Nick Pratt 9 1 2 0.0 / 0.0 / 0.0
slowery 8 1 2 0.0 / 0.0 / 0.0
astrapi69 4 5 2 0.0 / 0.0 / 0.0
Jezza 3 1 1 0.0 / 0.0 / 0.0
tatjana19 3 1 1 0.0 / 0.0 / 0.0
robert mcguinness 3 1 1 0.0 / 0.0 / 0.0
Peter Dave Hello 3 1 1 0.0 / 0.0 / 0.0
barney2k7 2 1 2 0.0 / 0.0 / 0.0
bsaad 1 1 1 0.0 / 0.0 / 0.0
Sander Evers 1 1 1 0.0 / 0.0 / 0.0
Yoann Rodière 1 1 1 0.0 / 0.0 / 0.0
Jeremy Thomerson 1 4 1 0.0 / 0.0 / 0.0
Peter Lamby 1 3 1 0.0 / 0.0 / 0.0
Dan Retzlaff 0 2 0 0.0 / 0.0 / 0.0
Jared Renzullo 0 1 0 0.0 / 0.0 / 0.0
Joe Schaefer 0 1 0 0.0 / 0.0 / 0.0
Leonid Bogdanov 0 3 0 0.0 / 0.0 / 0.0
Yoshiki Higo 0 1 0 0.0 / 0.0 / 0.0
cvs2svn 0 1 0 0.0 / 0.0 / 0.0

В любом случае, мы увидим, что Wicket, по сути, разрабатывается не более чем десятью людьми. Если кто-то из этих десяти человек навернется (особенно Мартин), то вашему свободному времени настанет неминуемый капец — придется вечерами и ночами сидеть и осознавать баги в рендеринге страницы.

Думаю, пора заканчивать избиение младенцев и сделать какой-то вывод.

Совсем недавно было такое время, когда мы возмущались «программистами на фреймворках». «Как же так, — говорили мы на собеседовании, — ты умеешь использовать Spring, но понятия не имеешь, как работает изнутри HashMap! Что за дичь!» В еще больший ужас мы приходили, когда человек начинал рассказывать о десятках различных фреймворков, ни один из которых он не знал даже приблизительно, но все успешно применял на практике. Совсем ужасно, когда человек сам написал пять веб-фреймворков и даже в них не разбирался!

Ну что ж, если долго жечь поляну, то в конце концов травы на ней не останется. В результате своих возмущений мы получили ситуацию, когда JavaScript-проекты растут как грибы после дождика, а вот создание новых фреймворков для Java оказалось не такой уж популярной задачей. Теперь вы легко найдете того самого Senior Framework Coder (если этот фреймворк — Spring Boot, JSF и Play), который назубок расскажет про устройство табличных компонентов и внутреннюю кухню хэшмапы, но вряд ли сможет написать пять своих фреймворков и десять вариантов хэшмапы. И ни одного такого, кто сможет написать нечто лучшее, чем Spring Boot.

Возможно, вот прямо сейчас стоит остановиться и начать раздувать большущий такой фреймворк-хайп. Что думаете?

И возвращаясь к стартовому вопросу. Эй, читатель! Помоги выбрать веб-фреймворк? Требования: модный, молодежный, популярный, качественный фреймворк, и чтобы им кто-то действительно пользовался в проде, а не как Vert.x.

UPD: если кто-то из новосибирцев пишет на Wicket и не согласен с написанным выше, предлагаю встретиться на JBreak и перетереть за всю хурму. Как раз будет несколько месяцев, чтобы подготовиться к защите любимого фреймворка — готовьтесь тщательней :-)

Автор: olegchir

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js