Término coloquial para el software que requiere muchas dependencias conflictivas.
El infierno de dependencia es un término coloquial que se refiere a la frustración de algunos usuarios de software que han instalado paquetes de software que tienen dependencias de versiones específicas de otros paquetes de software. [1]
El problema de dependencia surge cuando varios paquetes tienen dependencias de los mismos paquetes o bibliotecas compartidas , pero dependen de versiones diferentes e incompatibles de los paquetes compartidos. Si el paquete o la biblioteca compartida solo se pueden 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 trasladar 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 prolongadas, 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 misma se pueda portar fácilmente). También puede ser difícil localizar todas las dependencias, lo que se puede solucionar con 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 se instale esa plataforma, pero otras aplicaciones no la requieren. Este es un problema particular si una aplicación utiliza una pequeña parte de una gran biblioteca (lo que se puede resolver mediante la refactorización del código ), o si una aplicación simple depende de muchas bibliotecas. [2]
- Largas cadenas de dependencias
- Si
app
depende de liba
, que depende de libb
, ..., que depende de libz
. Esto es distinto de "muchas dependencias" si las dependencias deben resolverse manualmente, p. ej., al intentar instalar app
, se le solicita al usuario que instale liba
primero y al intentar instalar liba
, se le solicita al usuario que instale libb
, y así sucesivamente. A veces, sin embargo, durante esta larga cadena de dependencias, surgen conflictos donde se requieren dos versiones diferentes del mismo paquete [3] (ver 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 conflictivas
- Resolver las dependencias de un software puede romper la compatibilidad de otro de una manera similar a la del juego whack-a-mole . Si
app1
depende de libfoo 1.2
, y app2
depende de , y no se pueden instalar simultáneamente libfoo 1.3
versiones diferentes de , entonces y no se pueden usar simultáneamente (o instalar, si el instalador verifica las dependencias). Cuando es posible, esto se soluciona permitiendo instalaciones simultáneas 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 (lo cual no se recomienda) [ cita requerida ] es que la larga cadena de dependencias resultante puede llevar a una versión conflictiva de la biblioteca estándar de C (por ejemplo, la biblioteca C de GNU ), de la que dependen miles de paquetes. Si esto sucede, se le solicitará al usuario que desinstale todos esos paquetes.libfoo
app1
app2
- Dependencias circulares
- Si
application A
depende de y no puede ejecutarse sin una versión específica de application B
, pero application B
, a su vez, depende de y no puede ejecutarse sin una versión específica de application A
, entonces actualizar cualquier aplicación romperá otra. Este esquema puede ser más profundo en la ramificación. Su impacto puede ser bastante fuerte si afecta a los sistemas centrales o al software de actualización en sí: un administrador de paquetes (A), que requiere una biblioteca de tiempo de ejecución específica (B) para funcionar, puede romperse a sí mismo (A) en medio del proceso al actualizar esta biblioteca (B) a la siguiente versión. Debido a una versión incorrecta de la biblioteca (B), el administrador de paquetes (A) ahora está roto, por lo que no es posible revertir 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 se produzca un infierno de dependencias al instalar un paquete preparado a través de un gestor de paquetes (p. ej., APT ), pero esto es poco probable ya que los principales gestores de paquetes han madurado y los repositorios oficiales están bien mantenidos. Este es el caso de las versiones actuales de Debian y los principales derivados como Ubuntu . Sin embargo, el infierno de dependencias puede resultar de instalar un paquete directamente a través de un instalador de paquetes (p. ej. , RPM o dpkg ).
- Dependencia del diamante
- 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, lo que causa un infierno de dependencias en distribuciones de Linux como CentOS y Red Hat Enterprise Linux .
Soluciones
- Eliminando dependencias
- Muchas bibliotecas de software están escritas de forma generosa, en un intento de satisfacer las necesidades de la mayoría de los usuarios, pero a veces solo se requiere una pequeña parte de las funciones en el código anfitrión. Al examinar el código fuente, la funcionalidad se puede reescribir de una manera mucho más compacta (con respecto a la licencia). En general, esto puede reducir significativamente el código de la aplicación y, posteriormente, los costos de mantenimiento, y los programadores pueden mejorar sus habilidades de escritura de software.
- 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 utiliza 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 usaron esa versión ya no serán compatibles. La versión secundaria puede cambiar incluso con una revisión simple que no impida 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 particular y cualquier versión secundaria (mayor o igual a una versión secundaria particular). Como tal, continuarán funcionando y las dependencias se resolverán correctamente, incluso si la versión secundaria cambia. El control de versiones semántico (también conocido como "SemVer" [6] ) es un ejemplo de un esfuerzo por generar una especificación técnica que emplea números con formato específico 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 su lugar, se animaba 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 la ruta de búsqueda de Windows, que siempre prioriza la ruta local antes que el directorio del sistema con las bibliotecas de todo el sistema. Esto permite un seguimiento fácil y eficaz de las versiones de las bibliotecas por parte de aplicaciones específicas, evitando así el infierno de dependencias. [7]
- PC-BSD, hasta la versión 8.2 inclusive, predecesor de TrueOS (un sistema operativo basado en FreeBSD ), coloca los paquetes y dependencias en directorios independientes en /Programs , lo que evita que se rompan si se actualizan o modifican las bibliotecas del sistema. Utiliza su propio "PBI" (Push Button Installer) para la gestión de paquetes. [8]
- Instalación en paralelo de múltiples versiones
- La solución de numeración de versiones se puede mejorar elevando la numeración de versiones a una característica compatible con el sistema operativo. Esto permite que una aplicación solicite un módulo/biblioteca mediante un nombre único y restricciones de número de versión, transfiriendo efectivamente la responsabilidad de gestionar las versiones de la biblioteca/módulo desde las aplicaciones al sistema operativo. Un módulo compartido se puede colocar entonces en un repositorio central sin el riesgo de dañar las aplicaciones que dependen de versiones anteriores o posteriores del módulo. Cada versión tiene su propia entrada, junto con otras versiones del mismo módulo.
- Esta solución se utiliza en los sistemas operativos Microsoft Windows desde Windows Vista, donde la caché de ensamblajes global 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 problema de incompatibilidad de números importantes.
- Muchas distribuciones Linux actuales también han implementado sistemas de administración de paquetes basados en repositorios para intentar resolver el problema de dependencias. Estos sistemas son una capa sobre RPM , dpkg u otros sistemas de empaquetado que están diseñados para resolver automáticamente las dependencias mediante la búsqueda en repositorios de software predefinidos . Ejemplos de estos sistemas incluyen Apt , Yum , Urpmi , ZYpp , Portage , Pacman y otros. Por lo general, los repositorios de software son sitios FTP o sitios web, directorios en la computadora local o compartidos a través de una red o, mucho menos comúnmente, directorios en medios extraíbles como CD o DVD. Esto elimina el infierno de dependencias para el software empaquetado en esos repositorios, que generalmente son mantenidos por el proveedor de la distribución Linux y reflejados en todo el mundo. Aunque estos repositorios suelen ser enormes, no es posible tener cada pieza de software en ellos, por lo que el infierno de dependencias aún puede ocurrir. En todos los casos, el infierno de dependencias aún lo enfrentan los mantenedores de los repositorios. [4]
- Opciones de instalación
- Debido a que los distintos programas tienen distintas dependencias, es posible entrar en un círculo vicioso de requisitos de dependencia, o un árbol de requisitos en constante expansión , ya que cada nuevo paquete exige la instalación de varios más. Los sistemas como la herramienta de empaquetado avanzado de Debian pueden resolver esto presentando al usuario una gama de soluciones y permitiéndole aceptarlas o rechazarlas, según lo desee.
- Fácil adaptabilidad en la programación
- Si el software de aplicación está diseñado de tal manera que sus programadores puedan 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 los diseñadores de la biblioteca de componentes y ajustar rápidamente su software con actualizaciones para sus usuarios, todo con un mínimo esfuerzo y sin rediseños costosos y que consumen 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 ninguno de los involucrados.
- Requisito estricto de compatibilidad en el desarrollo y mantenimiento del código
- Si las aplicaciones y bibliotecas se desarrollan y mantienen teniendo en mente la compatibilidad con versiones anteriores, cualquier aplicación o biblioteca se puede reemplazar por una versión más nueva en cualquier momento sin que se produzcan problemas. Si bien esto no alivia la multitud de dependencias, sí facilita mucho el trabajo de los administradores de paquetes o los instaladores.
- 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 de software. En cambio, la carga se traslada a los desarrolladores del dispositivo de software. Los contenedores y sus imágenes (como los que proporcionan Docker y Docker Hub) pueden considerarse una implementación de dispositivos 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 que nada esté instalado previamente. Está codificada para tener todos los componentes necesarios incluidos, o está diseñada para mantener todos los archivos necesarios dentro de su propio directorio, y no creará un problema de dependencia. Estas suelen poder ejecutarse independientemente del sistema al que están conectadas. Las aplicaciones en RISC OS y ROX Desktop para Linux utilizan directorios de aplicaciones , que funcionan de manera muy similar: los programas y sus dependencias están contenidos en sus propios directorios (carpetas). [10]
- Este método de distribución también ha demostrado ser útil al trasladar aplicaciones diseñadas para plataformas tipo Unix a Windows, siendo el inconveniente más notable la necesidad de realizar varias instalaciones de las mismas bibliotecas compartidas . Por ejemplo, los instaladores de Windows para gedit , GIMP y HexChat incluyen copias idénticas del kit de herramientas GTK , que estos programas utilizan para representar widgets. Por otro lado, si cada aplicación requiere diferentes versiones de GTK, este es el comportamiento correcto y evita con éxito el infierno de las dependencias.
Específico de la plataforma
En plataformas informáticas específicas , el "infierno de la dependencia" a menudo tiene un nombre local específico, generalmente el nombre de los componentes.
Véase también
Referencias
- ^ Michael Jang (2006). Los inconvenientes de Linux para los expertos . O'Reilly Media. p. 325. ISBN 9780596552244. Recuperado el 16 de febrero de 2012 .
- ^ Donald, James (25 de enero de 2003). "Mejora de la portabilidad de las bibliotecas compartidas" (PDF) . Universidad de Princeton. Archivado desde el original (PDF) el 26 de septiembre de 2007. Consultado el 9 de abril de 2010 .
- ^ Stevens, Al (1 de mayo de 2001). "Es un buen trabajo cuando lo puedes encontrar; el carrusel de la dependencia". J-DDJ . 26 (5). www.drdobbs.com/blog: 121–124. ISSN 1044-789X. Archivado desde el original el 11 de agosto de 2011 . Consultado el 10 de abril de 2010 .
- ^ ab Pjotr Prins; Jeeva Suresh & Eelco Dolstra (2008-12-22). "Nix corrige el problema de las dependencias en todas las distribuciones Linux". linux.com. Archivado desde el original el 2015-07-08 . Consultado el 2013-05-22 .
Todos los gestores de paquetes populares, incluidos APT, RPM y la colección de puertos de FreeBSD, sufren el problema de las actualizaciones destructivas. Cuando realiza una actualización, ya sea para una sola aplicación o para todo el sistema operativo, el gestor de paquetes sobrescribirá los archivos que se encuentran actualmente en su sistema con versiones más nuevas. Mientras los paquetes sean siempre perfectamente compatibles con versiones anteriores, esto no es un problema, pero en el mundo real, los paquetes son todo menos perfectamente compatibles con versiones anteriores. Supongamos que actualiza Firefox y su gestor de paquetes decide que también necesita una versión más nueva de GTK. Si la nueva GTK no es completamente compatible con versiones anteriores, es posible que otras aplicaciones de su sistema dejen de funcionar de repente. En el mundo de Windows existe un problema similar conocido como el infierno de las DLL, pero el infierno de las dependencias es un problema igualmente grave en el mundo de Unix, si no mayor, porque los programas de Unix tienden a tener muchas dependencias externas.
- ^ "Yum Dependency Hell". 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 de las DLL". microsoft.com. Archivado desde el original el 5 de junio de 2001. Consultado el 7 de julio de 2010 .
- ^ pbiDIR
- ^ Asignación de espacios en gentoo.org
- ^ "Directorios de aplicaciones" . Consultado el 7 de septiembre de 2013 .
- ^ Weinstein, Paul (11 de septiembre de 2003). "¿Es Linux molesto?". linuxdevcenter.com . Consultado el 10 de abril de 2010 .
Enlaces externos
- Independencia del contexto
- Caminante de dependencia
- Dependencia implícita
- Dependencia de Mac