-1

I have faced some difficulties with Java parsing. I need somehow to get comments of class, fields, methods etc. via reflection.

I have found JavaParser and it looks like it can elicit comments but I haven't got how to do it as all the examples just parse given string. I have found TypeSolver that can take Canonical name but it looks like that it can't work with comments.

My question is how to find comments if I have only Class<?> and also the project has some other jar's that should also be introspected. Via debugging I see the original source code and it looks like that it is possible to do somehow.
Thanks.

P.S. I have source code, I need to match Class<?> with source code and then extract comments via JavaParser

aspirisen
  • 965
  • 13
  • 29
  • 2
    AFAIK comments get removed when compiling, so resulting class files don't have them – BackSlash Mar 13 '18 at 14:55
  • Yes, but I have source code, i need to match class with it's source code – aspirisen Mar 13 '18 at 15:20
  • I have reopened this question, it is *not* a duplicate of https://stackoverflow.com/questions/8504013/how-to-read-javadoc-comments-by-reflection. The OP has the source code, they are not asking the impossible. – lexicore Apr 23 '18 at 18:11

4 Answers4

5

First of all, you cannot directly get comments using reflection, and you cannot get them by using a library that reads the ".class" file. The information is not present the ".class" file, and reflection only knows about information is directly available from there.

As people have pointed out, you can only get comments if you have the source code. And if you have a source code file you should be able to extract comments using JavaParser or (possibly) some other library, ... or by writing your own parser.

The problem will be mapping from a Class object to the corresponding source code file. Let us assume that you have multiple source trees corresponding to multiple JARs on the application's classpath. You will need:

  • the URIs for each JAR or directory on the classpath,
  • a mapping from each URI to a corresponding source tree.

The approach would be:

  1. Get the fully qualified class name from the Class object.
  2. Map the classname to a relative Java source path; e.g. foo.bar.Baz would become foo/bar/Baz.java
  3. Use clazz.getProtectionDomain().getCodeSource().getLocation().toURI() to get the URI from whence the class was loaded.
  4. Map the URI to the corresponding source tree ... using your mappings.
  5. Resolve the relative path relative to the root of the source tree.
  6. Open the source file.

Some of the above steps could present problems. For example:

  • in step 2, you need to deal with nested classes,
  • in step 3, getCodeSource() could return null,
  • in step 3, the resulting URI could have a weird protocol,
  • if your mapping are incomplete, step 4 could fail,
  • if your source code doesn't match the code you are executing, step 5 could fail.

Once you have the source file open, you construct a Reader and parse the source code ... using your chosen Java parser.


If yours was a "green field" project, it may be simpler to define a custom annotation type (with retention runtime) and turn your comments into annotations. These annotations can be extracted simply and quickly, with none of the possible failure modes in the above.

But the flipside is that annotations are cumbersome to write (in the source code) compared to comments. Also, you would be bloating the ".class" files with the extra annotations.


I haven't got how to do it as all the [JavaParser] examples just parse given string.

The javadoc shows that you can use a JavaParser instance to parse a File, an InputStream, a Reader or a String.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

If you have the source code, it is probably in form of a JAR file. It is quite easy to locate the source file in the JAR file as the class provides both the package as well as local name. You have to consider a case with nested classes, but its is actually quite easy to implement.

When you've located the source file, you can easily parse it with JavaParser and retrieve the comments:

    String classText = "public class Dummy{\n" + "//Comment\n" + "}";
    StringReader reader = new StringReader(classText);
    CompilationUnit compilationUnit = JavaParser.parse(reader, true);

    for (Comment comment : compilationUnit.getAllContainedComments()) {
        System.out.println(comment.getContent());
    }
lexicore
  • 42,748
  • 17
  • 132
  • 221
1

I doubt that comments are contained in compiled code - so there is no way to do it by reflection. Closest tool to do it would be XDoclet-1/2 which parsed javadoc tags and used them to generate other stuff (and this inspired annotations) - but this tool is obsolete and not suppported anymore

Konstantin Pribluda
  • 12,329
  • 1
  • 30
  • 35
0

You can't.

Bytecode does not contain any comments, either inline or in JavaDoc format, from the original source code, as they are removed during the compilation phase.

If you need the comments to somehow be transferred into the Bytecode, consider using Java's Annotations instead.

Community
  • 1
  • 1
Lefteris008
  • 899
  • 3
  • 10
  • 29
  • I have source code, I need to match source code and class – aspirisen Mar 13 '18 at 15:23
  • So, you actually have the compiled binaries and separately the source code of them and somehow need to "attach" the source code on the binaries? – Lefteris008 Mar 13 '18 at 15:41
  • yes, I need it in Maven plugin and I have source code – aspirisen Mar 13 '18 at 15:46
  • 1
    If *you* are the author of the code, then you can compile the files with the `source` flag enabled. You can then attach the produced `.jar` as external sources on top of the project. The same applies also if you had a separate JavaDoc file. – Lefteris008 Mar 14 '18 at 07:51