TNG / ArchUnit

A Java architecture test library, to specify and assert architecture rules in plain Java
http://archunit.org
Apache License 2.0
3.18k stars 288 forks source link

[BUG] Calling getEnclosingClass() on a nested class does provide a JavaClass with no members #1216

Open erikmaas-malmberg opened 9 months ago

erikmaas-malmberg commented 9 months ago

When calling the getEnclosingClass() on a nested class, the supplied class is the correct class, though it does not expose any of it's members. image

There is a workaround for this. Namely that you have to load in the class file manually. image

I've validated that these are the same classes.

With a small test setup, I could not reproduce this behavior. That made the test setup even stranger.

I'm using this functionality to create an ImportOption that filters out generated files (need to analyze the EnclosingClass for an annotation....)

hankem commented 9 months ago

I don't know what location in your new ClassFileImporter().importLocations(List.of(location)) is, but could it be that you're indeed only importing the nested class?

It's expected that ArchUnit, when dealing with missing classes that are referenced by imported classes, but not imported themselves, may create stub JavaClasses, which will have [isFullyImported()](https://www.javadoc.io/doc/com.tngtech.archunit/archunit/latest/com/tngtech/archunit/core/domain/JavaClass.html#isFullyImported())`==``false`.

Maybe you can Configure the resolution behavior according to your needs?

codecholeric commented 6 months ago

Did this help you @erikmaas-malmberg ?

erikmaas-malmberg commented 4 months ago

Sorry for the late answer. The reminder emails were filtered into the wrong folder in my mailbox....

The Class we are asking the enclosing class for is a class that lives inside the class. The locations is a complete folder. This means that the relevant classes should be loaded, and thus my idea that this is a bug.

The usecase for my to do this is:

public class A {
  // .....
  static class B {
    // ....
  }
}

As both classes A and B are generated, I do want to exclude them from certain tests. They are not in seperate packages. This to keep the code clean. The way I can identify those classes are with certain annotations on class A. This means that I need to check class A for this annotation while checking whether I need to check class B.

Because of this usecase I would assume that the encolosing class is on the classpath, and I have verified that it is inside the ClassFileImporter's locations.