Uploaded image for project: 'Maven Compiler Plugin'
  1. Maven Compiler Plugin
  2. MCOMPILER-233

Default build mode doesn't recompile all dependencies, causing NoSuchMethodError/NoSuchFieldError at runtime

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Incomplete
    • 2.0.2, 3.0
    • None
    • None
    • Linux amd64

    Description

      I build a project with 'mvn package', change the type of a field/method in one source file, run 'mvn package' again and it only rebuilds the changed file, and not the other classes that depend on it.
      This can cause NoSuchMethodError/NoSuchFieldError when/if the code is reached at runtime. (at least Java 1.7 didn't detect this at class load time).

      Due to MCOMPILER-209 it is not entirely obvious how to turn off these partial builds, for example if I put <useIncrementalCompilation>true</useIncrementalCompilation> in my pom.xml then both source files are recompiled and the program works correclty so I would think that incremental compilation is NOT used in that case? Confusing.

      It appears that the only reliable way to build a project is to run 'mvn clean package' instead of just 'mvn package'.

      Maven should probably print a warning when using the partial builds, and the documentation should be updated to warn of these inconsistencies.
      Or perhaps you could run a final checking step after all files are compiled that checks whether the .class files are all still consistent (like a linker step).

      Self-contained testcase:

      #!/bin/sh
      set -e
      

      # Setup initial project
      mvn archetype:generate -DgroupId=com.example.bug -DartifactId=build-bug -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
      cd build-bug

      src/main/java/com/example/bug/App.java
      package com.example.bug;
      
      public class App
      {
          public static void main( String[] args )
          {
              System.out.println( new Other().foo() );
          }
      }
      
      src/main/java/com/example/bug/Other.java
      package com.example.bug;
      
      public class Other {
          Integer foo() { return new Integer(42); }
      }
      

      mvn package java -cp target/build-bug-1.0-SNAPSHOT.jar com.example.bug.App

      # Make a change
      sed -i -e 's/Integer/Long/g' src/main/java/com/example/bug/Other.java

      # Watch how incremental compilation breaks everything
      mvn -X package >build.log
      java -cp target/build-bug-1.0-SNAPSHOT.jar com.example.bug.App

      Attachments

        1. build.log
          54 kB
          Török Edwin

        Activity

          People

            rfscholte Robert Scholte
            edwintorok Török Edwin
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: