8 Replies Latest reply on Dec 6, 2013 2:01 AM by rp0428

    javax.tools provider for javadoc

    gajasutra

      When trying to use javax.tools.DocumentationTool in JDK8 builds, I had a null pointer exception.

      java.lang.NullPointerException at com.sun.tools.doclets.internal.toolkit.util.DocFile.createFileForOutput(DocFile.java:69)

       

      I think the reason is the following, given my context:

      1) I am using a custom class implementing JavaFileManager for providing Java sources files and trying to receive generated Javadoc.

      2) My instance of JavaFileManager is not an instance of StandardJavaFileManager (not File-based) nor of com.sun.tools.javac.nio.PathFileManager (non-public API).

      3) Then the method getting factory in com.sun.tools.doclets.internal.toolkit.util.DocFileFactory return null, causing the exception.

       

      Please see method: static synchronized DocFileFactory getFactory(Configuration configuration) {...}

      http://hg.openjdk.java.net/jdk8/tl/langtools/file/400a4e8accd3/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFileFactory.java

       

      Thanks,

      Gaja.

        • 1. Re: javax.tools provider for javadoc
          dadams07

          And your question? At least I assume there's a question hiding here somewhere, though you didn't post any code or error stack trace.

          • 2. Re: javax.tools provider for javadoc
            gajasutra

            Sorry, please choose your preferred question

            • Is the problem a bug in JDK8?
            • Does someone know what is the official way to generate javadoc from javax.tools (without using File-based API: i.e. only JavaFileManager not StandardJavaFileManager)? (documentation on the web is very scarce Javadoc API, JEP 106 or Jonathan Gibbons blog)

            NB: I have no problem to compile the same java code using similar calls to javax.tools.JavaCompiler.

             

            If you like a stack trace, here is:

            Note: Standard Doclet version 1.8.0-ea

            Note: Building tree for all the packages and classes...

            java.lang.NullPointerException

                at com.sun.tools.doclets.internal.toolkit.util.DocFile.createFileForOutput(DocFile.java:69)

                at com.sun.tools.doclets.formats.html.markup.HtmlWriter.<init>(HtmlWriter.java:183)

                at com.sun.tools.doclets.formats.html.markup.HtmlDocWriter.<init>(HtmlDocWriter.java:67)

                at com.sun.tools.doclets.formats.html.HtmlDocletWriter.<init>(HtmlDocletWriter.java:109)

                at com.sun.tools.doclets.formats.html.SubWriterHolderWriter.<init>(SubWriterHolderWriter.java:60)

                at com.sun.tools.doclets.formats.html.ClassWriterImpl.<init>(ClassWriterImpl.java:78)

                at com.sun.tools.doclets.formats.html.WriterFactoryImpl.getClassWriter(WriterFactoryImpl.java:93)

                at com.sun.tools.doclets.internal.toolkit.builders.BuilderFactory.getClassBuilder(BuilderFactory.java:143)

                at com.sun.tools.doclets.formats.html.HtmlDoclet.generateClassFiles(HtmlDoclet.java:194)

                at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.generateClassFiles(AbstractDoclet.java:205)

                at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.generateClassFiles(AbstractDoclet.java:189)

                at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.startGeneration(AbstractDoclet.java:137)

                at com.sun.tools.doclets.internal.toolkit.AbstractDoclet.start(AbstractDoclet.java:82)

                at com.sun.tools.doclets.formats.html.HtmlDoclet.start(HtmlDoclet.java:80)

                at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

                at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

                at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

                at java.lang.reflect.Method.invoke(Method.java:483)

                at com.sun.tools.javadoc.DocletInvoker.invoke(DocletInvoker.java:310)

                at com.sun.tools.javadoc.DocletInvoker.start(DocletInvoker.java:189)

                at com.sun.tools.javadoc.Start.parseAndExecute(Start.java:366)

                at com.sun.tools.javadoc.Start.begin(Start.java:219)

                at com.sun.tools.javadoc.Start.begin(Start.java:212)

                at com.sun.tools.javadoc.api.JavadocTaskImpl.call(JavadocTaskImpl.java:79)

                [... My code calling the javadoc rendering ...]

             

            Thank you very much.

            • 3. Re: javax.tools provider for javadoc
              gimbal2

              You realize that you're not talking to Oracle here right? Its just a user to user forum, so all you are going to get is guesswork if you ask questions about the implementation of a JDK that is still only in early access.

               

              Nonetheless I did a little research. I copy pasted "at com.sun.tools.doclets.internal.toolkit.util.DocFile.createFileForOutput" into google to see if someone else reported this somewhere before. No hits, but it does return this link with the source code of DocFile:


              New src/share/classes/com/sun/tools/doclets/internal/toolkit/util/DocFile.java

               

              Now when I look at that @since tag mentioning version 8, I conclude that this class was added in Java 8 and so this being a new bug is actually kind of likely.

              • 4. Re: javax.tools provider for javadoc
                rp0428

                I've never understood why people will go to great lengths to post a problem that their own code is giving them but then won't post the code that causes the problem so that someone can try to help them.

                 


                • 5. Re: javax.tools provider for javadoc
                  gajasutra

                  Because posting code which is only executing a task is fully unuseful, cf.

                  at com.sun.tools.javadoc.api.JavadocTaskImpl.call(JavadocTaskImpl.java:79)

                   

                  NB: I will post my problem as a bug to Oracle, given nobody seems to have already seen this problem.

                  • 6. Re: javax.tools provider for javadoc
                    rp0428
                    Because posting code which is only executing a task is fully unuseful, cf.

                    at com.sun.tools.javadoc.api.JavadocTaskImpl.call(JavadocTaskImpl.java:79)

                     

                    NB: I will post my problem as a bug to Oracle, given nobody seems to have already seen this problem.

                    We're trying to help you.

                     

                    It may be 'unuseful' to you because you already know what it is. But it is SOMETHING in your code or your system that is driving the issue. Java code only executes when you call it and it is YOUR code that is calling it.

                     

                    We have NO way of knowing what that call in your code looks like. We also have NO way of knowing if the method you pointed to is what is really causing the exception:

                    3) Then the method getting factory in com.sun.tools.doclets.internal.toolkit.util.DocFileFactory return null, causing the exception.

                    There is NO mention of that class in the stack trace so how do you know that it is causing the exception?

                     

                    What I see in the trace is this:

                        at com.sun.tools.doclets.internal.toolkit.util.DocFile.createFileForOutput(DocFile.java:69)

                    And if you go to the source code that gimbal2 referenced you find this:

                      67     /** Create a DocFile for a file that will be opened for writing. */

                      68     public static DocFile createFileForOutput(Configuration configuration, DocPath path) {

                      69         return DocFileFactory.getFactory(configuration).createFileForOutput(path);

                      70     }

                    The stack trace references line 69 and that means the exception could be from ANYTHING on that line.

                      69         return DocFileFactory.getFactory(configuration).createFileForOutput(path);

                    Since that line has multiple statements either statement could be the problem. It could be the getFactory(configuration)  method returning NULL as you mention or it could be the 'createFileForOutput(path)' method.

                     

                    Without seeing your code we have NO idea what values are being passed for 'configuration' or 'path' so we can't tell what code path will be taken in those methods.

                           57         DocFileFactory f = factories.get(configuration);

                           58         if (f == null) {

                           59             JavaFileManager fm = configuration.getFileManager();

                           60             if (fm instanceof StandardJavaFileManager)

                           61                 f = new StandardDocFileFactory(configuration);

                           62             else {

                           63                 try {

                           64                     Class<?> pathFileManagerClass =

                           65                             Class.forName("com.sun.tools.javac.nio.PathFileManager");

                           66                     if (pathFileManagerClass.isAssignableFrom(fm.getClass()))

                           67                         f = new PathDocFileFactory(configuration);

                           68                 } catch (Throwable t) {

                           69                     throw new IllegalStateException(t);

                           70                 }

                           71             }

                           72         }

                           73         return f;

                           74     }

                    What is being passed for 'configuration'? If it is null then this line will probably raise that exception:

                    JavaFileManager fm = configuration.getFilemanager();

                    If it isn't null then this line will exceed or fail

                    DocFileFactory f = factories.get(configuration);

                    But if that succeeds 'f' is returned and this method doesn't cause a NULL exception. If it fails then the inner code is executed.

                     

                    That code is what is doing this

                    if (fm instanceof StandardJavaFileManager)

                    That is the class you mention in your thread but nothing from this code is in the stack trace.

                     

                    That leaves the 'path' parameter as the cause of the exception:

                    createFileForOutput(path);

                    We have no idea what value, if any, is being used for 'path'. What is the value of 'path'?

                     

                    You said you weren't using a file so maybe 'path' is null.

                     

                    That is why we asked to see your code.

                     

                    Good luck with your problem.

                    • 7. Re: javax.tools provider for javadoc
                      jschellSomeoneStoleMyAlias

                      > The stack trace references line 69 and that means the exception could be from ANYTHING on that line.

                       

                      Not really.

                       

                      Some basic assumptions.  Presumably the VM version used by the OP is the same as what you analyzed, so your line 69 is the same.  And createFileForOutput() is not a native method.

                       

                      Given that then the only possible source is that getFactory() returned null

                      • 8. Re: javax.tools provider for javadoc
                        rp0428
                        Not really.

                        Whynot?

                        createFileForOutput(path);

                        What can't this method be causing the NPE? You said it isn't a 'native' method but I have no idea what you mean by that.

                         

                        Some basic assumptions.  Presumably the VM version used by the OP is the same as what you analyzed, so your line 69 is the same.

                        I didn't analyze anything except the code at the links that were posted.

                         

                        Given that then the only possible source is that getFactory() returned null

                        It may have. But that still could be because of the 'configuration' parameter value being passed.

                         

                        In any case the warning at the start of the linked code pretty much sums up the issue for me:

                               41  *  <p><b>This is NOT part of any supported API.

                               42  *  If you write code that depends on this, you do so at your own risk.

                               43  *  This code and its internal interfaces are subject to change or

                               44  *  deletion without notice.</b>