Почему соглашение о перекрестном построении добавляет версию scala к artifactId?

#scala #sbt

#maven #sbt

Вопрос:

Основной механизм, используемый для указания, с какой версией Scala была скомпилирована библиотека, заключается в добавлении _<scala-version> к имени библиотеки. Этот довольно простой подход позволяет взаимодействовать с пользователями Maven, Ant и других инструментов сборки. — Документация sbt: соглашения о публикации перекрестной сборки

Хотя это простой подход, совместимость с Maven и другими инструментами сборки оставляет желать лучшего. Поскольку artifactId они разные (например scalatest_2.9.0 , и scalatest_2.10.0 ), Maven рассматривает их как разные артефакты. Таким образом, механизм разрешения зависимостей Maven скомпрометирован, и несколько версий одного и того же артефакта (построенных на основе разных версий scala) могут оказаться в пути к классу.

Почему бы не поместить версию scala в классификатор? Похоже, это один из основных предполагаемых вариантов использования классификатора:

Классификатор позволяет [Maven] различать артефакты, которые были созданы из одного и того же POM, но отличаются по своему содержанию. В качестве мотивации для этого элемента рассмотрим, например, проект, который предлагает артефакт, предназначенный для JRE 1.5, но в то же время также артефакт, который все еще поддерживает JRE 1.4. Первый артефакт может быть оснащен классификатором jdk15, а второй — jdk14, чтобы клиенты могли выбирать, какой из них использовать. — Документация Maven: ссылка на POM

Комментарии:

1. Я помню, как это решение было принято несколько лет назад, и я почти уверен, что использование классификатора обсуждалось и было отклонено, и все согласились, что это не было работоспособным решением. Чего я не могу вспомнить, так это почему!

2. @SethTisue Спасибо за подсказку.

Ответ №1:

Добавление версии к имени — это историческое решение, которое было принято давным-давно, поэтому оно, вероятно, не изменится, поскольку многие библиотеки уже опубликованы с соглашением.

Сказав это, как отметил Сет, несколько лет назад было обсуждение этой темы, когда sbt 0.12 сократил постфикс «_2.10.0» до «_2.10», чтобы воспользоваться двоичной совместимостью библиотеки Scala между второстепенными версиями. Вот отметка из плана [0.12]:

Под перекрестным управлением версиями я подразумеваю практику включения некоторой части версии Scala в идентификатор модуля, чтобы отличать артефакт, созданный путем компиляции одного и того же исходного кода от разных версий Scala. Я не имею в виду возможность сборки с использованием нескольких версий Scala task , которые останутся; Я просто имею в виду соглашение о перекрестном построении.

[снип]

Всегда было сложно кодировать это в негибком pom.xml формат, и я думаю, что, возможно, лучше отказаться от этого для проектов, созданных на основе Scala 2.10 и более поздних версий. Однако, возможно, это лучше, чем любые специальные решения, которые могут занять его место. Я не вижу, чтобы пользователи других инструментов сборки делали это, поэтому я ожидаю, что ничто не заменит его.

Где-то в конце темы Джош предложил:

(1) Классификаторы Scala. Это могут быть пользовательские строки и могут быть указаны с зависимостями. По крайней мере, IIRC это должно работать.

Вот ответ Марка:

Что означает «может быть указано с зависимостями»? Для всех классификаторов существует только один pom, верно? Как вы можете объявлять разные зависимости для каждого классификатора?

Вот еще несколько интересных замечаний о классификаторах от Джеффа Риди

Я тоже подумал, что классификаторы были бы идеальным способом решения этой проблемы, особенно в свете предложения в документах maven о том, что классификаторы java-1.4 и java-1.5 должны использоваться для разделения между банками, подходящими для соответствующей платформы. Фатальным недостатком, по-видимому, является управление транзитивными зависимостями. То есть нет способа выбрать набор переходных зависимостей на основе классификатора, используемого для запроса модуля. Нам нужно было бы иметь возможность сказать, что когда вы используете этот модуль с scala-2.10 классификатором, он привносит свои собственные зависимости с помощью scala-2.10 классификатора, а при использовании с классификатором 2.9 привносит свои собственные deps с scala-2.9 классификатором.

Я думаю, что с версиями jvm это возможно сделать, потому что управление версиями jvm имеет специальную поддержку при активации профиля, которая может управлять зависимостями.