18
votes

I find it difficult to read the new look-and-feel in JDK8 javadoc compared to JDK7. Here's a side-by-side example.

JDK7:

JDK7 javadoc look

JDK8:

JDK8 javadoc look

JDK8 takes up considerable more space. It now uses the DejaVu font where Arial was previously used. There may be good reasons for that. I don't know.

My biggest problem is in the "Parameters" and "Throws" sections where there's no longer any visual difference between the argument and its description. They are both in a mono spaced font. Writing descriptive text in mono spaced font is just ugly, I think. Mono spaced font is for names of identifiers, source code listings and the like. (feel free to disagree).

Can I get the JDK7 style back while still using the JDK8 javadoc tool?

I was hoping for something like javadoc -stylesheet jdk7.css where jdk7.css was something included with the JDK8. Also if I decide to customize the css on my own (not my thing, but there may be no other solution) I would hate to have to ensure availability of the new stylesheet on every build server in our enterprise. Perhaps there's a Maven solution for that ?

POSSIBLE SOLUTION ?

It has been suggested (below) to use the JDK7 javadoc css with the JDK8 javadoc tool to see if that would bring back some eligible Javadoc.

I've done my test by checking out the source code from the Apache Commons Lang project. I use only the source code, not their POM. This is to ensure that I know I'm working off the right base.

Okay, first - for reference - here's the Javadoc which has been produced by an all JDK7 toolchain (JDK7 javadoc tool, JDK7 css). Here's the POM snippet:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>2.9.1</version>
            <configuration>
                <stylesheetfile>${basedir}/src/main/css/jdk7javadoc.css</stylesheetfile>  
                <javadocExecutable>C:/Program Files/Java/jdk1.7.0_55/bin</javadocExecutable>   
            </configuration>
        </plugin>
    </plugins>
</build>  

and the resulting Javadoc: JDK7 javadoc, JDK7 css

Next, the attempt to use the JDK7 css with the JDK8 javadoc tool. Here's the POM snippet:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>2.9.1</version>
            <configuration>
                <stylesheetfile>${basedir}/src/main/css/jdk7javadoc.css</stylesheetfile>  
                <javadocExecutable>C:/Program Files/Java/jdk1.8.0_05/bin</javadocExecutable>   
            </configuration>
        </plugin>
    </plugins>
</build>  

and the resulting Javadoc: JDK8 javadoc, JDK7 css

So, as you can see, this strategy did not work out for me.

UPDATE

I've just realized that a consequence of this change is that it has become pointless to use {@code } (or <code>) markup on parameter descriptions. It doesn't show anyway. In other words if you liked to do like this in past:

/**
* ...
* @param eName the name for the entity or <code>null</code> to use the default
* ...
*/

there's simply no point to that anymore. Your null text will not stand out anyway.

UPDATE 2019-04-19

Parts of the problems mentioned above has been fixed in JDK-8072052 : <dd> part of <dl> list in javadoc should not be in monospace font. Fixed in Java 9 onwards, not backported to Java 8.

3
Wow, the javadoc for 8 sure has worse readability. Interested in the answer.André Stannek
@AndréStannek. Unfortunately you and I seem to be the only ones who think so. I've not seen this mentioned anywhere so perhaps most people just don't care (or don't think it is important). What beats me is why the JDK developers have actively taken this step backwards .. as I see it.peterh
Guess it's a matter of opinion and they have another one as we do :-(André Stannek
Man, that lack of indentation on the parameters and throws and see also section is terrible.EpicPandaForce
No need for "matter of taste" and other PC stuff... because obviously, they have just followed the new trend of huge letters with non-standard front and "minimalism". And there's no way that this isn't worse than the sanely sized Arial from JDK7 in readability. So I guess someone will have to take the JDK8 CSS and modify it.ddekany

3 Answers

6
votes

The css used in Java 7's Javadoc can be found here:

http://docs.oracle.com/javase/7/docs/api/stylesheet.css

You can then use the stylesheetfile attribute from the javadoc commandline, or ant or maven

from commandline:

%javadoc -stylesheetfile <path> ...

in ant:

<javadoc 
        ....
        stylesheetfile="/path/to/stylesheet.css"
        />      

in Maven (see Maven's stylesheet configuration page for more details ):

<reporting> (or <build>)
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        ...
        <configuration>
          <stylesheetfile>${basedir}/path/to/your/stylesheetfile.css</stylesheetfile>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </reporting> (or </build>) 

UPDATE

Stephen Colebourne has an article about other breaking changes to Javadoc in Java 8 here . Apparently, the doclint now enforces HTML 4 compliance and will not link if the link is broken or not 100% correct HTML 4. You can turn it off with -Xdoclint:none as an additional parameter.

<plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <configuration>
        <additionalparam>-Xdoclint:none</additionalparam>
      </configuration>
    </plugin>
 </plugins>

Regarding the <code> tags in parameter descriptions, I did see that too. It looks like the parameter descriptions in javadoc are now always monospace so you don't need code tags anymore?

1
votes

You could get the standard JDK 8 stylesheet.css and fix it very quickly, and then you can put that into some source folder and tell javadoc to use that with its stylesheetfile option. The problem with that is that there's no backward compatibility guarantee, the generated HTML changes quite a bit sometimes. That happened with JDK 7, and now with JDK 8. And then often you also have to consider that just because JDk 8 is out, some may will build your project with JDK 7...

Anyway, what I did was detecting if we are building under JDK 8 or later, and in that case I have applied regexp replacements on stylesheet.css, on build time. That was easy for me, as this old project uses Ant, not Maven. Just to see what the changes are, the relevant part is:

<target name="_fixJDK8JavadocCSS" depends="_rawJavadoc" if="atLeastJDK8">
  <property name="file" value="build/api/stylesheet.css" />
  <echo>Fixing JDK 8 CSS in ${file}</echo>

  <!-- Tell that it's modified: -->
  <replaceregexp
      file="${file}" flags="gs" encoding="utf-8"
      match="/\* (Javadoc style sheet) \*/" replace="/\* \1 - JDK 8 usability fix regexp substitutions applied \*/"
  />

  <!-- Remove broken link: -->
  <replaceregexp
      file="${file}" flags="gs" encoding="utf-8"
      match="@import url\('resources/fonts/dejavu.css'\);\s*" replace=""
  />

  <!-- Font family fixes: -->
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="['&quot;]DejaVu Sans['&quot;]" replace="Arial"
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="['&quot;]DejaVu Sans Mono['&quot;]" replace="'Courier New'"
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="['&quot;]DejaVu Serif['&quot;]" replace="Arial"
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="(?&lt;=[\s,:])serif\b" replace="sans-serif"
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="(?&lt;=[\s,:])Georgia,\s*" replace=""
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="['&quot;]Times New Roman['&quot;],\s*" replace=""
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="(?&lt;=[\s,:])Times,\s*" replace=""
  />
  <replaceregexp
      file="${file}" flags="gsi" encoding="utf-8"
      match="(?&lt;=[\s,:])Arial\s*,\s*Arial\b" replace="Arial"
  />

  <!-- "Parameters:", "Returns:", "Throws:", "Since:", "See also:" etc. fixes: -->
  <property name="ddSelectorStart" value="(?:\.contentContainer\s+\.(?:details|description)|\.serializedFormContainer)\s+dl\s+dd\b.*?\{[^\}]*\b" />
  <property name="ddPropertyEnd" value="\b.+?;" />
  <!-- - Put back description (dd) indentation: -->
  <replaceregexp
      file="${file}" flags="gs" encoding="utf-8"
      match="(${ddSelectorStart})margin${ddPropertyEnd}" replace="\1margin: 5px 0 10px 20px;"
  />
  <!-- - No monospace font for the description (dd) part: -->
  <replaceregexp
      file="${file}" flags="gs" encoding="utf-8"
      match="(${ddSelectorStart})font-family${ddPropertyEnd}" replace="\1"
  />
</target>

So the point is the regular expression above, that anyone can apply with ant, sed, Notepad++, etc (for non-Ant, don't forget to resolve the &...; and ${...} parts).

The reason I have used regexp is that I hope that it will be able to survive some changes in the HTML and thus in the standard CSS... but maybe I should just use the resulting CSS, I don't know. Or I should opt for using some 3rd party doclet, where thus I can control the used version.

1
votes

I use a style sheet to override some of the JDK8 CSS definitions, to make it look mostly like JDK7 Javadoc.

@import "stylesheetOrig.css";

body {
   font-family: Arial, Helvetica, sans-serif;
   font-size: 12px; }

pre {
   font-family: monospace;
   font-size: 12px; }

code, tt, dt code, table tr td dt code  {
   font-family: monospace;
   font-size: 12px; }

.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
   font-size: 13px; }

.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
   margin-left: 20px;
   font-size: 12px;
   font-family: inherit; }

div.block {
   font-size: 12px;
   font-family: inherit; }

h4 {
   font-size: 15px; }

.memberSummary caption {
   padding-top: 0; }

div.summary th {
   border: 1px solid #9eadc0; }
div.summary td {
   border-left: 1px solid #9eadc0;
   border-right: 1px solid #9eadc0; }
div.summary th.colFirst,
div.summary td.colFirst {
   border-right: none; }
div.summary th.colLast,
div.summary td.colLast {
   border-left: none; }
div.summary table {
   border-bottom: 1px solid #9eadc0;
   margin-bottom: 15px; }
div.summary ul.blockList ul.blockList ul.blockList {
   margin-top: 20px; }
ul.blockList ul.blockList li.blockList,
ul.blockList ul.blockList ul.blockList li.blockList,
ul.blockList ul.blockList ul.blockListLast li.blockList {
   border: 1px solid #9eadc0; }
div.summary ul.blockList ul.blockList ul.blockList li.blockList h3,
div.details ul.blockList ul.blockList ul.blockList li.blockList h4,
div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
   border-bottom: 1px solid #9eadc0; }

My Ant script renames the original stylesheet.css to stylesheetOrig.css and replaces it with the new version (which imports the original version):

<condition property="isJava8">
 <equals arg1="${ant.java.version}" arg2="1.8"/>
</condition>

<target name="-fixupJava8Javadoc" if="isJava8">
 <move file="target/apidocs/stylesheet.css" tofile="target/apidocs/stylesheetOrig.css"/>
 <copy file="src/doc/javadoc8OverrideStylesheet.css" tofile="target/apidocs/stylesheet.css"/>
</target>