Abhängigkeit Hölle - Dependency hell

Dependency Hell ist ein umgangssprachlicher Begriff für die Frustration einiger Softwarebenutzer, die Softwarepakete installiert haben, die Abhängigkeiten von bestimmten Versionen anderer Softwarepakete aufweisen.

Das Abhängigkeitsproblem tritt auf, wenn mehrere Pakete Abhängigkeiten von denselben gemeinsam genutzten Paketen oder Bibliotheken aufweisen, sie jedoch von unterschiedlichen und inkompatiblen Versionen der gemeinsam genutzten Pakete abhängen. Wenn das gemeinsam genutzte Paket oder die gemeinsam genutzte Bibliothek nur in einer einzigen Version installiert werden kann, muss der Benutzer das Problem möglicherweise beheben, indem er neuere oder ältere Versionen der abhängigen Pakete beschafft. Dies kann wiederum andere Abhängigkeiten aufheben und das Problem auf einen anderen Paketsatz verlagern.

Probleme

Die Abhängigkeitshölle nimmt mehrere Formen an:

Viele Abhängigkeiten
Eine Anwendung hängt von vielen Bibliotheken ab , erfordert lange Downloads, viel Speicherplatz und ist sehr portabel (alle Bibliotheken sind bereits portiert, sodass die Anwendung selbst problemlos portiert werden kann). Es kann auch schwierig sein, alle Abhängigkeiten zu finden, die durch ein Repository behoben werden können (siehe unten). Dies ist teilweise unvermeidlich; eine Anwendung, die auf einer gegebenen Computerplattform (wie Java ) aufgebaut ist, erfordert die Installation dieser Plattform, aber weitere Anwendungen erfordern sie nicht. Dies ist ein besonderes Problem, wenn eine Anwendung einen kleinen Teil einer großen Bibliothek verwendet (was durch Code-Refactoring gelöst werden kann ) oder eine einfache Anwendung auf viele Bibliotheken angewiesen ist.
Lange Abhängigkeitsketten
Wenn apphängt davon ab liba, was hängt davon ab libb, ... , was hängt davon ab libz. Dies unterscheidet sich von "vielen Abhängigkeiten", wenn die Abhängigkeiten manuell aufgelöst werden müssen (z. B. beim Versuch, zu installieren app, wird der Benutzer aufgefordert, libazuerst zu installieren . Beim Versuch, zu installieren liba, wird der Benutzer dann aufgefordert, zu installieren libbusw.). Manchmal treten jedoch während dieser langen Kette von Abhängigkeiten Konflikte auf, wenn zwei verschiedene Versionen desselben Pakets erforderlich sind (siehe widersprüchliche Abhängigkeiten weiter unten). Diese langen Abhängigkeitsketten können durch einen Paketmanager gelöst werden, der alle Abhängigkeiten automatisch auflöst. Abgesehen davon, dass es mühsam ist (alle Abhängigkeiten manuell aufzulösen), kann die manuelle Auflösung Abhängigkeitszyklen oder Konflikte maskieren.
Widersprüchliche Abhängigkeiten
Wenn app1abhängig von libfoo 1.2, und app2abhängig von libfoo 1.3, und verschiedene Versionen von libfoonicht gleichzeitig installiert werden können, dann app1und app2können nicht gleichzeitig verwendet (oder installiert werden, wenn das Installationsprogramm Abhängigkeiten prüft). Wenn möglich, wird dies dadurch gelöst, dass gleichzeitige Installationen der verschiedenen Abhängigkeiten zugelassen werden. Alternativ muss die vorhandene Abhängigkeit zusammen mit der gesamten davon abhängigen Software deinstalliert werden, um die neue Abhängigkeit zu installieren. Ein Problem , auf Linux - Systemen mit Paketen von einem anderen Händler zu installieren (die nicht empfohlen oder sogar funktionieren sollten) ist , dass die resultierende lange Kette von Abhängigkeiten zu einer widersprüchlichen Version der führen kann C - Standardbibliothek (zB das GNU C Library ), von denen Tausende von Paketen abhängen. In diesem Fall wird der Benutzer aufgefordert, alle diese Pakete zu deinstallieren.
Zirkuläre Abhängigkeiten
Wenn von application Aabhängig ist und nicht ohne eine bestimmte Version von ausgeführt werden kann application B, aber application Bwiederum von einer bestimmten Version von abhängt und ohne diese nicht ausgeführt werden kann application A, dann wird das Upgrade einer Anwendung eine andere zerstören. Dieses Schema kann tiefer in der Verzweigung sein. Seine Auswirkungen können ziemlich gravierend sein, wenn es Kernsysteme betrifft oder Software selbst aktualisiert: Ein Paketmanager (A), der eine bestimmte Laufzeitbibliothek (B) benötigt, um zu funktionieren, kann sich selbst (A) mitten im Prozess blockieren, wenn Upgrade dieser Bibliothek (B) auf die nächste Version. Aufgrund einer falschen Version der Bibliothek (B) ist der Paketmanager (A) jetzt kaputt - somit ist kein Rollback oder Downgrade von Bibliothek (B) möglich. Die übliche Lösung besteht darin, beide Anwendungen herunterzuladen und bereitzustellen, manchmal aus einer temporären Umgebung.
Abhängigkeiten des Paketmanagers
Es ist möglich, dass eine Abhängigkeits-Hölle entsteht , wenn ein vorbereitetes Paket über einen Paketmanager (zB APT ) installiert wird , aber dies ist unwahrscheinlich, da die großen Paketmanager ausgereift sind und die offiziellen Repositorys gut gepflegt werden. Dies ist bei aktuellen Versionen von Debian und wichtigen Derivaten wie Ubuntu der Fall . Eine Abhängigkeits-Hölle kann jedoch entstehen, wenn ein Paket direkt über einen Paket-Installer (zB RPM oder dpkg ) installiert wird .
Diamantenabhängigkeit
Wenn eine Bibliothek A von Bibliotheken B und C abhängt, hängen sowohl B als auch C von Bibliothek D ab, aber B erfordert Version D.1 und C erfordert Version D.2. Der Build schlägt fehl, da in der endgültigen ausführbaren Datei nur eine Version von D vorhanden sein kann.
Paketmanager wie yum sind anfällig für Konflikte zwischen Paketen ihrer Repositorys, was in Linux-Distributionen wie CentOS und Red Hat Enterprise Linux zu einer Hölle der Abhängigkeit führt .

Lösungen

Versionsnummerierung
Eine sehr häufige Lösung für dieses Problem ist es, ein standardisiertes Nummerierungssystem zu haben, bei Software eine bestimmte Anzahl für jede Version verwendet (auch bekannt als Major - Version ) sowie eine Subnummer für jede Revision (auch bekannt als kleinere Version ), zB: 10 0,1, oder 5. 7 . Die Hauptversion ändert sich nur, wenn Programme, die diese Version verwendet haben, nicht mehr kompatibel sind. Die Nebenversion kann sich selbst mit einer einfachen Revision ändern, die andere Software nicht daran hindert, damit zu arbeiten. In solchen Fällen können Softwarepakete dann einfach eine Komponente anfordern, die eine bestimmte Hauptversion und eine beliebige Nebenversion (größer oder gleich einer bestimmten Nebenversion) hat. Als solche funktionieren sie weiterhin und Abhängigkeiten werden erfolgreich aufgelöst, selbst wenn sich die Nebenversion ändert. Die semantische Versionierung (auch bekannt als "SemVer") ist ein Beispiel für den Versuch, eine technische Spezifikation zu erstellen, die speziell formatierte Zahlen verwendet, um ein Softwareversionsschema zu erstellen.
Privat pro Anwendungsversionen
Der in Windows 2000 eingeführte Windows-Dateischutz verhinderte, dass Anwendungen System-DLLs überschrieben. Entwickler wurden stattdessen ermutigt, "Private DLLs" zu verwenden, Kopien von Bibliotheken pro Anwendung im Verzeichnis der Anwendung. Dies nutzt die Windows-Suchpfadeigenschaft, dass der lokale Pfad immer vor dem Systemverzeichnis mit den systemweiten Bibliotheken priorisiert wird. Dies ermöglicht ein einfaches und effektives Shadowing von Bibliotheksversionen durch spezifische Anwendungsversionen und verhindert so die Abhängigkeitshölle.
PC-BSD, bis einschließlich Version 8.2, ein Vorgänger von TrueOS (ein auf FreeBSD basierendes Betriebssystem ) legt Pakete und Abhängigkeiten in in sich geschlossene Verzeichnisse in /Programme ab , was Beschädigungen beim Upgrade oder Ändern von Systembibliotheken vermeidet. Es verwendet einen eigenen "PBI" (Push Button Installer) für die Paketverwaltung.
Parallele Installation mehrerer Versionen
Die Versionsnummerierungslösung kann verbessert werden, indem die Versionsnummerierung auf eine vom Betriebssystem unterstützte Funktion erhöht wird. Dies ermöglicht einer Anwendung, ein Modul/eine Bibliothek durch einen eindeutigen Namen und eine Versionsnummer-Einschränkung anzufordern, wodurch die Verantwortung für das Vermitteln von Bibliotheks-/Modulversionen von den Anwendungen auf das Betriebssystem effektiv übertragen wird. Ein gemeinsam genutztes Modul kann dann in einem zentralen Repository abgelegt werden, ohne dass die Gefahr besteht, dass Anwendungen beschädigt werden, die von früheren oder späteren Versionen des Moduls abhängig sind. Jede Version bekommt einen eigenen Eintrag, Seite an Seite mit anderen Versionen desselben Moduls.
Diese Lösung wird in Microsoft Windows- Betriebssystemen seit Windows Vista verwendet, wo der Global Assembly Cache eine Implementierung einer solchen zentralen Registrierung mit zugehörigen Diensten ist und in das Installationssystem/Paketmanager integriert ist. Gentoo Linux löst dieses Problem mit einem Konzept namens Slotting, das die Installation mehrerer Versionen von Shared Libraries ermöglicht.
Intelligente Paketverwaltung
Einige Paketmanager können intelligente Upgrades durchführen, bei denen gleichzeitig voneinander abhängige Softwarekomponenten aktualisiert werden, wodurch auch das Problem der Hauptnummerninkompatibilität behoben wird.
Viele aktuelle Linux- Distributionen haben auch Repository- basierte Paketverwaltungssysteme implementiert, um zu versuchen, das Abhängigkeitsproblem zu lösen. Diese Systeme sind eine Schicht über dem RPM , dpkg oder anderen Paketierungssystemen , die darauf ausgelegt sind , Abhängigkeiten automatisch aufzulösen , indem sie in vordefinierten Software - Repositorys suchen . Beispiele dieser Systeme umfassen Apt , Yum , Urpmi , ZYpp , Portage , Pacman und andere. Typischerweise handelt es sich bei den Software-Repositorys um FTP- Sites oder -Websites, Verzeichnisse auf dem lokalen Computer oder über ein Netzwerk freigegebene Verzeichnisse oder, viel seltener, Verzeichnisse auf Wechselmedien wie CDs oder DVDs. Dies beseitigt die Abhängigkeitshölle für Software, die in diesen Repositorys verpackt ist, die normalerweise vom Linux-Distributionsanbieter verwaltet und weltweit gespiegelt werden. Obwohl diese Repositorys oft riesig sind, ist es nicht möglich, jede Software darin zu haben, so dass die Hölle der Abhängigkeiten dennoch auftreten kann. In allen Fällen werden die Repository-Betreuer immer noch mit der Abhängigkeitshölle konfrontiert.
Installationsoptionen
Da verschiedene Teile der Software verschiedene Abhängigkeiten haben, ist es möglich , in einen bekommen Teufelskreis der Abhängigkeit Anforderungen oder einen ständig wachsenden Baumes von Anforderungen, da jedes neues Paket installiert wird mehrere verlangt. Systeme wie das Advanced Packaging Tool von Debian können dies lösen, indem sie dem Benutzer eine Reihe von Lösungen präsentieren und dem Benutzer erlauben, die Lösungen nach Wunsch zu akzeptieren oder abzulehnen.
Einfache Anpassbarkeit in der Programmierung
Wenn Anwendungssoftware so konzipiert ist, dass ihre Programmierer in der Lage sind, die Schnittstellenschicht, die mit dem Betriebssystem, dem Fenstermanager oder der Desktop-Umgebung befasst ist, einfach an neue oder sich ändernde Standards anzupassen, dann müssten die Programmierer nur die Benachrichtigungen der Umgebungsersteller überwachen oder Komponentenbibliotheks-Designer und passen ihre Software schnell mit Updates für ihre Benutzer an, alles mit minimalem Aufwand und ohne kosten- und zeitaufwändige Neugestaltung. Diese Methode würde Programmierer ermutigen, diejenigen, von denen sie abhängig sind, unter Druck zu setzen, um einen angemessenen Benachrichtigungsprozess aufrechtzuerhalten, der für alle Beteiligten nicht belastend ist.
Strenge Kompatibilitätsanforderung bei der Codeentwicklung und -pflege
Werden die Anwendungen und Bibliotheken unter Berücksichtigung einer garantierten Abwärtskompatibilität entwickelt und gewartet, kann jede Anwendung oder Bibliothek jederzeit durch eine neuere Version ersetzt werden, ohne dass etwas kaputt geht. Dies lindert zwar nicht die Vielzahl der Abhängigkeiten, erleichtert jedoch die Arbeit von Paketmanagern oder Installern erheblich.
Software-Appliances
Ein anderer Ansatz zur Vermeidung von Abhängigkeitsproblemen besteht darin, Anwendungen als Software-Appliance bereitzustellen . Eine Software-Appliance kapselt Abhängigkeiten in einer vorintegrierten, in sich geschlossenen Einheit, sodass sich Benutzer nicht mehr um das Auflösen von Software-Abhängigkeiten kümmern müssen. Stattdessen wird die Last auf die Entwickler der Software-Appliance verlagert.
Tragbare Anwendungen
Eine Anwendung (oder eine Version einer bestehenden herkömmlichen Anwendung), die vollständig in sich abgeschlossen ist und keine Installation erfordert. Es ist so codiert, dass alle erforderlichen Komponenten enthalten sind, oder es ist so konzipiert, dass alle erforderlichen Dateien in einem eigenen Verzeichnis gespeichert werden und kein Abhängigkeitsproblem entsteht. Diese sind oft unabhängig von dem System, an das sie angeschlossen sind, lauffähig. Anwendungen in RISC OS und dem ROX Desktop für Linux verwenden Anwendungsverzeichnisse , die ähnlich funktionieren: Programme und ihre Abhängigkeiten sind in eigenen Verzeichnissen (Ordnern) in sich abgeschlossen.
Diese Verteilungsmethode hat sich auch bei der Portierung von Anwendungen, die für Unix-ähnliche Plattformen entwickelt wurden, auf Windows als nützlich erwiesen, wobei der auffälligste Nachteil mehrere Installationen derselben Shared Libraries sind . Beispielsweise enthalten Windows-Installer für gedit , GIMP und XChat alle identische Kopien des GTK- Toolkits, das diese Programme zum Rendern von Widgets verwenden. Wenn jedoch von jeder Anwendung unterschiedliche Versionen von GTK benötigt werden, ist dies das richtige Verhalten und vermeidet erfolgreich die Abhängigkeitshölle.

Plattformspezifisch

Auf bestimmten Computerplattformen hat "Dependency Hell" oft einen lokalen spezifischen Namen, im Allgemeinen den Namen von Komponenten.

Siehe auch

Verweise

Externe Links