Over a million developers have joined DZone.

Verifying Usage of 3rd Party Libraries using Veripacks

DZone's Guide to

Verifying Usage of 3rd Party Libraries using Veripacks

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

Veripacks already allows to specify and verify which classes should be visible outside of a package(in a package-transitive way) as well as require importing and import packages within a project. This makes it possible to eliminate some build modules, while still keeping their strict isolation (which can be checked by running Veripacks).

However, what if we would like to verify that a 3rd party library is used only in a specific portion of the code? For example, let’s say we want the Hibernate classes to be used only by the dao module, and we want this to be verified at build time. The usual approach could be:

  • create a dao-api build module
  • create a dao build module with a dao-api and Hibernate dependencies
  • implement the DAOs
  • add the dao-api module as a dependency to all other modules which use the DAOs
  • add the dao module as a dependency to the module which builds the distribution (e.g. war)

If we are using Maven, that’s quite a lot of xml to write and directories to create. Could it be simpler?

Veripacks 0.4 aims at making this exact case simpler, using package-level annotations. When creating an instance of Veripacks, it is now possible to specify which packages should require importing. To use classes from such packages, you just need to add an @Import annotation to the package – and Veripacks will check that everything is used only where allowed:

// test case which runs Veripacks
// package in which we want to use Hibernate classes
// package-info.java
package com.foo.project.db.dao;
import org.veripacks.Import;

Veripacks itself uses these annotations to constraint the usage of the ASM bytecode-reading library; see the VeripacksSelfTest class and the annotation on the org.veripacks.reader package.

The improved process of constraining usage of a 3rd party library code to a specific part of our code now is:

  • create a dao.api and dao.impl packages (these are just example names; Veripacks doesn’t require using any specific naming convention)
  • add Hibernate as a dependency to the project
  • implement the DAOs
  • @Import the dao.api package in packages which use the DAOs

That’s a lot less XML to write (none), a bit more package-info.java to write, and only three directories to create.

Note however, that for project-packages, you should still use the @RequiresImport annotation. TheVeripacksBuilder.requireImportOf and .doNotRequireImportOf methods are only intended to be used with 3rd party packages.

The new release also contains two other features. Firstly, it is now possible to skip verification in a class using the @NotVerified annotation. This may be useful for bootstrap-like classes, where wiring of the class instances is done, and implementation-classes form various packages are used.

Secondly, when building Veripacks, you can provide an implementation of theCustomAccessDefinitionsReader trait, and specify metadata in a programmatic way. E.g. if the project has a com.[company].[project].[module].[submodule] package naming convention, and we would like all module-packages to always require import, instead of adding an@RequiresImport annotation to each such package, we can do:

  .withCustomAccessDefinitionReader(new CustomAccessDefinitionsReader {
    override def isRequiresImport(pkg: Pkg) = pkg.name.split(".").length == 4

As always Veripacks is available in the Maven central repository, and the sources on GitHub under the Apache2 license. Have fun!

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.


Published at DZone with permission of Adam Warski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}