Home

Awesome

Gradle Modernizer Plugin

Gradle Plugin Portal

Gradle Modernizer Plugin detects uses of legacy APIs which modern Java versions supersede.

These modern APIs are often more performant, safer, and idiomatic than the legacy equivalents. For example, Modernizer can detect uses of Vector instead of ArrayList, String.getBytes(String) instead of String.getBytes(Charset), and Guava Objects.equal instead of Java 7 Objects.equals. The default configuration detects over 200 legacy APIs, including third-party libraries like Guava.

This Gradle plugin is actually a wrapper around Modernizer Maven Plugin so that the same functionality is now available in Gradle builds.

Usage

To use the plugin, include in your build script:

// You need to do this only once
plugins {
    // Option A: When your root project has a SourceSet
    // e.g. the root project is applying the java/groovy/kotlin plugin as well 
    id "com.github.andygoossens.modernizer" version "1.10.0"
    // Option B: When your root project does not have a SourceSet
    id "com.github.andygoossens.modernizer" version "1.10.0" apply false
}

repositories {
    mavenCentral()
}

// Option 1: Apply the plugin in each project where you want to use it
// Gradle's old way:
apply plugin: 'com.github.andygoossens.modernizer'
// Gradle's new way:
plugins {
    id 'com.github.andygoossens.modernizer'
}

// Option 2: Apply the plugin in all projects (even in the root project)
//           Preferably used with option A (= not mentioning 'apply false')
allprojects {
    apply plugin: 'com.github.andygoossens.modernizer'
}

// Option 3: Apply the plugin in all sub-projects (but not the root project)
//           Preferably used with option B (= mentioning 'apply false')
subprojects {
    apply plugin: 'com.github.andygoossens.modernizer'
}

If you are still using the old plugin id com.github.andygoossens.gradle-modernizer-plugin then please switch to com.github.andygoossens.modernizer instead.

If you want to call the modernizer task directly:

./gradlew modernizer

Most of the time you don't need to call the modernizer task yourself. The task knows its place inside the build lifecycle, and it will execute whenever it is deemed necessary.

Extension properties

Property nameTypeDefault valueDescription
toolVersionStringSee table belowVersion of modernizer-maven-plugin that will be used.
javaVersionString${project.targetCompatibility}Target Java version. Decides which violations will apply.
failOnViolationsbooleanfalseFail build when a violation has been detected.
includeTestClassesbooleanfalseWhether test classes will be searched for violations.
violationLogLevelStringwarnLogs violations at this level. Possible values: error, warn, info, debug, trace
violationsFileStringnullUser-specified violation file. Overrides standard violation checks.
violationsFilesString[][]User-specified violation files. Overrides violationsFile and standard checks.
exclusionsFileStringnullDisables user-specified violations. See format description below.
exclusionsString[][]Violations to disable. See format description below.
exclusionPatternsString[][]Violation patterns to disable. See format description below.
ignorePackagesString[][]Package prefixes to ignore. See format description below.
ignoreClassNamePatternsString[][]Full qualified class names (incl. package) to ignore. See format description below.
ignoreGeneratedClassesbooleantrueWhether classes annotated with an annotation whose retention policy is <code>runtime</code> or <code>class</code> and whose simple name contain "Generated" will be ignored.
skipbooleanfalseWhether task should be skipped.

Usage example

modernizer {
    failOnViolations = true
    includeTestClasses = true
}

Note that you can only configure the plugin in projects where the plugin has been applied. See "Usage" section above.

Formats

exclusionsFile

This is a text file with one exclusion per line in the javap format.

Example:

java/lang/String.getBytes:(Ljava/lang/String;)[B
com/google/common/base/Function
sun/misc/BASE64Decoder.decodeBuffer:(Ljava/lang/String;)[B
exclusions

This is a list of exclusions. Each exclusion should be in the javap format.

Example:

modernizer {
    exclusions = [
        'java/lang/String.getBytes:(Ljava/lang/String;)[B',
        'com/google/common/base/Function',
        'sun/misc/BASE64Decoder.decodeBuffer:(Ljava/lang/String;)[B',
    ]
}
exclusionPatterns

This is a list of exclusion patterns. Each exclusion should be a regular expression that matches the javap format of a violation.

Example:

modernizer {
    exclusionPatterns = [
        'java/lang/.*',
    ]
}
ignorePackages

This is a list of package prefixes for which no violations will be reported.

Ignoring a package will ignore all its children. Specifying foo.bar subsequently ignores foo.bar.*, foo.bar.baz.* and so on.

Example:

modernizer {
    ignorePackages = [
        'com.github.andygoossens',
    ]
}
ignoreClassNamePatterns

This is a list of full qualified class names (incl. package) to ignore. Each exclusion should be a regular expression that matches a package and/or class; the package name will be slash-separated, not dot-separated (ASM's format).

Example:

modernizer {
    ignoreClassNamePatterns = [
        '.*MyLegacyClass',
    ]
}

Ignoring elements

You cannot only ignore elements by using extension properties (see above), you can indicate that the plugin should ignore violations within a class or method by adding @SuppressModernizer to the element you'd like to ignore:

import org.gaul.modernizer_maven_annotations.SuppressModernizer;

public class Example {
    @SuppressModernizer
    public static void method() { /* your code here */ }
}

Add the following dependency to your Gradle build script:

// Option 1: compile time dependency (Gradle's old way)
compile 'org.gaul:modernizer-maven-annotations:2.6.0'

// Option 2: implementation dependency (Gradle's new way)
implementation 'org.gaul:modernizer-maven-annotations:2.6.0'

Version comparison

Gradle Modernizer Plugin is basically a wrapper around Modernizer Maven Plugin. The table below describes how they relate to each other.

Gradle Modernizer PluginModernizer Maven Plugin
1.0.x1.6.0
1.1.x1.6.0
1.2.x1.8.0
1.3.x2.0.0
1.4.x2.1.0
1.5.x2.2.0
1.6.x2.3.0
1.7.x2.5.0
1.8.x2.6.0
1.9.x2.7.0
1.10.02.9.0

Note that you can override the default version of Modernizer Maven Plugin which will be used. Specify the desired version in the toolVersion extension property. Pay attention: This might break when there is an API change!

FAQ

I found an undetected case of legacy API. Can you add a new violation rule?

Sounds great! However, I cannot add it myself as Modernizer Maven Plugin maintains the list of violation rules. Open an issue there and describe what you found.

Note that it might take some time for them to release a new version with your rule.

There is a new version of Modernizer Maven Plugin, but there is no corresponding version of your plugin.

That is not a question. Unfortunately, I might not have found the time to release a new version of the Gradle plugin.

In the meanwhile you can specify the desired version in the toolVersion extension property. The Gradle plugin will then pick up the requested version and, if the API is still the same, use it.

modernizer {
    toolVersion = '1.10.0'
}

Will you add a feature X?

That depends on whether the feature is specific to Gradle. If it is, then I will see what I can do. However, if it requires changes in Modernizer Maven Plugin, then it is up to its maintainers.

References

License

Licensed under the Apache License, Version 2.0
Copyright (C) 2016-2024 Andy Goossens

Inspired by, and based upon code from:

Modernizer Maven Plugin
Copyright (C) 2014-2023 Andrew Gaul

Gradle Docker plugin
Copyright (C) 2014 the original author or authors.