2

Предположим, что я пишу библиотеку Scala L, которая зависит от некоторой зависимости D и потребляется программой P и другой программой Q. P зависит от версии 3.2 от D напрямую, а Q зависит от версии 3.3 напрямую.Как я могу использовать SBT, чтобы помочь моей библиотеке преодолеть конфликты транзитивной зависимости

Между этими двумя версиями API D's был перетасован таким образом, что для получения той же функции, которую я использую в L, я должен писать различные операторы импорта в L. Аналогично, P полагается на 3.2-специфическое поведение, тогда как Q полагается на поведение 3.3.

Теперь, как правило, произойдет то, что самая последняя версия D будет выбрана при компиляции P и Q, но это приведет к разрыву P, если L зависит от версии 3.3 библиотеки или L для разрыва при компиляции Q, если L зависит от версии 3.2 D. D.

Я бы идеально хотел, чтобы одна и та же версия L использовалась как P, так и Q, поскольку открытый API L не изменяется. Это возможно?

Общий метод, который приходит на ум, является условной компиляцией L на основе разрешения зависимостей. Это кажется недостижимым, хотя в мире JVM, поскольку мы не транзитивно компилируем зависимости проекта и вместо этого полагаемся на предварительно скомпилированные артефакты.

Я могу сделать это прямо сейчас с SBT, если D - сама Scala (т.е. кросс-компиляция с различными версиями Scala и наличие кода конкретной версии в собственных каталогах), но это что-то вроде взлома с точки зрения зависимости поскольку SBT изменяет имена артефактов, чтобы эта кросс-компиляция работала.

ответ

2

Вы можете сказать SBT для обработки зависимостей, как intransitive:

libraryDependencies ++= Seq(
    "org.some.id" % "some-lib" % "1.0.foobar" intransitive() 
) 

хотел бы добавить некоторые Пб к зависимостям, но не будет следовать зависимости от этого Lib. Так что если some-lib имеет зависимость от some-other-lib, что другая библиотека не будет загружена.

Возможно немного конкретнее. Скажем, вам нужны несколько библиотек, которые используют SLF4J в качестве интерфейса регистрации. Возможно, некоторые из библиотек требуют немного другой версии, но без каких-либо различий API. Таким образом, они могут работать с той же версией SLF4J. Затем вы помечали бы все тезисы libraryDependencies как непереходные и одновременно добавляли SLF4J как зависимость от библиотеки верхнего уровня.

libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % 1.7.6, 
"com.typesage.slick" %% "slick" % "2.0.0" intransitive(), 
"com.typesafe.akka" %% "akka-slf4j" % "2.2.0" intransitive() 
) 

Имею ли я смысл?

+0

Это не проблема, с которой я столкнулся. Чтобы взять ваш пример SLF4J, проблема, с которой я сталкиваюсь, сродни тому, что Slick использовал версию 1.7 SLF4J, но также мог использовать версию 1.6 с небольшими изменениями в своем коде. Приложение с использованием Slick должно использовать версию 1.6 и разрывается на 1.7. Могут ли авторы Slick приспособить этот вариант использования, разрешив, чтобы часть кода адаптера, необходимая для размещения 1.6, была скомпилирована, если присутствует 1.6, и скомпилирован другой фрагмент кода, если присутствует 1.7? – badcook

+0

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

Смежные вопросы