Как с помощью maven подключить библиотеку к проекту

  • Tutorial

Спросите кого-нибудь, для чего вообще нужен Maven — 90 процентов поголовья программистов ответит, что именно для этого и будут во многом правы.


Если в случае с, например, C++ подключение библиотеки к своему проекту — это серьёзный шаг, который гарантированно усложнит сборку до такой степени, что придётся включить инструкции по подключению данной конкретной библиотеки в readme, то в случае с Java это делается легко и непринуждённо — не в последнюю очедь благодаря Maven.


Хочу отметить, что статья предназначена для тех, кто начал изучать java относительно недавно и хотя уже значет из предыдущей статьи, что такое maven — о том, что такое библиотеки, знает не очень хорошо, а как их подключать не знает вообще.


Начнём издалека.


Как добавить в проект новый класс


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


Свеженаписанный класс должен лежать там же, где и все остальные классы иначе компилятор его не увидит. Теперь, для того, чтобы его использовать, достаточно добавить в использующий его класс соответствующую директиву import.


Предлагаю присутствущим потратить минуту-другую на выражение благодарности капитану Очевидность, а после продолжить чтение.


Как добавить в проект класс, написанный кем-то другим


Ответ, вообще говоря, очевиден — надо скопировать этот класс в свой код.


Кроме того, что немножко менее очевидно, нужно скопировать в свой проект все классы, которые используются классом, ради которого всё затевалось.


Классы, используемые каким-то другим классом, кстати, принято называть зависимостями (dependencies), этого класса.


У такого подхода есть очевидный минус. Для каждого класса надо выискивать зависимости, а потом руками копировать их к себе. Если позже во всей этой куче кода найдётся какой-нибудь баг, то после появления фикса придётся повторить процесс заново.


Как добавить в проект класс, написанный кем-то другим, не копируя его в свой код


Во всех более-менее современных языках программирования эта проблема уже решена.


Всегда можно сказать компилятору, что классы нужно брать не только из директории с проектом, но и из других, указанных программистом директорий. В Java это делается с помощью параметра classpath.


Если вы работаете с Java то понимать, что такое classpath — строго обязательно, но конкретно для того, чтобы добавить к проекту библиотеку с помощью maven, этого знать не нужно. В контексте нашей темы можно считать classpath сущностью, в которой перечислены все места, где компилятор будет искать классы, необходимые приложению. Если какого-нибудь из этих классов нет ни в одном из этих мест, то программа работать не будет.


Теперь для того, чтобы использовать чужой класс, достаточно скачать код с этим классом, и добавить в classpath директорию, в которую скачан этот код.


По сравнению с предыдущим способом это заметный прогресс. Теперь нет никакой необходимости вручную отслеживать все зависимости того единственного класса, который нужен для работы вашего приложения. Для добавки багфиксов и всего такого достаточно просто скачать новую версию кода.


Вот собственно мы и подошли к ответу на вопрос, что такое библиотека.


Что такое библиотека


Библиотекой принято называть тот самый код, корневую директорию которого нужно добавить в classpath. То есть совокупность нужного нам класса и его зависимостей, а также классов, которые не являются зависимостями нужного нам класса, но содержатся в коде.


В случае с Java, код, который мы добавляем в classpath, можно скомпилировать и добавить в classpath уже директорию со скомпилированным кодом.


Ещё можно заархивировать скомпилированный код в формате zip, поменять расширение файла с архивом на jar и добавить в classpath файл уже этот файл. В контексте разработки на Java, jar файл тоже называется библиотекой.


jar файлы не решают ни одной из изложенных выше проблем, но их использование существенно облегчает передачу библиотек между программистами.


Но, есть одна существенная проблема, которую jar файлы тоже никак решить не помогают.


Классы, которые использует библиотека, могут содержаться не в ней, а в какой-нибудь другой библиотеке, которая по аналогии с предыдущим случаем, тоже называется зависимостью.


Как добавить в проект библиотеку, использующую другую библиотеку


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


Может случиться так, что при обновлении какой-нибудь зависимости библиотека, класс из которой мы собираемся использовать в своём проекте, перестанет работать корректно — нам придётся внимательно следить за тем, чтобы такого не случилось и ответственно подходить к каждому обновлению, а лучше, обновлять библиотеки только если без обновления нельзя обойтись вообще.


Как убедиться, что обновление зависимости ничего не сломает


Сторого говоря — никак.


Необходимо, конечно, обновить зависимость и запустить юнит тесты. Если они не проходят, то определённо можно сказать, что что-то сломалось.


Если нет, то это является слабым свидетельством, что поломка отсутствует, но ничего не доказывает.


Но положим, что юнит тестам можно доверять. В этом случае при добавлении библиотеки придётся вручную проверить её совместимость с зависимостями запустив прилагаемые юнит тесты и делать это при каждом обновлении. Это, поверьте, мне тяжело.


Для того, чтобы избежать этой нудной и сложной работы, между программистами всего мира существует негласная договорённость. Библиотеки принято версионировать.


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


Если другие программисты находят в библиотеке ошибку, то создатель библиотеки не просто молча её исправляет, а после исправления изменяет идентификатор библиотеки и теперь миру доступно две библиотеки с одинаковым названием, но разными идентификаторами.


Этот идентификатор принято называть версией библиотеки.


Версию библиотеки программист обновляет не только при исправлении ошибок, но и вообще при любом изменении.


Программисты, использующие эту стороннюю библиотеку при создании своих библиотек, или просто программ, указывают в документации не только название, но и версию, с которой их библиотека гарантировано работает корректно.


То есть работу по проверке того, какие версии зависимостей нужно использовать, берёт на себя один человек, остальные просто пользуются плодами его трудов.


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


При обновлении какой-нибудь из библиотек процесс надо повторить. Это, поверьте мне, мучительно.


Как получить список всех библиотек, нужных проекту и добавить их в проект автоматически


И тут на помощь приходит Maven. Он формализует негласную договорённость между программистами и делает её гласной.


Если для каждой библиотеки есть список зависимостей, с чётко определёнными версиями, то составить список всех нужных проекту библиотек сложности не составляет.


Скопировать эти библиотеки на машину программиста и добавить их в classpath — тоже не высшая математика. Нужно только знать, откуда качать библиотеки и описания их зависимостей, а также в каком формате эти зависимости описаны.


Эти вопросы в Maven успешно решены.


Как подключить библиотеку к Maven проекту


Тут всё в общем-то банально. Библиотека в понимании Maven, является артефактом, нужным для сборки программы.


У каждого артефакта, как мы помним, есть groupId, artifactId и version. Нужно только указать maven, что данный артефакт является зависимостью проекта.


Список зависимостей должен быть обернут тегом dependencies. Каждая отдельная зависимость должна быть обёрнута тегом dependency. Внутри тега dependency в тегах groupId, artifactId и version нужно указать значения соответствующих параметров.


Тут наверное надо дать пример pom.xml с добавленной библиотекой. Вот пример:


<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com</groupId>
    <artifactId>hello-world</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
    </dependencies>
</project>

Тут мы подключили к проекту библиотеку, с кучей статических методов, выполняющих стандартные задачи. Одной из таких задач является расширение массива и добавление в него дополнительного элемента.


Вот например так:


package com;

import static org.apache.commons.lang3.ArrayUtils.*;

public class Application {
    public static void main(String[] argv) {
        String[] phrase = {"Hello"};
        phrase = add(phrase, " ");
        phrase = add(phrase, "world");
        for (String word : phrase) {
            System.out.print(word);
        }
        System.out.println();
    }
}

Чтобы скомпилировать код надо написать


mvn compile

Чтобы запустить


mvn exec:java -Dexec.mainClass="com.Application"

Этот код выведет Hello world, но, в отличии от предыдущей статьи, уже новым прогрессивным методом. С помощью библиотеки.


Вот собственно и всё.


Зависимости подключённого к проекту артефакта maven найдёт сам, сам составит список всех библиотек, необходимых проекту, включая зависимости зависимостей и зависимости зависимостей зависимостей, сам скачает их на машину, на которой происходит сборка и сам добавит их в classpath.


Это, поверьте мне, прекрасно.


Итого


  1. Классы, используемые другим классом, называются зависимостями этого класса
  2. Библиотекой принято называть совокупность классов, предназначенных для решения определённой задачи, и их зависимостей.
  3. Зависимости классов из библиотеки могут находиться в других библиотеках и тогда эти библиотеки называются её зависимостями.
  4. В Java скомпилированные классы из библиотеки можно упаковывать в zip архив с расширением jar. jar файлы тоже называются библиотекой.
  5. Библиотеки, используемые проектом, называются зависимостями проекта. Для подключения зависимости в maven используется тег dependency. Теги dependency должны находиться внутри тега dependencies.
  6. В Maven библиотека является артефактом, а значит имеет groupId, artifactId и version.
  7. Чтобы подключить библиотеку к проекту с помощью maven достаточно указать её groupId, artifactId и version.
Поделиться публикацией

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

    +3
    Открывая статью я, конечно, предполагал прочитав заголовок, что тут будет информация для новичков, но увидеть 98% воды в статье и лишь пару строчек, собственно, о подключении библиотеки я совсем не ожидал.
      –2

      Вы, наверное, уже знаете что такое библиотеки, зачем их версионируют и в каком виде они физически представлены в java :)

        +1
        Если бы статья была о чём-то новом, то я б ни слова не сказал.

        Скажем, о том как работать с Maven в Java 9 в свете появления Jigsaw.
          0

          Целевая аудитория статьи — те, для кого и мавен и библиотеки — это что-то новое. Вспомните те времена, когда вы не знали что это такое :)

            +4
            О том, как работать с java9 через maven еще даже контрибьюторы maven не знают :(
              0

              Вероятно по аналогии с felix и tycho?

        0
        Отлично разжёвано для «самых маленьких». А дальше хотелось бы в конце статьи ссылку на статью с более глубоким закапыванием в maven.
          0

          Я собираюсь писать статьи дальше. Сначала по основным понятиям, потом глубже. Это вот уже вторая, первая рассказывала только про то, что такое артефакт :). Там в комментариях, кстати, есть ссылки на подробное руководство. Раз и два.

          0
          Спасибо за статью, всё очень понятно. Главное не забрасывайте, пишите продолжение!
            0

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

            0
            Прочитав статью мне не стало понятно что такое версионность библиотек
              0

              Не стало понятно, зачем библиотекам версии?

              0

              Спасибо за статью. Мне, как новичку, было интересно.

                –1

                Всегда пожалуйста. Ваше одобрение значит для меня особенно много, потому что я старался чтобы было понятно именно людям, которые в области недавно.

                0
                Можно было добавить пару слов о том, что делать если библиотека, которую мы хотим подключить у нас есть, а вот в репозитории maven — ее нет.
                  –1

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

                  0
                  Спасибо за Ваши статьи! Для новичка, по-моему, очень даже.
                    +1
                    Зачем тут постить статьи которых уже множество накопилось раз в год появится статья для новичков.
                      –2

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

                      0
                      Спасибо за статью, реально очень помогло разобраться

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое