El infierno de la dependencia es un término coloquial para la frustración de algunos usuarios de software que han instalado paquetes de software que dependen de versiones específicas de otros paquetes de software. [1]
El problema de la dependencia surge cuando varios paquetes tienen dependencias de los mismos paquetes o bibliotecas compartidos , pero dependen de versiones diferentes e incompatibles de los paquetes compartidos. Si el paquete compartido o la biblioteca solo se puede instalar en una única versión, es posible que el usuario deba solucionar el problema obteniendo versiones más nuevas o más antiguas de los paquetes dependientes. Esto, a su vez, puede romper otras dependencias y llevar el problema a otro conjunto de paquetes.
Problemas
El infierno de la dependencia adopta varias formas:
- Muchas dependencias
- Una aplicación depende de muchas bibliotecas , lo que requiere descargas largas, grandes cantidades de espacio en disco y es muy portátil (todas las bibliotecas ya están portadas, lo que permite que la aplicación en sí se transfiera fácilmente). También puede ser difícil ubicar todas las dependencias, que se pueden solucionar si se tiene un repositorio (ver más abajo). Esto es en parte inevitable; una aplicación construida en una plataforma informática determinada (como Java ) requiere que esa plataforma esté instalada, pero otras aplicaciones no la requieren. Este es un problema particular si una aplicación utiliza una pequeña parte de una gran biblioteca (que puede resolverse mediante la refactorización de código ), o una aplicación simple se basa en muchas bibliotecas. [2]
- Largas cadenas de dependencias
- Si
app
depende deliba
, que depende delibb
, ..., que depende delibz
. Esto es distinto de "muchas dependencias" si las dependencias deben resolverse manualmente (por ejemplo, al intentar instalarapp
, se le pide al usuario que lo instaleliba
primero. Al intentar instalarliba
, se le pide al usuario que lo instalelibb
, y así sucesivamente). A veces, sin embargo, durante esta larga cadena de dependencias, surgen conflictos en los que se requieren dos versiones diferentes del mismo paquete [3] (consulte las dependencias en conflicto a continuación). Estas largas cadenas de dependencias se pueden resolver con un administrador de paquetes que resuelva todas las dependencias automáticamente. Además de ser una molestia (resolver todas las dependencias manualmente), la resolución manual puede enmascarar ciclos de dependencia o conflictos. - Dependencias en conflicto
- Si
app1
depende delibfoo 1.2
,app2
depende delibfoo 1.3
y diferentes versiones delibfoo
no se pueden instalar simultáneamente, entoncesapp1
yapp2
no se pueden usar simultáneamente (o instalar, si el instalador verifica las dependencias). Cuando es posible, esto se resuelve permitiendo la instalación simultánea de las diferentes dependencias. Alternativamente, la dependencia existente, junto con todo el software que depende de ella, debe desinstalarse para instalar la nueva dependencia. Un problema en los sistemas Linux con la instalación de paquetes de un distribuidor diferente (que no se recomienda o incluso se supone que funciona) es que la larga cadena de dependencias resultante puede llevar a una versión conflictiva de la biblioteca estándar C (por ejemplo, la Biblioteca GNU C ), del que dependen miles de paquetes. Si esto sucede, se le pedirá al usuario que desinstale todos esos paquetes. - Dependencias circulares
- Si
application A
depende y no se puede ejecutar sin una versión específica deapplication B
, peroapplication B
, a su vez, depende y no se puede ejecutar sin una versión específica deapplication A
, entonces la actualización de cualquier aplicación romperá otra. Este esquema puede tener ramificaciones más profundas. Su impacto puede ser bastante fuerte, si afecta a los sistemas centrales o actualiza el software en sí: un administrador de paquetes (A), que requiere una biblioteca de tiempo de ejecución específica (B) para funcionar, puede bloquearse (A) en medio del proceso cuando actualizar esta biblioteca (B) a la siguiente versión. Debido a la versión incorrecta de la biblioteca (B), el administrador de paquetes (A) ahora está roto, por lo que no es posible deshacer o degradar la biblioteca (B). La solución habitual es descargar e implementar ambas aplicaciones, a veces desde un entorno temporal. - Dependencias del administrador de paquetes
- Es posible [4] que el infierno de dependencias resulte de la instalación de un paquete preparado a través de un administrador de paquetes (por ejemplo, APT ), pero esto es poco probable ya que los principales administradores de paquetes han madurado y los repositorios oficiales están bien mantenidos. Este es el caso de las versiones actuales de Debian y sus principales derivados, como Ubuntu . El infierno de dependencias, sin embargo, puede resultar de instalar un paquete directamente a través de un instalador de paquetes (por ejemplo, RPM o dpkg ).
- Dependencia de diamantes
- Cuando una biblioteca A depende de las bibliotecas B y C, tanto B como C dependen de la biblioteca D, pero B requiere la versión D.1 y C requiere la versión D.2. La compilación falla porque solo puede existir una versión de D en el ejecutable final.
- Los administradores de paquetes como yum , [5] son propensos a tener conflictos entre los paquetes de sus repositorios, causando un infierno de dependencias en distribuciones de Linux como CentOS y Red Hat Enterprise Linux .
Soluciones
- Numeración de versiones
- Una solución muy común a este problema es tener un sistema de numeración estandarizado, en el que el software usa un número específico para cada versión (también conocida como versión principal ), y también un subnúmero para cada revisión (también conocida como versión secundaria ), por ejemplo: 10 .1, o 5. 7 . La versión principal solo cambia cuando los programas que usaban esa versión ya no serán compatibles. La versión menor puede cambiar incluso con una simple revisión que no impide que otro software funcione con ella. En casos como este, los paquetes de software pueden simplemente solicitar un componente que tenga una versión principal en particular y cualquier versión menor (mayor o igual a una versión menor en particular). Como tales, seguirán funcionando y las dependencias se resolverán con éxito, incluso si cambia la versión menor. El control de versiones semántico (también conocido como "SemVer" [6] ) es un ejemplo de un esfuerzo para generar una especificación técnica que emplea números formateados específicamente para crear un esquema de control de versiones de software.
- Versiones privadas por aplicación
- La protección de archivos de Windows introducida en Windows 2000 impedía que las aplicaciones sobrescribieran las DLL del sistema. En cambio, se animó a los desarrolladores a utilizar "DLL privadas", copias de bibliotecas por aplicación en el directorio de la aplicación. Esto utiliza la característica de ruta de búsqueda de Windows de que la ruta local siempre se prioriza antes que el directorio del sistema con las bibliotecas de todo el sistema. Esto permite un sombreado fácil y efectivo de versiones de bibliotecas por aplicaciones específicas, evitando así el infierno de dependencias. [7]
- PC-BSD, hasta la versión 8.2 inclusive, un predecesor de TrueOS (un sistema operativo basado en FreeBSD ) coloca paquetes y dependencias en directorios independientes en / Programas , lo que evita la rotura si se actualizan o cambian las bibliotecas del sistema. Utiliza su propio "PBI" (Push Button Installer) para la gestión de paquetes. [8]
- Instalación en paralelo de varias versiones
- La solución de numeración de versiones se puede mejorar elevando la numeración de versiones a una función compatible con el sistema operativo. Esto permite que una aplicación solicite un módulo / biblioteca con un nombre único y restricciones de número de versión, transfiriendo efectivamente la responsabilidad de la intermediación de las versiones de la biblioteca / módulo de las aplicaciones al sistema operativo. Luego, un módulo compartido se puede colocar en un repositorio central sin el riesgo de romper aplicaciones que dependen de versiones anteriores o posteriores del módulo. Cada versión tiene su propia entrada, al lado de otras versiones del mismo módulo.
- Esta solución se utiliza en los sistemas operativos Microsoft Windows desde Windows Vista, donde Global Assembly Cache es una implementación de dicho registro central con servicios asociados e integrado con el sistema de instalación / administrador de paquetes. Gentoo Linux resuelve este problema con un concepto llamado slotting, que permite instalar múltiples versiones de bibliotecas compartidas. [9]
- Gestión inteligente de paquetes
- Algunos administradores de paquetes pueden realizar actualizaciones inteligentes, en las que los componentes de software interdependientes se actualizan al mismo tiempo, resolviendo así también el principal problema de incompatibilidad numérica.
- Muchas distribuciones de Linux actuales también han implementado sistemas de administración de paquetes basados en repositorios para intentar resolver el problema de la dependencia. Estos sistemas son una capa sobre RPM , dpkg u otros sistemas de empaquetado que están diseñados para resolver dependencias automáticamente mediante la búsqueda en repositorios de software predefinidos . Ejemplos de estos sistemas incluyen Apt , Yum , Urpmi , ZYpp , Portage , Pacman y otros. Normalmente, los repositorios de software son sitios FTP o sitios web, directorios en la computadora local o compartidos a través de una red o, con mucha menos frecuencia, directorios en medios extraíbles como CD o DVD. Esto elimina el infierno de la dependencia para el software empaquetado en esos repositorios, que generalmente son mantenidos por el proveedor de distribución de Linux y duplicados en todo el mundo. Aunque estos repositorios suelen ser enormes, no es posible tener todos los componentes de software en ellos, por lo que aún puede ocurrir un infierno de dependencia. En todos los casos, los encargados del mantenimiento del repositorio todavía se enfrentan al infierno de la dependencia. [4]
- Opciones de instalador
- Debido a que diferentes piezas de software tienen dependencias diferentes, es posible entrar en un círculo vicioso de requisitos de dependencia , o en un árbol de requisitos en constante expansión , ya que cada nuevo paquete exige que se instalen varios más. Los sistemas como la herramienta de empaquetado avanzado de Debian pueden resolver esto presentando al usuario una gama de soluciones y permitiendo que el usuario acepte o rechace las soluciones, según lo desee.
- Fácil adaptabilidad en la programación
- Si el software de la aplicación está diseñado de tal manera que sus programadores pueden adaptar fácilmente la capa de interfaz que se ocupa del sistema operativo, el administrador de ventanas o el entorno de escritorio a estándares nuevos o cambiantes, entonces los programadores solo tendrían que monitorear las notificaciones de los creadores del entorno. o diseñadores de bibliotecas de componentes y ajustan rápidamente su software con actualizaciones para sus usuarios, todo con un esfuerzo mínimo y sin un rediseño costoso y que requiere mucho tiempo. Este método alentaría a los programadores a presionar a aquellos de quienes dependen para que mantengan un proceso de notificación razonable que no sea oneroso para nadie involucrado.
- Requisito estricto de compatibilidad en el desarrollo y mantenimiento de código
- Si las aplicaciones y bibliotecas se desarrollan y mantienen teniendo en cuenta la compatibilidad con versiones anteriores garantizada, cualquier aplicación o biblioteca se puede reemplazar con una versión más nueva en cualquier momento sin romper nada. Si bien esto no alivia la multitud de dependencias, facilita mucho el trabajo de los administradores o instaladores de paquetes.
- Dispositivos de software
- Otro enfoque para evitar problemas de dependencia es implementar aplicaciones como un dispositivo de software . Un dispositivo de software encapsula las dependencias en una unidad autónoma preintegrada de modo que los usuarios ya no tengan que preocuparse por resolver las dependencias del software. En cambio, la carga se traslada a los desarrolladores del dispositivo de software.
- Aplicaciones portátiles
- Una aplicación (o versión de una aplicación convencional existente) que es completamente autónoma y no requiere nada que esté ya instalado. Está codificado para tener todos los componentes necesarios incluidos, o está diseñado para mantener todos los archivos necesarios dentro de su propio directorio y no creará un problema de dependencia. A menudo, estos pueden funcionar independientemente del sistema al que están conectados. Las aplicaciones en RISC OS y ROX Desktop para Linux usan directorios de aplicaciones , que funcionan de la misma manera: los programas y sus dependencias están autocontenidos en sus propios directorios (carpetas). [10]
- Este método de distribución también ha demostrado ser útil al portar aplicaciones diseñadas para plataformas similares a Unix a Windows, siendo el inconveniente más notable la instalación de múltiples instalaciones de las mismas bibliotecas compartidas . Por ejemplo, los instaladores de Windows para gedit , GIMP y XChat incluyen copias idénticas del kit de herramientas GTK , que estos programas utilizan para renderizar widgets. Por otro lado, si cada aplicación requiere diferentes versiones de GTK, entonces este es el comportamiento correcto y evita con éxito el infierno de la dependencia.
Específico de la plataforma
En plataformas informáticas específicas , el "infierno de la dependencia" a menudo se conoce con un nombre específico local, generalmente el nombre de los componentes.
- DLL Hell : una forma de infierno de dependencia que ocurre en Microsoft Windows .
- Conflicto de extensión : una forma de infierno de dependencia que ocurre en el Mac OS clásico .
- Infierno JAR : una forma de infierno de dependencia que ocurre en Java Runtime Environment antes de que las herramientas de compilación como Apache Maven resolvieran este problema en 2004. [ cita requerida ]
- Infierno de RPM: una forma de infierno de dependencias que ocurre en la distribución Red Hat de Linux y otras distribuciones que usan RPM como administrador de paquetes. [11]
Ver también
- Gestión de la configuración : técnicas y herramientas para gestionar versiones de software
- Acoplamiento : formas de dependencia entre artefactos de software
- Eliminación dinámica de códigos muertos
- Gerente de empaquetación
- PBI
- Dispositivo de software
- Administrador de paquetes Nix
- Almohadilla izquierda
Referencias
- ^ Michael Jang (2006). Molestias de Linux para geeks . O'Reilly Media. pag. 325 . ISBN 9780596552244. Consultado el 16 de febrero de 2012 .
- ^ Donald, James (25 de enero de 2003). "Portabilidad mejorada de bibliotecas compartidas" (PDF) . Universidad de Princeton. Archivado desde el original (PDF) el 26 de septiembre de 2007 . Consultado el 9 de abril de 2010 . Cite journal requiere
|journal=
( ayuda ) - ^ Stevens, Al (1 de mayo de 2001). "Es un buen trabajo cuando puede encontrarlo; el carrusel de dependencia" . J-DDJ . www.drdobbs.com/blog. 26 (5): 121-124. ISSN 1044-789X . Archivado desde el original el 11 de agosto de 2011 . Consultado el 10 de abril de 2010 .
- ^ a b Pjotr Prins; Jeeva Suresh y Eelco Dolstra (22 de diciembre de 2008). "Nix corrige el infierno de la dependencia en todas las distribuciones de Linux" . linux.com. Archivado desde el original el 8 de julio de 2015 . Consultado el 22 de mayo de 2013 .
Todos los administradores de paquetes populares, incluidos APT, RPM y FreeBSD Ports Collection, sufren el problema de las actualizaciones destructivas. Cuando realiza una actualización, ya sea para una sola aplicación o para todo su sistema operativo, el administrador de paquetes sobrescribirá los archivos que se encuentran actualmente en su sistema con versiones más recientes. Mientras los paquetes sean siempre perfectamente compatibles con versiones anteriores, esto no es un problema, pero en el mundo real, los paquetes son cualquier cosa menos perfectamente compatibles con versiones anteriores. Suponga que actualiza Firefox y su administrador de paquetes decide que también necesita una versión más nueva de GTK. Si el nuevo GTK no es del todo compatible con versiones anteriores, es posible que otras aplicaciones de su sistema se interrumpan repentinamente. En el mundo de Windows, un problema similar se conoce como el infierno de las DLL, pero el infierno de la dependencia es un problema igual en el mundo de Unix, si no uno mayor, porque los programas de Unix tienden a tener muchas dependencias externas.
- ^ "Infierno de la dependencia de Yum" . Archivado desde el original el 19 de diciembre de 2016 . Consultado el 28 de diciembre de 2015 .
- ^ "Sitio web del proyecto: semver.org" .
- ^ Anderson, Rick (11 de enero de 2000). "El fin del infierno DLL" . microsoft.com. Archivado desde el original el 5 de junio de 2001 . Consultado el 7 de julio de 2010 .
- ^ pbiDIR
- ^ Ranurado en gentoo.org
- ^ "Directorios de aplicaciones" . Consultado el 7 de septiembre de 2013 .
- ^ Weinstein, Paul (11 de septiembre de 2003). "¿Linux es molesto?" . linuxdevcenter.com . Consultado el 10 de abril de 2010 .
enlaces externos
- Independencia del contexto
- Caminante de la dependencia
- Dependencia implícita
- MacDependency