Статьи

Проверка использования сторонних библиотек с помощью Veripacks

Veripacks  уже позволяет указывать и проверять, какие классы  должны быть видны вне пакета (транзитивно-транзитивно), а также  требовать импорта и импорта пакетов  внутри проекта. Это позволяет  исключить некоторые модули сборки , сохраняя при этом их строгую изоляцию (что можно проверить, запустив Veripacks).

Однако что, если мы хотим убедиться, что сторонняя библиотека используется только в определенной части кода? Например, допустим, мы хотим, чтобы классы Hibernate использовались только  dao модулем, и мы хотим, чтобы это проверялось во время сборки. Обычный подход может быть:

  • создать  dao-api модуль сборки
  • создать  dao модуль сборки с dao-api зависимостями и Hibernate
  • реализовать DAO
  • добавить  dao-api модуль в качестве зависимости от всех других модулей, которые используют DAO
  • добавить  dao модуль в качестве зависимости от модуля, который строит дистрибутив (например, war)

Если мы используем Maven, то достаточно много xml для написания и каталогов для создания. Может ли быть проще?

Цель Veripacks 0.4 —  упростить этот конкретный случай, используя аннотации на уровне пакета. При создании экземпляра Veripacks теперь можно указать, какие пакеты следует импортировать. Чтобы использовать классы из таких пакетов, вам просто нужно добавить  @Import аннотацию к пакету — и Veripacks проверит, что все используется только там, где это разрешено:

// test case which runs Veripacks
VeripacksBuilder
   .requireImportOf("org.hibernate")
   .build
   .verify("com.foo.project")
   .throwIfNotOk()
// package in which we want to use Hibernate classes
// package-info.java
@Import("org.hibernate")
package com.foo.project.db.dao;
 
import org.veripacks.Import;

Сам Veripacks использует эти аннотации, чтобы ограничить использование библиотеки чтения байтов ASM; увидеть  VeripacksSelfTest класс и аннотацию на  org.veripacks.reader упаковке.

Улучшенный процесс ограничения использования стороннего библиотечного кода определенной частью нашего кода теперь:

  • создать  пакеты dao.api и  dao.impl(это просто примеры имен; Veripacks не требует использования какого-либо конкретного соглашения об именах)
  • добавить Hibernate в качестве зависимости к проекту
  • реализовать DAO
  • @Importdao.api пакет в пакетах , которые используют объекты DAO

Это намного меньше XML для записи (нет), немного больше  package-info.java для написания, и только три каталога для создания.

Однако обратите внимание, что для пакетов проектов вы все равно должны использовать  @RequiresImport аннотацию. Эти VeripacksBuilder.requireImportOf и  .doNotRequireImportOf методы предназначены только для использования с 3 — пакетов сторонних производителей .

Новая версия также содержит две другие функции. Во-первых, теперь можно пропустить проверку в классе с помощью  @NotVerified аннотации. Это может быть полезно для бутстрапоподобных классов, где выполняется инсталляция экземпляров класса, и используются классы реализации из различных пакетов.

Во-вторых, при создании Veripacks вы можете обеспечить реализацию CustomAccessDefinitionsReader признака и указать метаданные программным способом. Например, если у проекта есть  com.[company].[project].[module].[submodule] соглашение об именовании пакетов, и мы хотим, чтобы все пакеты модулей всегда требовали импорта, вместо добавления @RequiresImport аннотации к каждому такому пакету, мы можем сделать:

VeripacksBuilder
  .withCustomAccessDefinitionReader(new CustomAccessDefinitionsReader {
    override def isRequiresImport(pkg: Pkg) = pkg.name.split(".").length == 4
  })
  .build
  .verify(List("com.[company].[project]"))
  .throwIfNotOk()

Как всегда, Veripacks доступен в  центральном  репозитории Maven и в  источниках GitHub  под лицензией Apache2. Повеселись!