27 September 2016

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

ProgrammingJavaBuild automation
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.
Tags:javamavenсистемы сборкибиблиотекиуправление зависимостямиdependency
Hubs: Programming Java Build automation
+7
33.5k 74
Comments 20