Dependency hell

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

Dependency hell (англ. Ад зависимостей) — это разговорный термин, обозначающий раздражение от некоторого программного обеспечения, которое зависит от специфичных версий других ПО.[1] Проблемы с зависимостями возникают у общих пакетов/библиотек, у которых некоторые другие пакеты имеют зависимости от несовместимых и различных версий общих пакетов. Если установлена одна версия общего пакета/библиотеки, для решения этой проблемы пользователю/администратору понадобится получить новые или старые версии зависимых пакетов. Это, в свою очередь, может нарушить работу других зависимых пакетов и добавить проблем в другой набор пакетов, таким образом образуя настоящий ад.

Обзор[править | править вики-текст]

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

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

Проблему «ада зависимостей» можно рассматривать как антипаттерн, где вина лежит не столько на поставщиках продукта, сколько на фреймворке, в рамки которого они должны входить.

Виды проблем[править | править вики-текст]

«Dependency hell» принимает несколько форм:

Множество зависимостей
Приложение зависит от большого числа объёмных библиотек, которые требуют длительных скачиваний, занимают много дискового пространства. Возможна ситуация, когда приложение построено на определённой платформе (например Java) и требует установки этой платформы, в то время, как 99% остальных ваших приложений поддержки этой платформы не требуют. Это частный случай проблемы когда либо приложение использует маленькую часть большой платформы и в конечном итоге требует установки всей платформы(что может быть решено только с помощью рефакторинга приложения), либо маленькое приложение опирается на большое число различных библиотек одновременно.
Длинные цепочки зависимостей
Приложение зависит от библиотеки "А", которая зависит от библиотеки "Б", ... , которая в свою очередь зависит от библиотеки "Я". Это частный случай проблемы "Множество зависимостей", с той разницей, что большое количество зависимостей осложнено их запутанной и длительной взаимосвязью, которая должна решаться вручную. (Пользователь устанавливает приложение, но ему выдаётся требование установить библиотеку "А", он устанавливает библиотеку "А", но при попытке это сделать библиотека "А" запрашивает установку библиотеки "Б" и т.д.
Иногда наличие такой длинной цепочки зависимостей, может приводить к возникновению конфликтов, когда разными компонентами цепочки требуются разные версии одного и того же пакета или библиотеки. (см. Конфликтующие зависимости) Такие длинные цепочки зависимостей должны решаться пакетными менеджерами, которые делают это в автоматическом режиме, вместо того чтобы заставлять пользователя решать их ручным способом, при котором зависимости могут остаться частично неудовлетворёнными (не все инсталляторы библиотек постоянно напоминают о всех своих зависимостях пользователю).
Конфликтующие зависимости
Если "Приложение 1" зависит от библиотеки "А" версии 1.2, а "Приложение 2" зависит от той же библиотеки "А", но уже версии 1.3, и различные версии библиотеки "А" не могут быть одновременно установлены, то "Приложение 1" и "Приложение 2" нельзя одновременно использовать (или даже установить, если установщики проверяют зависимости).
Когда возможно одновременное использование разных версий библиотеки - это решают путём параллельных установок разных версий библиотеки. В противном же случае, установка с использованием новой версии библиотеки должна сопровождаться удалением старой версии библиотеки и, соответственно, всех программ, которые зависят от неё т.к. они будут неработоспособны.
На Linux-системах эта проблема часто возникает при попытке установки в систему пакетов от разных разработчиков, которые не предназначены для этой версии системы. В таком случае удовлетворение долгой цепи зависимостей пакетов даже может привести, например, к запросу другой версии библиотеки glibc, одной из крайне важных, основополагающих системных библиотек. Если это случается пользователю будет предложено удалить тысячи пакетов, что по сути будет равноценно удалению, например, 80% системы, включая графические оболочки и сотни различных программ.
Циклические зависимости
Ситуация, когда приложение "А" версии 2 зависит от приложения "Б", которое зависит от приложения "В", которое в свою очередь зависит от приложения "А" , но версии 1. Это приводит к тому, что в пакетных системах типа RPM или DPKG, пользователь должен установить две версии одного и того же исходного приложения "А", что может оказаться недопустимо и не разрешено менеджером пакетов.[2] Однако на Linux-стсемах наличие циклической зависимости, чаще всего является результатом непонимания пользователем того, как пользоваться операционной системой и её менеджером пакетов.

Решения[править | править вики-текст]

Нумерация версий
The most obvious (and very common) solution to this problem is to have a standardised numbering system, wherein software uses a specific number for each version (aka major version), and also a subnumber for each revision (aka minor version), e.g.: 10.1, or 5.7. The major version only changes when programs that used that version will no longer be compatible. The minor version might change with even a simple revision that does not prevent other software from working with it. In cases like this, software packages can then simply request a component that has a particular major version, and any minor version (greater than or equal to a particular minor version). As such, they will continue to work, and dependencies will be resolved successfully, even if the minor version changes.
Параллельная установка различных версий ПО
The version numbering solution can be improved upon by elevating the version numbering to an operating system supported feature. This allows an application to request a module/library by a unique name and version number constraints, effectively transferring the responsibility for brokering library/module versions from the applications to the operating system. A shared module can then be placed in a central repository without the risk of breaking applications which are dependent on previous or later versions of the module. Each version gets it own entry, side by side with other versions of the same module. This solution is used in Windows operating systems since Windows Vista, where the Global Assembly Cache is an implementation of such a central registry with associated services and integrated with the installation system/package manager.
Хороший пакетный менеджер
Some package managers can perform smart upgrades, in which interdependent software components are upgraded at the same time, thereby resolving the major number incompatibility issue too.
Many current Linux distributions have also implemented repository-based package management systems to try to solve the dependency problem. These systems are a layer on top of the RPM, dpkg, or other packaging systems that are designed to automatically resolve dependencies by searching in predefined software repositories. Typically these software repositories are FTP sites or websites, directories on the local computer or shared across a network or, much less commonly, directories on removable media such as CDs or DVDs. This eliminates dependency hell for software packaged in those repositories, which are typically maintained by the Linux distribution provider and mirrored worldwide. Although these repositories are often huge it is not possible to have every piece of software in them, so dependency hell can still occur. In all cases, dependency hell is still faced by the repository maintainers.[3] Examples of these systems include Apt, Yum, Urpmi, ZYpp, Portage, Pacman and others.
PC-BSD (an operating system based on FreeBSD) avoids dependency hell by placing packages and dependencies into self-contained directories, which avoids breakage if system libraries are upgraded or changed. PC-BSD uses its own «PBI» (Push Button Installer) for package management.[4][5]
Настройки установщика
Because different pieces of software have different dependencies, it is possible to get into a vicious circle of dependency requirements, or (possibly worse) an ever-expanding tree of requirements, as each new package demands several more be installed. Systems such as Debian’s APT can resolve this by presenting the user with a range of solutions, and allowing the user to accept or reject the solutions, as desired.
Easy Adaptability in Programming
If application software is designed in such a way that its programmers are able to easily adapt the interface layer that deals with the OS, window manager or desktop environment to new or changing standards, then the programmers would only have to monitor notifications from the environment creators or component library designers and quickly adjust their software with updates for their users, all with minimal effort and a lack of costly and time-consuming redesign. This method would encourage programmers to pressure those upon whom they depend to maintain a reasonable notification process that is not onerous to anyone involved.
Software appliances
Another approach to avoiding dependency issues is to deploy applications as a software appliance. A software appliance encapsulates dependencies in a pre-integrated self-contained unit such that users no longer have to worry about resolving software dependencies. Instead the burden is shifted to developers of the software appliance.
Портативные приложения
An application (or version of an existing conventional application) that is completely self-contained and requires nothing to be already installed. It is coded to have all necessary components included, or is designed to keep all necessary files within its own directory, and will not create a dependency problem. These are often able to run independently of the system to which they are connected. Applications in RISC OS and the ROX Desktop for Linux use application directories, which work in much the same way: programs and their dependencies are self contained in their own directories (folders).[6]

На других платформах[править | править вики-текст]

On specific computing platforms, «dependency hell» often goes by a local specific name, generally the name of components.

См. также[править | править вики-текст]

Примечания[править | править вики-текст]

  1. Michael Jang. Linux annoyances for geeks. — O'Reilly Media, 2006.
  2. Dependency hell
  3. Nix fixes dependency hell on all Linux distributions. linux.com (22 декабря 2008). — «All popular package managers, including APT, RPM and the FreeBSD Ports Collection, suffer from the problem of destructive upgrades. When you perform an upgrade -- whether for a single application or your entire operating system -- the package manager will overwrite the files that are currently on your system with newer versions. As long as packages are always perfectly backward-compatible, this is not a problem, but in the real world, packages are anything but perfectly backward-compatible. Suppose you upgrade Firefox, and your package manager decides that you need a newer version of GTK as well. If the new GTK is not quite backward-compatible, then other applications on your system might suddenly break. In the Windows world a similar problem is known as the DLL hell, but dependency hell is just as much a problem in the Unix world, if not a bigger one, because Unix programs tend to have many external dependencies.»  Проверено 22 мая 2013.
  4. Package Management. Проверено 12 февраля 2013.
  5. The PBI Format for 9.0 and Beyond (Modified on 9 November 2012 when retrieved). Проверено 12 февраля 2013. PC-BSD Wiki page.
  6. Application directories. Проверено 7 сентября 2013.
  7. Weinstein, Paul Is Linux Annoying?. linuxdevcenter.com (11 сентября 2003). Проверено 10 апреля 2010.
  8. Проблема циклической перезагрузки обновления 3033929.

Ошибка в сносках?: Тег <ref> с именем «jamesdonald», определённый в <references>, не используется в предшествующем тексте.

Ссылки[править | править вики-текст]