Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassGraphFacade fails for inner classes #353

Closed
peter721 opened this issue Apr 16, 2019 · 4 comments
Closed

ClassGraphFacade fails for inner classes #353

peter721 opened this issue Apr 16, 2019 · 4 comments
Labels
Milestone

Comments

@peter721
Copy link

Class.getCanonicalName() and Class.getName() generally return the same thing - except for inner classes. ClassGraph will find inner classes based on their "name", so the code in "searchForPublicConcreteSubTypesOf" will fail when string-matching the canonicalName.

@fmbenhassine
Copy link
Member

Do you have a failing test?

If I understand correctly, you mean we need to use type.getName() instead of type.getCanonicalName() here: https://github.com/j-easy/easy-random/blob/master/easy-random-core/src/main/java/org/jeasy/random/util/ClassGraphFacade.java#L56

Is that correct?

@fmbenhassine
Copy link
Member

fmbenhassine commented Apr 28, 2019

Hi @peter721 ,

so the code in "searchForPublicConcreteSubTypesOf" will fail when string-matching the canonicalName.

I'm not able to reproduce the issue (unless I misunderstand it). Here is a passing test with version 4.0.0.RC1:

package org.jeasy.random;

public interface IBar {
}
package org.jeasy.random;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class Foo {

    private IBar bar;

    public IBar getBar() {
        return bar;
    }

    public class Bar implements IBar {

    }

    @Test
    void testScanClasspathForConcreteTypes_whenConcreteTypeIsAnInnerClass() {
        EasyRandomParameters parameters = new EasyRandomParameters()
                .scanClasspathForConcreteTypes(true);
        EasyRandom easyRandom = new EasyRandom(parameters);

        Foo foo = easyRandom.nextObject(Foo.class);

        Assertions.assertThat(foo).isNotNull();
        Assertions.assertThat(foo.getBar()).isInstanceOf(Bar.class);
    }
}

In this example, Foo.Bar.class.getName() = org.jeasy.random.Foo$Bar and Foo.Bar.class.getCanonicalName() = org.jeasy.random.Foo.Bar, and still ClassGraph is able to find the concrete type Bar by its canonical name even if it is an inner class.

Do you agree?

@peter721
Copy link
Author

Hi, thanks for the reply!

The ClassGraphFacade.searchForPublicConcreteSubTypesOf() method must be called with an inner type to illustrate the problem. The following code does fail:

public class Foo {

  public abstract class Bar {}

  public class Bar2 extends Bar {}

  public class Baz {
    private Bar bar;

    public Bar getBar() {
      return bar;
    }
  }

  @Test
  void testScanClasspathForConcreteTypes_whenConcreteTypeIsAnInnerClass() {
    EasyRandomParameters parameters =
        new EasyRandomParameters().scanClasspathForConcreteTypes(true);
    EasyRandom easyRandom = new EasyRandom(parameters);

    Foo.Baz baz = easyRandom.nextObject(Foo.Baz.class);

    Assertions.assertThat(baz).isNotNull();
    Assertions.assertThat(baz.getBar()).isNotNull();
  }
}

fmbenhassine added a commit that referenced this issue May 2, 2019
Before this commit, searching for a matching type by canonical
name does not return concrete inner types.

This commit uses the type's name (instead of its canonical name)
to look for concrete types in the classpath.

Resolves issue #353
@fmbenhassine
Copy link
Member

Thank you for the clarification. The issue happens when both the abstract type and the concrete one are inner classes. I fixed the issue by using the type name instead of its canonical name.

The fix will be part of the upcoming 4.0.0 release. Stay tuned.

Thank you for reporting this issue just in time 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants