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

Maven compiler creates ghost classes when invoked with a compilerId of 'eclipse'

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • 2.0.1
    • 2.1
    • None
    • Windows XP, java 5 and java 1.4 with maven 2.0.4

    Description

      The maven-compiler-plugin, along with the plexus-eclipse-compiler component, is generating ghost classes (i.e. java source files that compile, but don't generate a .class file). If I put a deliberate error into the Logger.java file then the compilers, javac and eclipse, both catch it. However, only javac when invoked through maven will create a .class files for the 2 java files in the example project. I'm using the following pom definition:

      <?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>
      <groupId>com.abc.logging</groupId>
      <artifactId>abc-logging</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>jar</packaging>
      <name>ABC Logging</name>
      <dependencies>
      <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      </dependency>
      </dependencies>
      <build>
      <plugins>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <configuration>
      <source>1.4</source>
      <target>1.4</target>
      <verbose>true</verbose>
      <fork>false</fork>
      <compilerId>eclipse</compilerId>
      </configuration>
      <dependencies>
      <dependency>
      <groupId>org.codehaus.plexus</groupId>
      <artifactId>plexus-compiler-eclipse</artifactId>
      <version>1.5.1</version>
      </dependency>
      </dependencies>
      </plugin>
      </plugins>
      </build>
      </project>

      If you execute "mvn clean compile" then there will only be 1 class file, Foo.class, in the target/classes/com/abc/logging directory. However if you change the pom's <compilerId> element to be javac then 3 classes are now in the target folder. This would indicate an eclipse compiler bug, but wait there's more. The plexus-eclipse-compiler component uses the org.eclipse.jdt.core:core:3.1.0 repo artifact for compiling. So if you run the batch compiler in the core-3.1.0 jar like

      java -jar <repo path>/org/eclipse/jdt/core/3.1.0/core-3.1.0.jar -verbose -d target/classes src/main/java

      then you will get the following output indicating all 3 classes were created.

      E:\dev\workspace-eclipse\compiler-test>java -jar "C:\Documents and Settings\wbeckwit\.m2\repository\org\eclipse\jdt\core\3.1.0\core-3.1.0.jar" -verbose -d target/classes -verbose src/main/java
      Collecting source files inside E:\dev\workspace-eclipse\compiler-test\src\main\java
      Collecting source files inside E:\dev\workspace-eclipse\compiler-test\src\main\resources
      parsing E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Foo.java - #1/2
      parsing E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Logger.java - #2/2
      [reading java/lang/Object.class]
      analyzing E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Foo.java - #1/2
      writing com\abc\logging\Foo.class - #1
      completed E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Foo.java - #1/2
      analyzing E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Logger.java - #2/2
      [reading java/util/Map.class]
      [reading java/util/HashMap.class]
      [reading java/lang/Class.class]
      [reading java/lang/String.class]
      [reading java/lang/Throwable.class]
      [reading java/io/Serializable.class]
      [reading java/lang/Cloneable.class]
      [reading java/util/AbstractMap.class]
      writing com\abc\logging\Logger$Bar.class - #2
      writing com\abc\logging\Logger.class - #3
      completed E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Logger.java - #2/2
      [2 units compiled]
      [3 .class files generated]
      ----------
      1. WARNING in E:\dev\workspace-eclipse\compiler-test\src\main\java\com\abc\logging\Logger.java
      (at line 8)
      private boolean debug; // *** comment this invocation out and the class file will be generated
      ^^^^^
      The field Logger.debug is never read locally
      ----------
      1 problem (1 warning)
      E:\dev\workspace-eclipse\compiler-test>

      Also if you use the lastest 3.2 eclipse compiler available here, http://download.eclipse.org/eclipse/downloads/drops/R-3.2-200606291905/download.php?dropFile=ecj.jar, then you still get 3 classes compiled.

      Therefore this indicates a maven bug, but wait there's even more. The Logger.java file has 2 "// ***" comments in it. If you comment out the boolean declaration then the eclipse compiler, when invoked through maven, will create the 3 class files. Howeve if you also comment out the marked method invocation then the we're back to getting only 1 class file generated. WTF!? Again javac invoked via maven and the eclipse core-3.1.0 compiler always generates 3 class files. Can someone help the universe make sense again?

      Setting the <fork> element to true has no affect on the results seen.

      Attachments

        1. compiler-test.zip
          2 kB
          Binyan

        Activity

          People

            jdcasey John Dennis Casey
            binyan Binyan
            Votes:
            4 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: