11

Summary:

I've run into an interesting problem, and I'm not quite sure how to sleuth it:

  • Our project has been building fine for months
  • I changed the maven-compiler-plugin to use the eclipse compiler instead of javac
  • Now when I run mvn site, maven-javadoc-plugin fails
  • According to the stack trace, it appears the Javadoc tool is crashing on a class file created by the Eclipse compiler

Is there any way to fix this? If not, is there at least any way to debug it further?

Full details:

I'm using Java 1.6.0_27 and Maven 3.0.2.

I've been using the javac compiler to build our codebase, but I'm interested in trying the Eclipse compiler, since it produces much better warnings (and is more configurable in other ways).

So I changed the definition of the maven-compiler-plugin in the pom.xml to:

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <compilerId>eclipse</compilerId>
        <source>1.6</source>
        <target>1.6</target>
        <compilerArgument>-warn:+boxing,enumSwitch,javadoc,hashCode</compilerArgument>
        <showWarnings>true</showWarnings>
        <showDeprecation>true</showDeprecation>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>1.8.2</version>
        </dependency>
    </dependencies>
</plugin>

In my <reporting> section, I have:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.8</version>
</plugin>

So far, so good. I did a mvn clean install and everything builds fine, all the tests pass, and everything looks great.

But when I try to run mvn site, when it gets to the Javadoc report, it fails with what appears to be a Javadoc crash:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.0:site (default-site) on project framework: Error during page generation: Error rendering Maven report:
[ERROR] Exit code: 1 - java.lang.StringIndexOutOfBoundsException: String index out of range: -15
[ERROR] at java.lang.String.substring(String.java:1937)
[ERROR] at java.lang.String.substring(String.java:1904)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.simpleBinaryName(ClassReader.java:958)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readEnclosingMethodAttr(ClassReader.java:930)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readMemberAttr(ClassReader.java:909)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readClassAttr(ClassReader.java:1053)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readClassAttrs(ClassReader.java:1067)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readClass(ClassReader.java:1560)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.readClassFile(ClassReader.java:1658)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.fillIn(ClassReader.java:1845)
[ERROR] at com.sun.tools.javac.jvm.ClassReader.complete(ClassReader.java:1777)
[ERROR] at com.sun.tools.javac.code.Symbol.complete(Symbol.java:386)
[ERROR] at com.sun.tools.javac.code.Symbol$ClassSymbol.complete(Symbol.java:763)
[ERROR] at com.sun.tools.javac.code.Symbol$ClassSymbol.flags(Symbol.java:695)
[ERROR] at com.sun.tools.javadoc.ClassDocImpl.getFlags(ClassDocImpl.java:105)
[ERROR] at com.sun.tools.javadoc.ClassDocImpl.isAnnotationType(ClassDocImpl.java:116)
[ERROR] at com.sun.tools.javadoc.DocEnv.isAnnotationType(DocEnv.java:574)
[ERROR] at com.sun.tools.javadoc.DocEnv.getClassDoc(DocEnv.java:546)
[ERROR] at com.sun.tools.javadoc.PackageDocImpl.getClasses(PackageDocImpl.java:154)
[ERROR] at com.sun.tools.javadoc.PackageDocImpl.addAllClassesTo(PackageDocImpl.java:170)
[ERROR] at com.sun.tools.javadoc.RootDocImpl.classes(RootDocImpl.java:178)
[ERROR] at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.startGeneration(AbstractDoclet.java:96)
[ERROR] at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.start(AbstractDoclet.java:64)
[ERROR] at com.sun.tools.doclets.formats.html.HtmlDoclet.start(HtmlDoclet.java:42)
[ERROR] at com.sun.tools.doclets.standard.Standard.start(Standard.java:23)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
[ERROR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
[ERROR] at java.lang.reflect.Method.invoke(Method.java:597)
[ERROR] at com.sun.tools.javadoc.DocletInvoker.invoke(DocletInvoker.java:269)
[ERROR] at com.sun.tools.javadoc.DocletInvoker.start(DocletInvoker.java:143)
[ERROR] at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:340)
[ERROR] at com.sun.tools.javadoc.Start.begin(Start.java:128)
[ERROR] at com.sun.tools.javadoc.Main.execute(Main.java:41)
[ERROR] at com.sun.tools.javadoc.Main.main(Main.java:31)
[ERROR] 
[ERROR] Command line was: "C:\Program Files (x86)\Java\jdk1.6.0_27\jre\..\bin\javadoc.exe" @options @packages
[ERROR] 
[ERROR] Refer to the generated Javadoc files in 'C:\Projects\SMF\framework\target\site\apidocs' dir.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

My Question:

OK, so what changed? All the Javadoc and the Maven site were building just fine when I was using javac, but as soon as I switched to the Eclipse compiler, Javadoc crashes.

Worse, it doesn't even tell me what class caused it to crash, so I don't even know where to begin debugging this.

Obviously, for the time being this means that I'm not going to use the Eclipse compiler, and I'm going to stick with javac instead. But I'm curious as to why this is happening, and what I could possibly do to fix or work around it.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • This is odd. Maybe its a "defaults" issue --- can you run javac with explicit arguments ? – jayunit100 Nov 21 '11 at 18:57
  • @jayunit100: I'm not actually invoking javac at all. It looks like the Javadoc tool is using (parts of) javac internally, but as far as I know I have no control over that. (If you know a way, by all means, please post that as an answer!) – Daniel Pryden Nov 21 '11 at 19:59
  • How about using mvnDebug to find out what string it is balking on? That might give some clue. – Ustaman Sangat Nov 22 '11 at 17:34
  • @UstamanSangat: I'm not familiar with mvnDebug, I'll look into that. But I'm not sure if that will help, because it seems that the Maven plugin is invoking `javadoc.exe` via command line, and *that* process is the one that's crashing and not providing any useful diagnostic information. – Daniel Pryden Nov 22 '11 at 17:43
  • Worked for me on my project using java 6 update 29 and maven 3.0.3 on Windows 7. Perhaps you could try with the newer maven and java? – Raghuram Nov 23 '11 at 09:11
  • 1
    Do you have any javadoc generated, under `target\site\apidocs`? Maybe you can "guess" which class it was trying to process when it failed by checking folders and files? And did you run maven in debug mode to see more detailed output? Try `mvn site -X` to see error details. – melihcelik Nov 25 '11 at 14:23
  • @melihcelik: No, there was no javadoc generated at all. There was, however, a `javadoc.bat` file for running javadoc left behind in the `target\site\apidocs` folder, which I was able to use to solve the problem (see my answer below). – Daniel Pryden Feb 14 '12 at 20:48

5 Answers5

3

I finally got some time to look into this again. The maven-javadoc-plugin helpfully leaves behind a javadoc.bat script under target/site/apidocs when the javadoc.exe process fails, and I was able to find the offending package by pruning the list in the packages file that gets passed into javadoc.exe.

Interestingly, the problematic code turned out to be the Java source generated by the Google Protocol Buffers compiler. This was fortunate, since it's acceptable to simply exclude the protobuf-generated source from the Javadoc entirely.

I added the following definition, under both my <build> and <reporting> sections of the POM, and this resolved my issue:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.6.1</version>
    <configuration>
        <excludePackageNames>com.mycompany.myproject.proto</excludePackageNames>
    </configuration>
</plugin>
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
2

Workaround for this would be to create a separate profile for the site goal. So that you could define different compilers for different goals.

WeMakeSoftware
  • 9,039
  • 5
  • 34
  • 52
  • Interesting idea! But I'm not certain that it would work that well -- the Javadoc tool is already hardcoded to use the `javac` compiler. I suppose we would have to always use `mvn clean site` to make sure we didn't have any leftover `.class` files from the other compiler. – Daniel Pryden Nov 19 '11 at 00:35
  • This shouldn't be a problem unless you're building a really huge project on a really old PC. – WeMakeSoftware Nov 19 '11 at 00:46
1

Maybe the javadoc.exe is not using the same JRE that Eclipse uses. Are their any other JRE's installed? Try running the javadoc.exe process manually and see if it does the same thing, you might get the actual stacktrace of the problem.

Kelly S. French
  • 12,198
  • 10
  • 63
  • 93
0

This might not be an answer, but just propose an idea.

How about installing the JDK in the folder without space (I saw it is C:\Program Files (x86)...). Java supports spaces in the file names, but probably some of the plugins/tools/library that javadoc tools just doesn't support it.

Daniel Baktiar
  • 1,692
  • 11
  • 22
  • Interesting idea, but I don't think that's the problem, because all the javadoc was being generated just fine before I switched to the Eclipse compiler. – Daniel Pryden Jan 16 '12 at 01:04
0

Im guessing that the problem is that javac and eclipse are using different JDK versions for compiling your code

Andrew Koroluk
  • 611
  • 6
  • 19
  • 1
    The Eclipse compiler (ecj) doesn't use the JDK at all, it's a completely separate implementation. All it uses is the JRE. – Daniel Pryden Jan 16 '12 at 01:03