You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "Robert Scholte (JIRA)" <ji...@apache.org> on 2016/10/09 12:39:20 UTC

[jira] [Updated] (MCOMPILER-233) Default build mode doesn't recompile all dependencies, causing NoSuchMethodError/NoSuchFieldError at runtime

     [ https://issues.apache.org/jira/browse/MCOMPILER-233?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Robert Scholte updated MCOMPILER-233:
-------------------------------------
    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:
{noformat}
#!/bin/sh
set -e
{noformat}

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

{code:title=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() );
    }
}
{code}

{code:title=src/main/java/com/example/bug/Other.java }
package com.example.bug;

public class Other {
    Integer foo() { return new Integer(42); }
}
{code}

{{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}}


  was:
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 http://jira.codehaus.org/browse/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:
{noformat}
#!/bin/sh
set -e
{noformat}

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

{code:title=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() );
    }
}
{code}

{code:title=src/main/java/com/example/bug/Other.java }
package com.example.bug;

public class Other {
    Integer foo() { return new Integer(42); }
}
{code}

{{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}}



> Default build mode doesn't recompile all dependencies, causing NoSuchMethodError/NoSuchFieldError at runtime
> ------------------------------------------------------------------------------------------------------------
>
>                 Key: MCOMPILER-233
>                 URL: https://issues.apache.org/jira/browse/MCOMPILER-233
>             Project: Maven Compiler Plugin
>          Issue Type: Bug
>    Affects Versions: 2.0.2, 3.0
>         Environment: Linux amd64
>            Reporter: Török Edwin
>         Attachments: build.log
>
>
> 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:
> {noformat}
> #!/bin/sh
> set -e
> {noformat}
> \# Setup initial project
> {{mvn archetype:generate -DgroupId=com.example.bug -DartifactId=build-bug -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false}}
> {{cd build-bug}}
> {code:title=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() );
>     }
> }
> {code}
> {code:title=src/main/java/com/example/bug/Other.java }
> package com.example.bug;
> public class Other {
>     Integer foo() { return new Integer(42); }
> }
> {code}
> {{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}}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)