ImportControl
Since Checkstyle 4.0
Description
You can control imports based on the package name or based on the file name. When controlling packages, all files and sub-packages in the declared package will be controlled by this check. To specify differences between a main package and a sub-package, you must define the sub-package inside the main package. When controlling file, only the file name is considered and only files processed by TreeWalker. The file's extension is ignored.
Short description of the behaviour:
- 
          Check starts checking from the longest matching subpackage (later 'current subpackage') or
          the first file name match described inside import control file to package defined in class file.
        
- The longest matching subpackage is found by starting with the root package and examining if any of the sub-packages or file definitions match the current class' package or file name.
 - If a file name is matched first, that is considered the longest match and becomes the current file/subpackage.
 - If another subpackage is matched, then it's subpackages and file names are examined for the next longest match and the process repeats recursively.
 - If no subpackages or file names are matched, the current subpackage is then used.
 
 - Order of rules in the same subpackage/root are defined by the order of declaration in the XML file, which is from top (first) to bottom (last).
 - If there is matching allow/disallow rule inside the current file/subpackage then the Check returns the first "allowed" or "disallowed" message.
 - If there is no matching allow/disallow rule inside the current file/subpackage then it continues checking in the parent subpackage.
 - If there is no matching allow/disallow rule in any of the files/subpackages, including the root level (import-control), then the import is disallowed by default.
 
The DTD for an import control XML document is at https://checkstyle.org/dtds/import_control_1_4.dtd. It contains documentation on each of the elements and attributes.
The check validates a XML document when it loads the document. To validate against the above DTD, include the following document type declaration in your XML document:
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
        Properties
| name | description | type | default value | since | 
|---|---|---|---|---|
| file | Specify the location of the file containing the import control configuration. It can be a regular file, URL or resource path. It will try loading the path as a URL first, then as a file, and finally as a resource. | URI | null | 
              
4.0 | 
| path | Specify the regular expression of file paths to which this check should apply. Files that don't match the pattern will not be checked. The pattern will be matched against the full absolute file path. | Pattern | .* | 
              
7.5 | 
Examples
To configure the check using an import control file called "${config.folder}/import-control1.xml", then have the following:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control1.xml"/>
    </module>
  </module>
</module>
Import control configuration:
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <disallow class="java.io.File"/>
  <allow class="java.io.FileReader"/>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol;
import java.io.File; // violation, 'Disallowed import - java.io.File'
import java.io.FileReader;
public class Example1 {}
To configure the check to only check the "${config.folder}/api" directory using an import control file called "${config.folder}/import-control2.xml", then have the following:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control2.xml"/>
      <property name="path" value="${config.folder}[\\/]api[\\/].*$"/>
    </module>
  </module>
</module>
Import control configuration:
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <disallow class="java.io.File"/>
  <allow class="java.io.FileReader"/>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol;
import java.io.File; // ok, import control pkg attribute does not package this class
import java.io.FileReader;
public class Example2 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control3.xml"/>
    </module>
  </module>
</module>
          In the example below, access to package
          com.puppycrawl.tools.checkstyle.checks and its subpackages is
          allowed from anywhere in
          com.puppycrawl.tools.checkstyle.checks.imports.importcontrol except
          from the filters subpackage where access to all
          check's subpackages is disallowed. Two java.lang.ref
          classes are allowed by virtue of one regular expression instead of listing
          them in two separate allow rules (as it is done with the Files
          and ClassPath classes).
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <disallow pkg="sun"/>
  <allow pkg="com.puppycrawl.tools.checkstyle.api"/>
  <allow pkg="com.puppycrawl.tools.checkstyle.checks"/>
  <allow class="com.google.common.io.Files"/>
  <allow class="com.google.common.reflect.ClassPath"/>
  <subpackage name="filters">
    <allow class="java\.lang\.ref\.(Weak|Soft)Reference"
      regex="true"/>
    <disallow pkg="com\.puppycrawl\.tools\.checkstyle\.checks\.[^.]+"
      regex="true"/>
    <disallow pkg="com.puppycrawl.tools.checkstyle.ant"/>
    <disallow pkg="com.puppycrawl.tools.checkstyle.gui"/>
  </subpackage>
  <subpackage name="dao">
    <disallow pkg="javax.swing" exact-match="true"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.filters;
import com.google.common.io.Files;
import com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck;
// violation above, 'Disallowed import'
import java.lang.ref.ReferenceQueue;
// violation above, 'Disallowed import - java.lang.ref.ReferenceQueue'
import java.lang.ref.SoftReference; // ok, specifically allowed by regex expression
public class Example3 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control4.xml"/>
    </module>
  </module>
</module>
          Regular expressions are used to enforce a layering rule: In all
          dao packages it is not allowed to access UI layer code (ui,
          awt, and swing). On the other hand it is not allowed to
          directly access dao and service layer from ui
          packages. The root package is also a regular expression that is used to handle old
          and new domain name with the same rules.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com\.puppycrawl\.tools\.checkstyle\.checks\.imports\.importcontrol\.(olddomain|newdomain)\..*"
                regex="true">
  <allow class="java.io.File"/>
  <allow class="java.util.Scanner"/>
  <subpackage name="[^.]+\.dao" regex="true">
    <disallow pkg=".*\.checks" regex="true"/>
    <disallow pkg=".*\.(awt|swing).\.*" regex="true"/>
  </subpackage>
  <subpackage name="[^.]+\.checks" regex="true">
    <disallow pkg=".*\.(dao|service)" regex="true"/>
  </subpackage>
</import-control>
Example results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.newdomain.dao;
import com.puppycrawl.tools.checkstyle.checks.TranslationCheck;
// violation above, 'Disallowed import'
import java.io.File;
import java.util.Scanner;
import javax.swing.ActionMap; // violation, 'Disallowed import - javax.swing'
public class Example4 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control5.xml"/>
    </module>
  </module>
</module>
          For example below, usage of strategyOnMismatch property is shown.
          This property defines strategy in a case when no matching allow/disallow rule was found.
          Property strategyOnMismatch is attribute of import-control and
          subpackage tags.
          Property can have the following values for import-control tag:
        
- disallowed (default value) - if there is no matching allow/disallow rule in any of the subpackages, including the root level (import-control), then the import is disallowed.
 - allowed - if there is no matching allow/disallow rule in any of the subpackages, including the root level, then the import is allowed.
 
          And following values for subpackage tags:
        
- delegateToParent (default value) - if there is no matching allow/disallow rule inside the current subpackage, then it continues checking in the parent subpackage.
 - allowed - if there is no matching allow/disallow rule inside the current subpackage, then the import is allowed.
 - disallowed - if there is no matching allow/disallow rule inside the current subpackage, then the import is disallowed.
 
          The following example demonstrates usage of strategyOnMismatch property for
          import-control tag. Here all imports are allowed except
          java.awt.Image and java.io.File classes.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol"
  strategyOnMismatch="allowed">
  <disallow class="java.awt.Image"/>
  <disallow class="java.io.File"/>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol;
import java.awt.Image; // violation, 'Disallowed import - java.awt.Image'
import java.io.File; // violation, 'Disallowed import - java.io.File'
import java.util.Scanner; // ok, allowed on mismatch by default
public class Example5 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control6.xml"/>
    </module>
  </module>
</module>
          In the example below, any import is disallowed inside
          com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports
          package except imports from package javax.swing and class
          java.io.File. However, any import is allowed in the classes outside of
          com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports
          package.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol"
  strategyOnMismatch="allowed">
  <subpackage name="someImports" strategyOnMismatch="disallowed">
    <allow pkg="javax.swing"/>
    <allow class="java.io.File"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports;
import javax.swing.Action;
import java.io.File;
import java.util.Random; // violation, 'Disallowed import - java.util.Random'
public class Example6 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control7.xml"/>
    </module>
  </module>
</module>
          When strategyOnMismatch has allowed or disallowed
          value for subpackage tag, it makes subpackage isolated from
          parent rules.
          In the next example, if no matching rule was found inside
          com.puppycrawl.tools.checkstyle.checks.filters then it continues checking
          in the parent subpackage, while for
          com.puppycrawl.tools.checkstyle.checks.someImports import will be disallowed
          by default.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <allow class="java\.awt\.Image" regex="true"/>
  <allow class="java\..*\.File" local-only="true" regex="true"/>
  <subpackage name="someImports" strategyOnMismatch="disallowed">
    <allow pkg="javax\.swing" regex="true"/>
    <allow pkg="java\.io" exact-match="true"
      local-only="true" regex="true"/>
  </subpackage>
  <subpackage name="filters">
    <allow class="javax.util.Date"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports;
import javax.swing.Renderer;
import java.io.File;
import java.awt.Image; // violation, 'Disallowed import - java.awt.Image'
public class Example7 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control8.xml"/>
    </module>
  </module>
</module>
          In the example below, in the package gui, only the file names that include
          "Panel", "View", or "Example" are disallowed to have imports from
          com.mycompany.dao and any sql package. In addition, only
          the file name named "PresentationModel" in the package gui is
          disallowed to have imports that match javax.swing.J*.
          All other imports in the package are allowed.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <subpackage name="gui" strategyOnMismatch="allowed">
    <file name=".*(Panel|View|Example).*" regex="true">
      <disallow pkg="com.mycompany.dao"/>
      <disallow pkg=".*\.sql" regex="true"/>
    </file>
    <file name="PresentationModel">
      <disallow pkg="javax\.swing\.J.*" regex="true"/>
    </file>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.gui;
import java.sql.Blob; // violation, 'Disallowed import - java.sql.Blob'
import java.io.File;
import javax.swing.Renderer; // ok, does not match a file name for disallow rule.
public class Example8 {}
Example of blacklist mode
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control9.xml"/>
    </module>
  </module>
</module>
To have a blacklist mode, it is required to have disallows inside subpackage and to have allow rule inside parent of the current subpackage to catch classes and packages those are not in the blacklist.
          In the example below any import from java.util package is allowed except
          java.util.Map inside subpackage
          com.puppycrawl.tools.checkstyle.filters.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <allow pkg="java.util"/>
  <subpackage name="filters" >
    <disallow class="java.util.Map"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.filters;
import java.util.Date;
import java.util.List;
import java.util.Map; // violation, 'Disallowed import - java.util.Map'
public class Example9 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control10.xml"/>
      <property name="path" value="^.*[\\/]src[\\/]xdocs-examples[\\/].*$"/>
    </module>
  </module>
</module>
          imports java.util.stream.Stream and
          java.util.stream.Collectors are disallowed inside
          com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports
          package, but because of <allow pkg="java.util.stream"/> every import
          from java.util.stream is allowed except described ones.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <allow pkg="java.util.stream"/>
  <subpackage name="someImports">
    <disallow class="java.util.stream.Stream"/>
    <disallow class="java.util.stream.Collectors"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports;
import java.util.stream.Stream;     // violation, 'Disallowed import - java.util.stream.Stream'
import java.util.stream.Collectors; // violation, 'Disallowed import - java.util.stream.Collectors'
import java.util.stream.IntStream;
public class Example10 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control11.xml"/>
    </module>
  </module>
</module>
          In the following example, all imports are allowed except the classes
          java.util.Date, java.util.List and package sun.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <allow pkg=".*" regex="true"/>
  <subpackage name="someImports">
    <disallow class="java.util.Date"/>
    <disallow class="java.util.List"/>
    <disallow pkg="sun"/>
  </subpackage>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol.someImports;
import java.io.FileFilter;
import java.util.Date; // violation, 'Disallowed import - java.util.Date'
import java.util.List; // violation, 'Disallowed import - java.util.List'
import java.util.Optional;
import sun.misc.Signal; // violation, 'sun.misc.Signal'
public class Example11 {}
To configure the check:
<module name="Checker">
  <module name="TreeWalker">
    <module name="ImportControl">
      <property name="file" value="${config.folder}/import-control12.xml"/>
    </module>
  </module>
</module>
          In the following example, all imports of the java.util package are allowed
          except the java.util.Date class.
        
<?xml version="1.0"?>
<!DOCTYPE import-control PUBLIC
    "-//Checkstyle//DTD ImportControl Configuration 1.4//EN"
    "https://checkstyle.org/dtds/import_control_1_4.dtd">
<import-control pkg="com.puppycrawl.tools.checkstyle.checks.imports.importcontrol">
  <disallow class="java.util.Date"/>
  <allow pkg="java.util"/>
</import-control>
Results:
package com.puppycrawl.tools.checkstyle.checks.imports.importcontrol;
import java.util.Date; // violation, 'Disallowed import - java.util.Date'
import java.util.List;
import java.util.Optional;
import java.util.Map;
public class Example12 {}
Notes on regular expressions
Regular expressions in import rules have to match either Java packages or classes. The language rules for packages and class names can be described by the following complicated regular expression that takes into account that Java names may contain any unicode letter, numbers, underscores, and dollar signs (see section 3.8 in the Java specs):
- 
            
[\p{Letter}_$][\p{Letter}\p{Number}_$]*or short[\p{L}_$][\p{L}\p{N}_$]*for a class name or package component. - 
            
([\p{L}_$][\p{L}\p{N}_$]*\.)*[\p{L}_$][\p{L}\p{N}_$]*for a fully qualified name. 
          But it is not necessary to use these complicated expressions since no validation is
          required. Differentiating between package separator '.' and others is
          sufficient. Unfortunately '.' has a special meaning in regular expressions so one has
          to write \. to match an actual dot.
        
- 
            Use 
[^.]+(one or more "not a dot" characters) for a class name or package component. - 
            Use 
com\.google\.common\.[^.]+to match any subpackage ofcom.google.common. - 
            When matching concrete packages like 
com.google.commonomitting the backslash before the dots may improve readability and may be just exact enough:com.google.common\.[^.]+matches not only subpackages ofcom.google.commonbut e.g. also ofcom.googleecommonbut you may not care for that. - 
            Do not use 
.*unless you really do not care for what is matched. Often you want to match only a certain package level instead. 
Notes on static imports
Static members (including methods, constants and static inner classes) have to be explicitly allowed when they are imported, they are not automatically allowed along with their enclosing class.
          For example, to allow importing both java.util.Map and
          java.util.Map.Entry use the following configuration:
        
<import-control pkg="com.puppycrawl.tools.checkstyle">
  <allow class="java.util.Map"/>
  <allow class="java.util.Map.Entry"/>
</import-control>
        It is also possible to use a regex with a wildcard:
<import-control pkg="com.puppycrawl.tools.checkstyle">
  <allow class="java.util.Map"/>
  <allow class="java.util.Map.*" regex="true" />
</import-control>
        Example of Usage
Violation Messages
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
Package
com.puppycrawl.tools.checkstyle.checks.imports






