QDox
  1. QDox
  2. QDOX-40

Infinite recurssion while resolving implemented interfaces of inner classes

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Cannot Reproduce
    • Affects Version/s: 1.4
    • Fix Version/s: 1.4
    • Component/s: Java API
    • Labels:
      None
    • Environment:
      Any
    • Number of attachments :
      2

      Description

      Infinite recursion is possible, if nested class implements interface
      like this:

      class WrappedInternalContextAdapter implements InternalContextAdapter {
      }
      ( happens in webwork velocity directives )

      Bug is in method public String resolveType(String typeName) of JavaClass. ( Inner classes loop )

      --%<------
      if (innerName.endsWith(typeName)) {
      --%<------

      Shall be :
      --%<--------
      if (innerName.endsWith("$" + typeName)) {
      --%<------

      Maybe mroe elegant solution is possible....

      ( Line number omitted, because I spiced everything with log statements to track this... )

      Merry XMass

      1. InfobitDirective.java
        12 kB
        Konstantin Pribluda
      2. test.diff
        0.7 kB
        Konstantin Pribluda

        Activity

        Aslak Hellesøy made changes -
        Field Original Value New Value
        Assignee Aslak Hellesoy [ rinkrank ]
        Hide
        Aslak Hellesøy added a comment -

        Hi Konstantin,

        I can't find (or figure out) the source code required to reproduce the bug. The best would be to have a minimal sample source code + some QDox API calls to make it apparent.

        I could of course modify line 213 in JavaClass and add the dollar, but I'd really prefer to have a failing testcase to illustrate why this modification is needed.

        Could you provide a (failing) test case that looks something like the following?

        public void testJiraQdox40() {
        String sourceCode = ""
        + "package foo;\n"
        + "public class WrappedInternalContextAdapter implements InternalContextAdapter

        {\n" + "// Maybe some more code needed?"; + "}

        ";
        JavaDocBuilder builder = new JavaDocBuilder();
        builder.addSource(new StringReader(sourceCode));
        JavaClass aClass =
        builder.getClassByName("foo.WrappedInternalContextAdapter ");
        // Perhaps this is what causes the infinite recursion? That's ok. A failing test gives us a clue...
        assertNotNull(aClass);
        }

        It's really simple to write (failing) unit tests for QDox. Try it out See QDox' JavaDocBuilderTest for inspiration.

        Cheers,
        Aslak

        Show
        Aslak Hellesøy added a comment - Hi Konstantin, I can't find (or figure out) the source code required to reproduce the bug. The best would be to have a minimal sample source code + some QDox API calls to make it apparent. I could of course modify line 213 in JavaClass and add the dollar, but I'd really prefer to have a failing testcase to illustrate why this modification is needed. Could you provide a (failing) test case that looks something like the following? public void testJiraQdox40() { String sourceCode = "" + "package foo;\n" + "public class WrappedInternalContextAdapter implements InternalContextAdapter {\n" + "// Maybe some more code needed?"; + "} "; JavaDocBuilder builder = new JavaDocBuilder(); builder.addSource(new StringReader(sourceCode)); JavaClass aClass = builder.getClassByName("foo.WrappedInternalContextAdapter "); // Perhaps this is what causes the infinite recursion? That's ok. A failing test gives us a clue... assertNotNull(aClass); } It's really simple to write (failing) unit tests for QDox. Try it out See QDox' JavaDocBuilderTest for inspiration. Cheers, Aslak
        Hide
        Konstantin Pribluda added a comment -

        diff to test case to demonstrate this bug.

        Show
        Konstantin Pribluda added a comment - diff to test case to demonstrate this bug.
        Konstantin Pribluda made changes -
        Attachment test.diff [ 11189 ]
        Hide
        Konstantin Pribluda added a comment -

        there is no assert, because this infinite recursion produces segv...

        With "$" + everything works fine.

        Show
        Konstantin Pribluda added a comment - there is no assert, because this infinite recursion produces segv... With "$" + everything works fine.
        Hide
        Aslak Hellesøy added a comment -

        I'm unable to reproduce the claimed infinite recursion with this testcase. I ran your supplied test against QDox' CVS HEAD, and it passes.

        Some questions:

        1) What do you mean by "this infinite recursion produces segv..."?

        2) Am I correct if I'm assuming that you are getting a java.lang.StackOverflowError?

        3) Can you verify that your test fails against CVS HEAD? (I can't make it fail).

        4) Can you attach a stack trace here?

        Show
        Aslak Hellesøy added a comment - I'm unable to reproduce the claimed infinite recursion with this testcase. I ran your supplied test against QDox' CVS HEAD, and it passes. Some questions: 1) What do you mean by "this infinite recursion produces segv..."? 2) Am I correct if I'm assuming that you are getting a java.lang.StackOverflowError? 3) Can you verify that your test fails against CVS HEAD? (I can't make it fail). 4) Can you attach a stack trace here?
        Hide
        Konstantin Pribluda added a comment -

        I did a clean checkout , and it failed.

        1) What do you mean by "this infinite recursion produces segv..."?

        It goes into infinite recursion. I'm able to see it through my logging statements.

        2) Am I correct if I'm assuming that you are getting a java.lang.StackOverflowError?

        From maven side I get segv ( on linux ) - your mileage may vary...
        But real cause should be stack overflow...

        4) Can you attach a stack trace here?
        unfortunately no... Thereis also no error report from junit - it's just empty...

        Maybe we are out of synch due to some snapshot dependecies you compiled yourself?

        Anyway, in resolveType() when you check inner classes, you shall take into account unqualified name of inner class ( which starts from last $ ) , and not just endsWith() - or you will resolve
        InternalVelocityContext as foo.bar.baz.Blurge$WrappedInternalVelocityContext - which is not desired behaviour...

        I'm ataching real world example which bite my ass off...

        Show
        Konstantin Pribluda added a comment - I did a clean checkout , and it failed. 1) What do you mean by "this infinite recursion produces segv..."? It goes into infinite recursion. I'm able to see it through my logging statements. 2) Am I correct if I'm assuming that you are getting a java.lang.StackOverflowError? From maven side I get segv ( on linux ) - your mileage may vary... But real cause should be stack overflow... 4) Can you attach a stack trace here? unfortunately no... Thereis also no error report from junit - it's just empty... Maybe we are out of synch due to some snapshot dependecies you compiled yourself? Anyway, in resolveType() when you check inner classes, you shall take into account unqualified name of inner class ( which starts from last $ ) , and not just endsWith() - or you will resolve InternalVelocityContext as foo.bar.baz.Blurge$WrappedInternalVelocityContext - which is not desired behaviour... I'm ataching real world example which bite my ass off...
        Hide
        Konstantin Pribluda added a comment -

        real world example

        Show
        Konstantin Pribluda added a comment - real world example
        Konstantin Pribluda made changes -
        Attachment InfobitDirective.java [ 11194 ]
        Hide
        Aslak Hellesøy added a comment -

        I'm still unable to make the test fail. Both with the patch and the attached source code. Anyway, I have applied the code change, as it still makes all tests pass. (And it seems correct).

        Show
        Aslak Hellesøy added a comment - I'm still unable to make the test fail. Both with the patch and the attached source code. Anyway, I have applied the code change, as it still makes all tests pass. (And it seems correct).
        Aslak Hellesøy made changes -
        Fix Version/s 1.4 [ 10304 ]
        Resolution Cannot Reproduce [ 5 ]
        Status Open [ 1 ] Closed [ 6 ]
        Hide
        Konstantin Pribluda added a comment -

        Well this also could be some weird transient error. If class was resolved beforehand, it does not happen.

        But you commented out a line you added...

        Show
        Konstantin Pribluda added a comment - Well this also could be some weird transient error. If class was resolved beforehand, it does not happen. But you commented out a line you added...

          People

          • Assignee:
            Aslak Hellesøy
            Reporter:
            Konstantin Pribluda
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: