В статье я расскажу, как подключить библиотеку, которой в maven по умолчанию нет, и как подключить другую библиотеку, исходники которой давным-давно потеряны. Также я опишу, как сделать maven проект, который генерирует артефакт, по совместительству являющийся библиотекой, и как подключить эту библиотеку к другому своему же maven проекту. Эта статья для тех, кто только начинает осваивать java.  В моей предыдущей статье было сказано, что maven сам скачает все указанные в pom.xml зависимости. А вот что будет, если он какую-нибудь зависимость не найдёт? В таком случае maven скажет, что зависимость не обнаружена и прервёт процесс сборки с ошибкой. Что делать в этом случае? Этот вопрос, на самом деле, распадается на несколько вопросов, каждый из которых надо решать индивидуально. Выбор решения же определяется тем, где эта зависимость есть. Зависимость может быть в интернете в каком-то месте, о существовании которого maven не знает. Ещё она может быть в виде jar файла у вас на руках и, наконец, в виде исходного кода, оформленного как maven проект. Об этих трёх случаях мы и поговорим. Но сначала надо коротко прояснить один вопрос. На просторах интернета есть сервер, на котором выложены java библиотеки. Этот сервер называется репозиторием, а по-русски — хранилищем. Это не какой-то абстрактный, а вполне конкретный ресурс, адрес которого зашит в дефолтные настройки maven. Поэтому он называется репозиторием по умолчанию. Именно там maven будет искать зависимости из pom.xml. Первая и, возможно, самая частая проблема возникает, если библиотеки в этом умолчальном репозитории нет или в случае, если этот репозиторий с машины, на которой осуществляется сборка, недоступен, например, по соображениям безопасности. Причины проблемы немного разные, но решение одинаковое — нужно указать репозиторий, в котором зависимости есть. Это либо какой-то другой адрес в Интернете, либо адрес репозитория, поднятого админами в локальной сети. Для того, чтобы указать maven, что зависимости надо искать не только в умолчальном репозитории, существует штатный механизм. Вот так можно прописать ещё один адрес для поиска. Далее мы подключили репозиторий проекта Spring, в котором можно найти последние версии этого семейства бибилиотек. Вот как это выглядит внутри pom.xml Теперь maven, когда не найдёт зависимости в репозитории по умолчанию, или обнаружит, что оный недоступен — не запаникует, а поищет библиотеку в ещё одном репозитории и, если всё идёт по плану, найдёт её там. Тут следует уточнить, что если ваша программа может быть использована в качестве зависимости, например, если сама является библиотекой, то класть тег репозиторий в pom.xml — не лучшая идея. Объяснение того, почему это так, выходит за рамки статьи, но с ним можно ознакомиться тут. Но бывает так, что библиотеки в репозиториях нет. Например, если это драйвера для MSSQL, или если это проприетарная библиотека, которую вы недавно приобрели за большие деньги. Подключить такую библиотеку можно несколькими способами. Например, если у вас есть свой репозиторий в локальной сети, то можно (а иногда даже нужно), положить библиотеку туда, и тем самым свести задачу к предыдущей. Но, если это возможно, такую библиотеку лучше положить в проект и хранить прямо в системе контроля версий. Тогда библиотека будет доступна программе всегда и на любой машине, а шаг по копированию этой библиотеки в репозиторий можно не включать в мануал. Для обработки таких кейсов у maven тоже есть штатный механизм. Только что мы выяснили, как указать maven удалённый репозиторий, отличный от умолчального. Так вот, не обязательно использовать удалённое хранилище. Можно сделать репозиторий в локальной файловой системе, положить туда библиотеку и проинструктировать maven искать зависимости ещё и там. Для этого, как сказано выше, у maven есть штатное средство. Допустим у нас есть библиотека, которая находится в jar файле под названием hello-world-library-1.0-SNAPSHOT.jar. О библиотеке нам известно, что в ней есть один класс HelloWorld, который включает один статический метод say, печатающий в консоли, как несложно догадаться, Hello World. Мы хотим в директории проекта создать директорию lib, в которой будет находиться наш дополнительный репозиторий, и поместить туда библиотеку. Для этого достаточно в директории проекта выполнить следующую команду. Если вы используете операционную систему Windows, нужно заменить \ на ^, то есть написать Или можно просто убрать \ и написать команду в одну строчку. Обратите внимание, как и для любого другого артефакта, для библиотеки нам нужно придумать groupId, artifactId и version. Мы потом укажем их в pom.xml, когда будем подключать зависимость. Внутри директории, которую создаст команда, находится полноценный репозиторий, для использования которого достаточно указать maven, где он находится. Все сведения о том, какие библиотеки можно там найти, содержатся непосредственно в структуре директорий свежесозданного репозитория. Для последующего использования репозитория, например, на других машинах, команду deploy-file выполнять не надо. Дать проекту знать, что репозиторий существует, и показать, где он находится, можно уже описанным способом, правда, с поправкой на то, что репозиторий локальный. Обратите внимание на пятую строку Тут сказано, что искать репозиторий надо в директории проекта, на которую указывает встроенная переменная maven project.basedir. Класс, использующий библиотеку, будет предельно прост, но для порядка приведём его код. Осталось добавить в pom.xml зависимость и можно собирать проект. Проверим: Работает! Директорию lib надо закомитить и библиотека будет доступна проекту вообще всегда. Однако следует помнить об одном правиле. Нужно обязательно обновлять номер версии библиотеки в локальном репозитории при каждом изменении jar файла Maven воспринимает репозитории как внешние, поэтому, если не изменить номер версии, то maven будет использовать не версию библиотеки из директории lib, а ту, что он закешировал на локальной машине. В данном конкретном случае это не должно сыграть роли из-за суффикса SNAPSHOT, но об этом нужно знать. Есть ещё один распространённый сценарий. У вас есть своя библиотека, которую вы сами собираете с помощью maven и потом подключаете к другому maven проекту. Для того, чтобы сделать библиотеку, достаточно написать класс с модификатором public. И потом можно будет использовать этот класс в коде, к которому подключена библиотека. Вот такой, например, класс. Теперь нужно сделать maven проект, который будет собирать библиотеку, содержащую этот класс. Как мы помним, с точки зрения maven, библиотека — это просто артефакт, поэтому помник будет выглядеть тривиально. Итак, у нас есть класс со статическим методом, у нас есть описание артефакта для maven. Осталось только собрать этот код, чтобы получилась библиотека, то есть jar файл. Просто напишем в консоли: После этого в директории target появится файл с названием \<artifactId>-\<version>.jar, в нашем конткретном случае — hello-world-library-1.0-SNAPSHOT.jar, который и есть ваша библиотека. Для того, чтобы библиотеку потом можно было подключать к другому проекту, нужно вместо package написать install. Это нужно будет делать после каждого изменения в коде библиотеки, и на каждом компьютере, на котором мы захотим эту библиотеку использовать. Теперь можно сделать новый проект, который будет использовать библиотеку. Внутри проекта будет один класс, который использует статический метод из библиотеки, чтобы сказать Hello world. Мы этот класс уже видели. Проверим ещё раз: Работает не хуже предыдущего варианта! Вопрос, казалось бы, глупый, но на всякий случай проведём эксперимент. Сделаем библиотеку с непустыми зависимостями. и напишем для неё код Теперь соберём её Перейдём в директорию с нашим проектом, который эту библиотеку использует и попробуем его собрать и запустить. И работает! Строго говоря знать, как процесс устроен внутри, не обязательно, но всё равно очень полезно. Команда mvn install соберёт библиотеку, а потом положит её в локальный репозиторий по умолчанию. То есть в то же самое место, где лежат все библиотеки, которые вы когда-либо подключали к maven проектам, за исключением, разумеется, тех, которые находятся в локальных репозиториях, сделанных лично вами. Потом, при сборке проекта, использующего эту библиотеку, maven поищет её в локальном хранилище, найдёт и подключит. UPD: В комментариях sshikov, igor_suhorukov, jbaruch и другие высказали мнение, что библиотеки нельзя хранить вместе с исходниками, потому что для этого есть другие, предназначенные специально для этого инструменты, такие как Nexus и Artifactory. Тут я совершенно согласен. Когда речь идёт о крупных проектах и корпоративной разработке, быть по-другому просто не может. Но, с моей точки зрения, есть случаи, когда удобнее сделать иначе. Я имею в виду маленькие проекты, созданные в процессе обучения, потому что именно с такими вещами обычно имеют дело новички, и случаи, когда доступа к инфраструктуре нет, а добавить библиотеку в сборку нужно в течение 10 минут. Нужно было с самого начала уточнить, что речь в статье именно о таких кейсах. Да, хранить библиотеки в системе контроля версий — хак. Но, как и все хаки, это такая штука, которой в некоторых случаях можно пользоваться и о возможности осуществления которой неплохо бы знать. Причины, по которым техника, предложенная в статье, не подходит для корпоративной разработки, хорошо раскрыты в комментариях. Также советую обратить внимание на статью от разработчиков Nexus, спасибо jbaruch за ссылку. Статья интересная, если не найду существующего перевода на Хабре, планирую перевести ее и сделать отдельным постом. Software developer