Maven bans dependencies with no configuration

I am developing a plugin for Bitbucket Server. When I try to start it, it fails because of banned dependencies:

[INFO] --- bitbucket-maven-plugin:8.1.0:validate-banned-dependencies (default-validate-banned-dependencies) @ diffPlugin ---
[INFO] validate banned dependencies
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.BannedDependencies failed with message:
make sure platform artifacts are not bundled into plugin
Found Banned Dependency: org.slf4j:slf4j-api:jar:1.7.30
Found Banned Dependency: commons-fileupload:commons-fileupload:jar:1.4
Found Banned Dependency: org.apache.httpcomponents:httpclient:jar:4.1.1
Found Banned Dependency: org.slf4j:slf4j-log4j12:jar:1.7.30
Found Banned Dependency: commons-io:commons-io:jar:2.6
Found Banned Dependency: org.apache.httpcomponents:httpcore:jar:4.4.12
Use 'mvn dependency:tree' to locate the source of the banned dependencies.

I cannot find any reference to the error message. Why are those dependencies banned? They are widely used packages.

I would appreciate any help in tracking this issue down.

Can you provide the dependencies section of your pom.xml? We want to see how you’ve set them up.

Here is the POM (I removed everything until the properties tag). One other thing of note is that this POM works with Bitbucket version 5.16, but when I use 7.2.4 it throws this error.

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <amps.version>8.1.0</amps.version>
        <bitbucket.version>7.2.4</bitbucket.version>
        <bitbucket.data.version>${bitbucket.version}</bitbucket.data.version>

        <!-- This property ensures consistency between the key in atlassian-plugin.xml and the OSGi bundle's key. -->
        <atlassian.plugin.key>${project.groupId}.${project.artifactId}</atlassian.plugin.key>

        <atlassian.spring.scanner.version>2.1.7</atlassian.spring.scanner.version>
        <javax.inject.version>1</javax.inject.version>
        <jsr311.version>1.1.1</jsr311.version>
        <plugin.testrunner.version>2.0.1</plugin.testrunner.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.atlassian.bitbucket.server</groupId>
                <artifactId>bitbucket-parent</artifactId>
                <version>${bitbucket.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.atlassian.bitbucket.server</groupId>
            <artifactId>bitbucket-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.bitbucket.server</groupId>
            <artifactId>bitbucket-spi</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.soy</groupId>
            <artifactId>soy-template-renderer-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.atlassian.plugin</groupId>
            <artifactId>atlassian-spring-scanner-annotation</artifactId>
            <version>${atlassian.spring.scanner.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.sal</groupId>
            <artifactId>sal-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.plugins</groupId>
            <artifactId>atlassian-plugins-webfragment</artifactId>
            <version>4.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.core</groupId>
            <artifactId>atlassian-core-utils</artifactId>
            <version>5.0-rc1</version>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- Jackson dependency for passing JSON objects to Soy templates -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.8</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>jsr311-api</artifactId>
            <version>${jsr311.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>com.atlassian.plugins</groupId>
            <artifactId>atlassian-plugins-osgi-testrunner</artifactId>
            <version>${plugin.testrunner.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun.pdfview/PDFRenderer -->
        <dependency>
            <groupId>org.swinglabs</groupId>
            <artifactId>pdf-renderer</artifactId>
            <version>1.0.5</version>
        </dependency>
        <!-- Framework for image scaling -->
        <dependency>
            <groupId>org.imgscalr</groupId>
            <artifactId>imgscalr-lib</artifactId>
            <version>4.2</version>
        </dependency>
        <!-- Apache PDFBox for processing Gerber PDFs -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.14</version>
        </dependency>
        <!-- processing file uploads -->
        <dependency> 
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.8.5</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>com.atlassian.maven.plugins</groupId>
                <artifactId>bitbucket-maven-plugin</artifactId>
                <version>${amps.version}</version>
                <extensions>true</extensions>
                <configuration>
                    <products>
                        <product>
                            <id>bitbucket</id>
                            <instanceId>bitbucket</instanceId>
                            <version>${bitbucket.version}</version>
                            <dataVersion>${bitbucket.data.version}</dataVersion>
                        </product>
                    </products>
                    <extractDependencies>false</extractDependencies>
                    <Bundle-Activator></Bundle-Activator>
                    <enableDevToolbox>false</enableDevToolbox>
                    <enablePde>false</enablePde>
                    <skipRestDocGeneration>true</skipRestDocGeneration>
                    <allowGoogleTracking>false</allowGoogleTracking>
                    <skipManifestValidation>true</skipManifestValidation>
                    <extractDependencies>false</extractDependencies>
                    <enableQuickReload>true</enableQuickReload>
                    <instructions>
                        <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>

                        <!-- Add package to export here -->
                        <Export-Package>
                            com.dizainsync.diff.diffPlugin.api,
                        </Export-Package>

                        <!-- Add package import here -->
                        <Import-Package>
                            org.springframework.osgi.*;resolution:="optional",
                            org.eclipse.gemini.blueprint.*;resolution:="optional",
                            *
                        </Import-Package>

                        <!-- Ensure plugin is Spring powered -->
                        <Spring-Context>*</Spring-Context>
                    </instructions>
                    <pluginArtifact>
                        <groupId>com.atlassian.labs.plugins</groupId>
                        <artifactId>quickreload</artifactId>
                        <version>${quick.reload.version}</version>
                    </pluginArtifact>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.atlassian.plugin</groupId>
                <artifactId>atlassian-spring-scanner-maven-plugin</artifactId>
                <version>${atlassian.spring.scanner.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>atlassian-spring-scanner</goal>
                        </goals>
                        <phase>process-classes</phase>
                    </execution>
                </executions>
                <configuration>
                    <verbose>false</verbose>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

On all the banned dependencies, please add <scope>provided</scope> to indicate to maven that it does not need to package those dependencies as the parent application will provide them. The default value for <scope/> is compile so right now Maven is trying to compile those dependencies into your plugin, which should not work and is now failing in newer versions of Bitbucket.

For instance, you currently have:

        <dependency> 
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

But this should be:

        <dependency> 
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
            <scope>provided</scope>
        </dependency>

This is documented here: https://developer.atlassian.com/server/framework/atlassian-sdk/managing-dependencies/

Adding a <dependency> tells the SDK that your code will use this artifact, but specifying <scope>provided</scope> refines that to mean “these classes will be provided at runtime by the product”.

1 Like

Thank you, that helped. I think I am getting confused with the scopes, I thought that provided means that the SDK has those plugins. At least, it seemed to work that way with the older version of the plugin that the POM was based on.

The default setting or when setting scope = compile, this means take the JAR and include it in your package.

The setting of scope = provided means that Jira/Bitbucket/Confluence/Parent Application already has it and will give it to you.

Good luck! We’re all counting on you!

Ah, I see. I guess Bitbucket now has more JARs than it did before. Thanks for your help!

1 Like

I think it causes them problems when plugin authors bring their own packages, so I think newer versions are just getting more restrictive about how you package things.