Как стать автором
Обновить

Комментарии 40

Похожая ситуация со встроенной в Mac OS OpenSSL.
Удивительно, что по описанной мной проблеме нет никаких статей и описаний. Копал материалы с нуля, руководствуясь только дичайшим удивлением «и как это так вышло?!»

В своё время я пытался переупаковать HttpComponents с помощью maven shade и gradle на этапе сборки (не вышло, где-то использовалась рефлексия), а потом я увидел, что авторы HttpComponents (не от хорошей жизни) предоставляют отдельную сборку под android с другими названиями классов. Но этот вариант никак не подходил (я писал библиотеку, зависящую от HttpComponents), и пришлось отказаться от HttpComponents.


Это печально. Надо бы предусмотреть пункт в лицензии библиотек на случай подобного использования.

brew install openssl

Google довольно часто руководствуется принципом "здесь и сейчас", игнорируя правила, и через некоторое время пользователи остаются наедине с негибкими решениями.


Навскидку:
  • Описанная ситуация с нестабильной версией HttpComponents (включить нестабильную библиотеку в ОС, и тем самым запретить её обновления без костылей? серьёзно?)
  • Ограничение 64К методов в .dex (конечно, этого хватит всем).
  • Отсутствие generic-ов в go (сойдёт и так, пока вам не понадобятся самописные коллекции).
  • Отказ от использования исключений в языках, в которых они есть (в их библиотеках на С++ и по инерции на Java).
  • Нестандартное для Java соглашение об именовании полей (префикс m).

В принципе, этого достаточно, чтобы подходить с осторожностью к использованию их библиотек/технологий.

По некоторым пунктам я думаю были реальные причины сделать так.
  • Например dex был придуман когда телефоны были еще совсем маленькими. Еще кнопочными. И придумало его не гугл.
  • Префикс m это Венгерская нотация. Очень удобно раньше было. Понятно что сейчас IDE тебе все подскажут. Так исторически сложилось. Было написанно много кода и сейчас что либо менять, не имеет смысла.

Но если честно, то дело то не в корпорации. Дело в конкретных людях и принимаемых ими решениях. Создается впечатление что иногда когда произносят Google/Apple/Microsoft то априори там сидят люди и думаю: «Тааак, сейчас я выпилю эту либу, а потом перейду в другую контору и напишу свою на основе выпиленной и буду молодец.»
Я из статьи не до конца понял, чем вас не устроило OkHttp, кроме того что это «неприятно пахнущий форк»? Или вы говорите про какие то проекты которые существуют более 6 лет?
Меня не устроила библиотека OkHttp своей историй и тем, что в её использовании нет смысла, если есть хороший оригинал. Преимуществ OkHttp над Apache HttpComponents я не видел — возможно они есть, с интересом прочту.

В целом, у OkHttp просто нормальный апи из коробки, Apache Http без всяких врапперов просто невозможно пользоваться (ощущения очень схожи с употреблением Calendar API вместо JodaTime/ThreeTen)

Гмм, у меня таких проблем не было, но для простоты есть FluentApi:
Request.Get("http://targethost/homepage")
    .execute().returnContent();
Request.Post("http://targethost/login")
    .bodyForm(Form.form().add("username",  "vip").add("password",  "secret").build())
    .execute().returnContent();

Вроде легко и понятно.

Ну как бы, то что у библиотеки есть отдельная библиотека с Fluent API говорит о плохом дизайне основной библиотеки.

Да не так чтобы — это довольно стандартный подход, когда появляются упрощающие низкоуровневую работу вещи, примеры сплошь и рядом. Например, наличие ORM никоим образом не означает, что SQL плох.

Всё таки посмотрите API OkHttp. Аналогия с SQL плохая, более корректно было бы сказать что есть HTTP (SQL) и ORM (OkHttp, FluentApacheHttp).

А можете сказать, есть ли там поддержка SSL прокси и возможность обращения к айпишнику с произвольным именем хоста? Это не надуманный пример, это те самые задачи, которые у меня возникали. Интересно просто. Вроде никакой чёрной магии…

Прокси, конечно, поддерживаются. Более того, там есть Interceptors API который позволяет вклиниваться в механизм выполнения запросов и делать всё, что угодно.


Про обращение к айпишнику с произвольным именем хоста — если я правильно понял, то это решается заголовком Host и запросом на конкретный IP.

использовать перепакованную под другим пространством классов библиотеку, собранную неким товарищем на гитхабе (ссылка ниже). Там, правда, на самом деле версия 4.4, а не 4.5 — но это не так принципиально

Всегда можно самому собрать подобную сборку с помощью jarjar. Да и доверия у ней будет больше, чем «собранной неким товарищем».
На самом деле, всё не совсем так просто, я просто не стал упоминать все технические моменты. Текущие релизы от Apache не рассчитаны под Android, так что при своей пересборке нужно будет не только поменять пространство классов, но и как минимум:
Commons Logging replaced with Android Logging.
Base64 implementation from Commons Codec replaced with Android Base64.
Android default SSLSocketFactory used by for SSL/TLS connections.

Это из заметок к апачевскому релизу 4.3.
Хотя я как раз и написал, что лучше всего собрать самому.
Для name shadowing есть хороший плагин для gradle под названием shadow-jar. Возможно, стоит к нему присмотреться.
Да, крутая штука, я уже пользовался ей, когда в приложение нужно было включать библиотеку, которая уже есть в другой подключенной библиотеке. К сожалению, минус в том, что я написал выше — готовой сборки последних версий от Apache под Android просто нет.
А загрузить свою версию библиотеки при помощи своего класслоадера нельзя?
Не знаю, не видел такого подхода. Работающий пример с библиотеками Apache было бы очень интересно посмотреть. Навскидку возникает вопрос в быстродействии.

Класслоадер по-хорошему сначала должен искать стандартные классы (которые уже есть у его родителя), а потом — свои.

Как разработчик под Андроид со стажем, скажу — ничего необычного. Гугл есть гугл. Хуже них только Самсунг, который берет худо бедно работающий Андроид и портит во всех местах перед установкой на устройства.
В Apache HTTP нет дефолтного кеширования, компрессии, поддержки HTTP 2, cert pinning, автоматического повтора запросов, нормального пула соединений, как любая апач библиотека она огромна и поэтому годится только для десктопов. Я что-то совсем не вижу причин почему кто-то на андроиде может выбрать сейчас апач как HTTP движок для своего приложения кроме как нежелания перейти на что-то более современное.
Ваша неправда.
  1. Автоматические повторы запросов есть.
  2. Пул соединений точно есть, причём с кучей настроек.
  3. Насчёт «огромна» — полная библиотека весит мегабайт. При этом в вашем приложении она ни разу не целиком будет.
  4. Работа над поддержкой HTTP 2 идёт в пятой версии, но скажем честно — сейчас она никому не сдалась.
  5. А зачем вы делаете из мобильного приложения повторные запросы, которые будут кешированы?


Ещё аргументы есть? Не спор ради спора, хочется правда понять.
Ну ладно, в большинстве фигню написал ) Но смысл в том что на андроиде okhttp обновляется чуть ли не каждый месяц а апач — нет. Как следствие — okhttp выглядит и чувствуется как более современная удобная и быстрая библиотека.
Ну так стоковая — да, с 2008 не обновляется. А настоящая обновляется раз в месяц. Собственно речь в посте и была о том, что возможность нормального обновления была фактически сломана гуглом. Именно для создания видимости того, что их форк лучше.
Если заглянуть в список лицензий открытого ПО, используемого такими приложениями, как Google и Play Market, то можно увидеть, что там используется OkHTTP.
О да, товарищ, вы я смотрю, разработчик с опытом…
Во-первых, начиная с Андроида 4.2, под фасадом HttpConnection как раз OkHttp и используется, если бы вы разрабатывали под Андроид, то увидели бы это в стек-трейсе (пруф: https://android.googlesource.com/platform/external/okhttp/)
Под компресией подразумевается использование gzip по-умолчанию.
А теперь по-поводу Google Compression Proxy — он в любом случае не работает при использовании https, а если вы не использует https, то какая тогда по сути разница — за вами может любой следить. И я даже не знаю как его использовать в аппах, это вроде как фича Chrome browser.
Гмм, не мог предположить, что они так торжественно gzip приподнесли, который есть уже черт знает сколько времени у apache.
Про то, что под фасадом okhttp — да, не знал, но и обратного тоже не говорил, так что не вижу ничего некорректного в моих утверждениях.
По поводу Google compression proxy — я писал статью как его использовать.
Уточнение — да, посмотрел, OkHttp используется для HttpUrlConnection — правда, с версии 4.4, а не 4.2, как вы сказали. Что, впрочем, непринципиально и значения особого не имеет.

А если бы вы внимательно читали статью, то поняли бы, почему я не видел этого в стек трейсах — просто потому, что у HttpUrlConnection тупо не хватало для моих нужд и я использовал httpComponents.
К сожалению, впечатление от вашей статьи типа «Злой брат Гугл говорит вам не пользоваться Apache HttpComponents, чтобы следить за вами, а пользоваться надо вот этой».
Просто HttpUrlConnection (читай OkHttp) хватает в 99% случаях, просто у вас был очень специфический случай.
Возможно, именно так и сложилось — но я скорее хотел сказать, что не стоит отказываться от уже используемого httpComponents в погоне за не совсем адекватной рекомендацией Google.
Сложился пост именно из-за огромного количества вопросов на stack overflow и issues на github, где говорили, что надо вот срочно переезжать с httpComponents на okHttp.

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

А вы всё ещё помните милого парня Джесси Вилсона из Dalvik team?

Да.

А вы знаете, что сейчас он работает в Square? И именно он является создателем OkHttp?

Да.

Более того, вы знате, что OkHttp начинался как форк куска AOSP (Android Open Source Project), который в свою очередь брал свой код из Apache Harmony?

Да.

Так что это и есть по сути создание форка Apache с последующим выкидыванием оригинала из обращения (второй вариант из озвученных ранее Джесси в общении с Apache). Звучит довольно гнусно, не правда ли? Единственное что непонятно — была ли это инициатива Google или самого Джесси. Но поступил он крайне некрасиво, выкинув конкурентов с помощью Google и придя весь в белом со своим решением.

Я конечно не знаю всей истории, но в вашем изложении это звучит как какая-то теория заговора. Может быть всё куда проще, и OkHttp был создан как попытка улучшить HttpComponents? Может апачевская библиотека страдает от каких-то косяков, которые можно было исправить только переписыванием всего проекта, что Вилсон и сделал в OkHttp? Я не сравнивал их api, но может быть на OkHttp советуют переходить потому, что он лучше/удобнее/написан с учётом работы на Android-устройствах, в отличие от апачевского оригинала, а не потому, что Google и Вилсон коварны и вероломны?
Выводов я специально старался не делать, поскольку и без них звучит как теория заговора. Но гораздо чаще всё объясняется глупостью или жадностью.

Насчёт предположения о косяках — советую почитать ссылки на лист рассылки и джиру. Там видно, что каких-то косяков нет, и Apache были готовы исправлять что бы то ни было. А Вилсон сначала говорил, что у него нет времени на коммуникации, и вообще они все заняты в других «горящих» частях проекта… А затем написал свою библиотеку. Ну правда — не вижу я там каких-то технических проблем.
Послушайте вот этот выпуск подкаста Fragmented, там как раз Вилсон давал свой взгляд на проблемы HttpComponents, и причины, побудившие его создать OkHttp. Просто сейчас ваша статья излагает довольно односторонний взгляд на проблему.
К сожалению, подскасты и ютуб ролики это не мой формат — при попытке просмотра чувствую уходящее напрасно время. Буду страшно вам благодарен за выжимку или отдельную статью.

Предполагаю, что там речь шла о невозможности менять интегрированную в систему библиотеку без breaking changes. Но тут можно было легко поступить так же, как сделали с android.camera. Просто появился новый пакет android.camera2, старый можно было использовать, но с предупреждениями о том, что он не рекомендуется, deprecated и все дела. И тут ситуация была бы даже лучше. camera2 можно использовать только с API 21 (что ведёт к аду с имплиментацией обеих версий. А по факту все забивают и используют старый camera), в то время как подключаемую извне httpComponents можно было бы использовать в любых версиях API.

Взгляд у меня может быть односторонний, но основанный на комментариях самого Вилсона. Думаю, вы не сможете не согласиться с тем, что качество коммуникации было ужасно. И это ответы самого Вилсона, никто за них его не писал.
К сожалению, большинство разработчиков слепо верят Google и сразу считают, что библиотека Apache “плохая”, и нужно бежать выкидывать её из своего кода.

После этого ожидал увидеть сравнение OkHttp и Apache HttpComponents, чтобы понять, какая из бибилотек объективно лучше. Вместо этого увидел следующее:

Например, тот же OkHttp. Сам его не пробовал, но говорят, что библиотека хорошая… Ну и касательно именно OkHttp — я бы не стал использовать столь неприятно пахнущий форк.

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

Насчёт OkHttp — это не предубеждение, а личная позиция на основании проведённых исследований. Данная позиция может обуславливаться не только техническим характеристиками кода.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации