Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

Двоичная (бинарная)совместимость в программном обеспечении кратко

Лекция



Привет, Вы узнаете о том , что такое двоичная совместимость, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое двоичная совместимость, бинарная совместимость , настоятельно рекомендую прочитать все из категории Разработка программного обеспечения и информационных систем.

Двои́чная совмести́мость, бина́рная совмести́мость (англ. binary compatibility) — вид программной совместимости, позволяющий программе работать в различных средах без изменения ее исполняемых файлов.

Этот термин часто используется в значении «совместимость операционных систем», и в таком случае означает способность уже скомпилированной версии программы для одной операционной системы работать в другой операционной системе без перекомпиляции. К примеру, практически все программы, написанные для Windows 2000, можно запустить в Windows XP — это означает, что Windows 2000 и Windows XP бинарно (двоично) совместимы.

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

Слом двоичной совместимости означает прекращение поддержки программ и обязательное требование перекомпиляции и возможных исправлений в программе, чтобы она заработала. К примеру, после того, как компания Apple начала использовать в своих компьютерах процессоры Intel, была сломана двоичная совместимость со всеми приложениями, написанными для процессоров PowerPC. Чтобы не лишиться всех разработанных в прошлом программных продуктов для операционной системы Mac OS, компания Apple использует легкий транслятор Rosetta, переводящий вызовы операционной системы Mac OS для PowerPC в вызовы Mac OS для Intel. Этот пример демонстрирует также возможный метод борьбы со сломом двоичной совместимости.

В операционной системе Solaris 10 для x86 существует возможность запускать приложения для Linux без перекомпиляции с помощью BrandZ. На платформе SPARC такая возможность отсутствует.

Возможно, многие из вас задавались вопросами вроде «А что будет, если кто-то подложит к моему приложению неправильную версию библиотеки?». Вопрос хороший, а ответ на него и некоторые другие вы найдете в этом топике. Для затравки задачка: пусть есть два интерфейса и класс, реализующий один из них:

  Двоичная (бинарная)совместимость в программном обеспечении


А также класс, в котором есть метод foo, перегруженный для A и B. Этот метод вызывают от экземпляра класса C:

  Двоичная (бинарная)совместимость в программном обеспечении


Вполне очевидно, что выведется «A». Не менее очевидно, что если сказать, что C implements A, B, то получится ошибка компиляции (тем, кому последнее не очевидно, могу порекомендовать почитать про то, как происходит выбор методов. Например, в стандарте в разделе 15.12.2 или в более просто описывающих местах).
Но вот что произойдет, если мы перекомпилируем только C.java, а потом запустим CompatibilityChecker из уже имеющегося класс-файла, является уже более сложным вопросом. Заинтересованы? Прошу под кат!

Static dispatch

Те, кто знают, что перегруженные методы выбираются во время компиляции, могут сообразить, что по этой причине в класс-файле будет сразу записана информация о том, какой же метод вызывать, и потому в результате выведется «A». Проверим это предположение:

  Двоичная (бинарная)совместимость в программном обеспечении


Действительно, как можно заметить по инструкции с отступом 19, идет вызов вполне конкретного метода. Впрочем, те, кто слышал про верификатор, могут возразить и предположить, что он заметит, что это какие-то не те пчелы класс C изменился, и швырнет исключение. К счастью, они ошибаются, ведь верификатор проверяет только лишь корректность структуры классов и интерфейсов, а не соответствие версий класс-файлов.

Итак, запустим-таки наш код и убедимся, что изначальное предположение было правильным: выведется действительно «А».

Кроме того, можно предположить, что в виртуальной таблице адресов может оказаться какой-то неправильный адрес, и потому все сломается в рантайме с NoSuchMethodError. Об этом говорит сайт https://intellect.icu . Это предположение тоже ошибочно, так как вызывается метод foo(A), и в виртуальной таблице он такой один. Другое дело, если бы были наследники, его переопределяющие…

Dynamic dispatch

Пусть у нас есть три следующих класса:

  Двоичная (бинарная)совместимость в программном обеспечении 

И класс, вызывающий foo в разных вариантах:

 Двоичная (бинарная)совместимость в программном обеспечении 

Все, конечно же, знают, что поскольку у переотпределенных типов методы выбираются в рантайме, изначальный вывод будет таким:

Двоичная (бинарная)совместимость в программном обеспечении 


Самое время сделать пакость, подменив класс-файл от A на результат компиляции следующего кода:

 Двоичная (бинарная)совместимость в программном обеспечении


Понять, что в данном случае произойдет, довольно просто. Во-первых, все попытки вызвать методы, где foo вызывается у экземпляпа класса A, точно вылетят с NoSuchMethodError. Среди этих попыток также находится и вызов super.foo() в классе C. Во-вторых, как мы уже видели раньше, метод B.foo() вызовется успешно.

Теперь изменим тактику: снова сделаем A.foo таким, каким он и был, но теперь поменяем B и C, вообще удалив из них переопределение метода foo:

Двоичная (бинарная)совместимость в программном обеспечении 


При запуске кода dynamic dispatch обнаружит только по одной записи для A.foo, и потому во всех случаех вызовет его, в результате чего мы увидем в консоли только буквы «A» и полное отсутствие каких-либо исключений.

Продолжим наши изыскания, снова переопределив методы в B и C. После запуска, как мы и можем ожидать, dynamic dispatch обнаружит все записи в виртуальной таблице, и даст точно такой же вывод, как и тот, который мы получили бы, заново перекомпилировав все.

Поля несоответствующих типов

Ранее мы пробовали экспериментировать только с методами. Посмотрим теперь, что бывает с полями. Пусть есть класс, хранящий значение типа int и наследник этого класса:

 Двоичная (бинарная)совместимость в программном обеспечении


И, традиционно, потребитель класса B:

  Двоичная (бинарная)совместимость в программном обеспечении


Добавим теперь в класс B собственное поле с таким же именем:

 Двоичная (бинарная)совместимость в программном обеспечении


Посмотрим, какой байт-код был сгенерирован для CompatibilityChecker:

  Двоичная (бинарная)совместимость в программном обеспечении


Этот листинг может сбить с толку, полкольку на отступе 11 в комменте вроде как сказано, что поле принадлежит B. Потому стоит полагать, что при перекомпиляции B мы столкнемся с ошибкой. Однако оказывается, что это вовсе не так. Поскольку физически поле есть только у базового класса, операнд команды putfield указывает именно на то самое нужное поле, в результате чего после изменений код продолжает работать.

А что вообще говорит спецификация?


В спецификации под бинарную совместимость отведена целая глава, в которой основным понятием является «двоично совместимое» или «безопасное» изменение. В спецификации утверждается, что при внесении только безопасных изменений гарантируется безопасное выполнение приложения без перекомпиляции всего остального и ошибок линковки. Как ни странно, но во всей огромной главе нет точного определения двоично совместимой операции, однако есть куча примеров:

  • Изменение реализации существующих методов, конструкторов или блоков инициализации
  • Добавление новых полей, методов и конструкторов существующим классам и интерфейсам
  • Удаление приватных полей, методов и конструкторов класса
  • Перемещение методов наверх по иерархии классов
  • Добавление новых классов и интерфейсов


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

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

  Двоичная (бинарная)совместимость в программном обеспечении

Произведем два безопасных изменения: добавим метод foo в интерфейс A и изменим реализацию метода main класса CompatibilityChecker:

 Двоичная (бинарная)совместимость в программном обеспечении  


При запуске, как вы могли понять, произойдет ошика, а именно AbstractMethodError: B.foo()V, чего по идее быть не должно. Эту проблема известна и лежит в самой основе обработки байт-кода Java. Были предложения по исправлению ситуации, но они пока ни к чему не привели.

Итак, ответ на вопрос, профигурировавший в самом начале статьи («А что будет, если кто-то подложит к моему приложению неправильную версию библиотеки?») такой: «А кто ж его знает. Смотря в чем та версия, которая использовалась при компиляции, отличается от той, которая используется в рантайме».

В статье не затронуты некоторые очевидные вещи. Например, что при несовместимых изменениях вроде удаления методов и классов или превращения класса в интерфейс, будут кидаться беспощадные ошибки вроде NoSuchMethodError, NoClassDefFoundError или IncompatibleClassChangeError.

Вау!! 😲 Ты еще не читал? Это зря!


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

Из статьи мы узнали кратко, но содержательно про двоичная совместимость
создано: 2021-06-15
обновлено: 2021-06-15
132265



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Разработка программного обеспечения и информационных систем

Термины: Разработка программного обеспечения и информационных систем