Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to speed up Javadoc (takes 7 minutes)

I am building a Javadoc for a module with 2,509 classes. This currently takes 7 min or 6 files per second.

I have tried

mvn -T 1C install 

However javadoc only uses 1 CPU. Is there a way to use more and/or speed up?

I am using Oracle JDK 8 update 112. My dev machine has 16 cores and 128 GB of memory.

Running flight recorder I can see that there is only one thread main

enter image description here

For those who are interested, I've used the following options:

<plugin>     <artifactId>maven-javadoc-plugin</artifactId>     <configuration>         <additionalJOptions>             <additionalJOption>-J-XX:+UnlockCommercialFeatures</additionalJOption>             <additionalJOption>-J-XX:+FlightRecorder</additionalJOption>             <additionalJOption>-J-XX:StartFlightRecording=name=test,filename=/tmp/myrecording-50.jfr,dumponexit=true</additionalJOption>             <additionalJOption>-J-XX:FlightRecorderOptions=loglevel=debug</additionalJOption>         </additionalJOptions>     </configuration> </plugin> 

NOTE: One workaround is to do:

-Dmaven.javadoc.skip=true 
like image 964
Peter Lawrey Avatar asked Dec 16 '16 17:12

Peter Lawrey


People also ask

How do I fix Javadoc errors?

You need to call mvn javadoc:fix to fix main Java source files (i.e. inside src/main/java directory) or mvn javadoc:test-fix to fix test Java source files (i.e. inside src/test/java directory).

Which goal is used to generate the path for publishing Javadoc after every successful build?

In the Goals field, place javadoc:javadoc —this will tell Maven to generate the Javadoc documentation. Now go to the “Post-build Action” and tick the “Publish Javadoc” checkbox.

How do I export a Javadoc?

In Eclipse, go to File > Export. Expand Java and select Javadoc. Then click Next. Select your project and package.


2 Answers

Running maven with -T1C will cause maven to try to build modules in parallel, so if you have a multi-module project, at best it will build each module's javadoc in parallel (if your dependency graph between modules allow it).

The javadoc process itself is single-threaded, so you won't be able to use multiple cores to generate the javadoc of one single module.

However, since you have many classes (and possibly many @link doclets or similar ?), maybe the javadoc process could benefit from extended heap. Have you looked into GC activity ? Try adding this in your configuration, see if it helps :

<additionalJOption>-J-Xms2g</additionalJOption> <additionalJOption>-J-Xmx2g</additionalJOption> 
like image 50
lbndev Avatar answered Sep 23 '22 02:09

lbndev


@lbndev is right, at least with the default Doclet (com.sun.tools.doclets.formats.html.HtmlDoclet) that is supplied with Javadoc. A look through the source confirms the single threaded implementation:

  • The starting point is in the parent class AbstractDoclet.startGeneration()
  • This in turn calls new ClassTree() which calls ClassTree.buildTree() which uses a for loop to iterate the list of classes, generating models of the classes
  • The next step is AbstractDoclet.generateClassFiles(), again a for loop on the packages
  • This then drills down to HtmlDoclet.generateClassFiles(), which iterates package.allClasses(), again in a for loop.

(Those links are to JDK 8 source. With JDK 11 the classes have moved, but the basic for loops in HtmlDoclet and AbstractDoclet are still there.)

Some sample based profiling confirmed these are the methods that are the bottleneck: Javadoc-profiling

This won't be what you're hoping to hear, but this looks like no option in the current standard Javadoc for multi-threading, at least within a single Maven module.

generateClassFiles() etc would lend themselves well to a bit of multithreading, though this would probably need to be a change in the JDK. As mentioned below AbstractDoclet.isValidDoclet() even actively blocks subclassing of HtmlDoclet. Trying to reimplement some of those loops as a third party would need to pull in a lot of other code.

A scan around other Doclet implementations (e.g. javadown) only found a similar implementation style around the package and class drilldown. It's possible others on this thread will know more.

Thinking a bit more widely, there might be room for tuning around DocFileFactory. It's clearly marked up as an internal class (not even public in the package), but it does abstract the writing of the (HTML) files. It seems possible an alternative version of this could buffer the HTML in memory, or stream directly to a zip file, to improve the IO performance. But clearly this would also need to understand the risk of change in the JDK tools.

like image 43
df778899 Avatar answered Sep 20 '22 02:09

df778899