Maven Dependency Plugin
  1. Maven Dependency Plugin
  2. MDEP-122

Analyze target does not work correctly when only using a constant defined in a different module

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 2.0-alpha-4
    • Fix Version/s: 2.6
    • Component/s: analyze
    • Labels:
      None
    • Environment:
      Windows.
      Maven 2.0.6
      Java 1.5 compiler
    • Number of attachments :
      2

      Description

      I have 2 projects as seen in the attached files.
      My first project contains a single interface that defines a String constant.
      My second project, uses the String constant from my first project.

      When i try to use dependency:analyze to fail the build as seen below, i can't make the system work.

      If i add the dependency from project 2 to project 1, i get:

      [INFO] [dependency:analyze {execution: analyze}]
      [INFO] Used declared dependencies:
      [INFO]    None
      [INFO] Used undeclared dependencies:
      [WARNING]    None
      [INFO] Unused declared dependencies:
      [INFO]    test:project1:jar: 1.0-SNAPSHOT:compile
      [WARNING] Potential problems discovered.

      But if i remove it, i get:
      If i remove the supposedly unused dependency, then I get a compile error:

      [INFO] ------------------------------------------------------------------------
      [ERROR] BUILD FAILURE
      [INFO] ------------------------------------------------------------------------
      [INFO] Compilation failure
      C:\ASSIA\development\maven_bug\project2\src\main\java\project2\NamesUser.java:[6,24] package project1 does not exist

      Here is the build definition i have...

          <build>
          <plugins>
           <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-dependency-plugin</artifactId>
              <executions>
                <execution>
                  <id>analyze</id>
                  <phase>package</phase>
                  <goals>
                    <goal>analyze</goal>
                  </goals>
                  <configuration>
                      <failBuild>true</failBuild>
                      <ignoreDirect>false</ignoreDirect>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
        </build>

        Issue Links

          Activity

          Hide
          Rémy Sanlaville added a comment -

          I also could reproduce the problem.

          I have been a little bit in depth.
          I found that it's not working only if it's an attribute (final static)

          For instance if I have a static final attribute, it does not work

          Message.java
          public static final String MSG = "Hello World";
          
          [INFO] [dependency:analyze]
          [WARNING] Unused declared dependencies found:
          [WARNING]    test.multimodules:module1:jar:1.0-SNAPSHOT:compile
          

          But on the other hand, if I have a static property it works.

          Message.java
          public static String MSG = "Hello World";
          
          [INFO] [dependency:analyze]
          [INFO] No dependency problems found
          

          Find in attachment my test analyze project : analyze.zip

          Show
          Rémy Sanlaville added a comment - I also could reproduce the problem. I have been a little bit in depth. I found that it's not working only if it's an attribute (final static) For instance if I have a static final attribute, it does not work Message.java public static final String MSG = "Hello World" ; [INFO] [dependency:analyze] [WARNING] Unused declared dependencies found: [WARNING] test.multimodules:module1:jar:1.0-SNAPSHOT:compile But on the other hand, if I have a static property it works. Message.java public static String MSG = "Hello World" ; [INFO] [dependency:analyze] [INFO] No dependency problems found Find in attachment my test analyze project : analyze.zip
          Hide
          Benjamin Bentmann added a comment -

          As stated in Clarifications and Amendments to the JLS, Class Initialization, a Java compiler must replace any references to a compile-time constant with a copy of its value. Hence, an analysis of the mere bytecode as done by the plugin via ASM cannot detect such dependencies.

          Show
          Benjamin Bentmann added a comment - As stated in Clarifications and Amendments to the JLS, Class Initialization , a Java compiler must replace any references to a compile-time constant with a copy of its value. Hence, an analysis of the mere bytecode as done by the plugin via ASM cannot detect such dependencies.
          Hide
          Iker Almandoz added a comment -

          Would it be possible to add an option to the dependency plugin to allow some dependencies to be ignored when using the 'analyze' target to 'failBuild' ?
          Something like:
          <configuration>
          <ignoreDependencies>
          <dependency>
          <groupId>test</groupId>
          <artifactId>project1</artifactId>
          <version>1.0-SNAPSHOT</version>
          </dependency>
          ...
          Such that the 'failBuild' ignores those dependencies when checking for the 'failure' ?
          This feature is important for our company in order to have all modules check that only the necessary dependencies are being imported.

          Show
          Iker Almandoz added a comment - Would it be possible to add an option to the dependency plugin to allow some dependencies to be ignored when using the 'analyze' target to 'failBuild' ? Something like: <configuration> <ignoreDependencies> <dependency> <groupId>test</groupId> <artifactId>project1</artifactId> <version>1.0-SNAPSHOT</version> </dependency> ... Such that the 'failBuild' ignores those dependencies when checking for the 'failure' ? This feature is important for our company in order to have all modules check that only the necessary dependencies are being imported.
          Hide
          brianfox brianfox added a comment -

          Yes, this sounds like a reasonable work around.

          Show
          brianfox brianfox added a comment - Yes, this sounds like a reasonable work around.
          Hide
          Benjamin Bentmann added a comment -

          Instead of <ignoredDependencies>, I suggest to use <usedDependencies> to tell the plugin the actual meaning of the dependency. This allows the plugin to correctly create the analysis right from the beginning instead of post-processing the initial analysis. For example, this also allows to detect the case of an used but undeclared dependency as sketched below:

          project                 uses constant C from dep-b, hence dep-b should be a declared dependency
          +- dep-a:compile
             +- dep-b:compile     defines some constant C
          
          Show
          Benjamin Bentmann added a comment - Instead of <ignoredDependencies> , I suggest to use <usedDependencies> to tell the plugin the actual meaning of the dependency. This allows the plugin to correctly create the analysis right from the beginning instead of post-processing the initial analysis. For example, this also allows to detect the case of an used but undeclared dependency as sketched below: project uses constant C from dep-b, hence dep-b should be a declared dependency +- dep-a:compile +- dep-b:compile defines some constant C
          Hide
          Carsten Behring added a comment -

          I have a similar problem, if I use only annotations from a certain dependency.

          In the case of using "project lombok", I add teh following to the pom.xml

          <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>0.11.0</version>
          </dependency>

          I think it's rather typical to use only annotations, if you use "project lombok". So by adding the annotations of the jar to my code:

          import lombok.Getter;
          import lombok.ToString;

          @Getter
          @ToString
          public class xxxx {
          }

          the dependency plugins warns about

          [WARNING] Unused declared dependencies found:
          [WARNING] org.projectlombok:lombok:jar:0.11.0

          Show
          Carsten Behring added a comment - I have a similar problem, if I use only annotations from a certain dependency. In the case of using "project lombok", I add teh following to the pom.xml <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>0.11.0</version> </dependency> I think it's rather typical to use only annotations, if you use "project lombok". So by adding the annotations of the jar to my code: import lombok.Getter; import lombok.ToString; @Getter @ToString public class xxxx { } the dependency plugins warns about [WARNING] Unused declared dependencies found: [WARNING] org.projectlombok:lombok:jar:0.11.0
          Hide
          Mark Michaelis added a comment -

          For now I am using a workaround for this issue: I use the classes once in my code. For example with such a (most of the time) hidden log-statement (here: slf4j):

          // Workaround for MDEP-122: Use class once.
          LOG.trace("Using constants from {}.", ConstantsClass.class.getName());
          
          Show
          Mark Michaelis added a comment - For now I am using a workaround for this issue: I use the classes once in my code. For example with such a (most of the time) hidden log-statement (here: slf4j): // Workaround for MDEP-122: Use class once. LOG.trace( "Using constants from {}." , ConstantsClass.class.getName());
          Hide
          Herve Boutemy added a comment -

          I like <usedDependencies> to declare groupId:artifactId (without version) used but not automatically detected by (bytecode) analysis

          Notice that if we add such an option, if a dependency is detected by bytecode analysis, it should be reported as a warning (to help people remove such manual declaration)

          Show
          Herve Boutemy added a comment - I like <usedDependencies> to declare groupId:artifactId (without version) used but not automatically detected by (bytecode) analysis Notice that if we add such an option, if a dependency is detected by bytecode analysis, it should be reported as a warning (to help people remove such manual declaration)
          Hide
          Herve Boutemy added a comment -

          done in r1400674

          Show
          Herve Boutemy added a comment - done in r1400674

            People

            • Assignee:
              Herve Boutemy
              Reporter:
              Iker Almandoz
            • Votes:
              9 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: