TNG / ArchUnit

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

How can I find out which gradle module a class belongs to #1289

Open GeeJoe opened 5 months ago

GeeJoe commented 5 months ago

I hope to scan out the dependencies between two modules, for example, a class in module A, and I want to scan out all the classes in Class A's dependencies that belong to module B. So I need to know whether a class belongs to module A or B. I have thought about distinguishing them by their package names, but in Android projects, two modules can have the same package name, so this method won't work. Are there any better ways?

hankem commented 5 months ago

This information should be available via [JavaClass's getSource() method](https://javadoc.io/doc/com.tngtech.archunit/archunit/latest/com/tngtech/archunit/core/domain/JavaClass.html#getSource()):

[Source] contains information about an imported class, i.e. the URI from where the class was imported and an md5 sum to compare different versions of the same class file at the same location.

GeeJoe commented 5 months ago

I don't quite understand what you mean, I can get the path of the imported class through JavaClass.getSource(), but I still don't know which module this class's source code belongs to.

For example, I have two classes, separately from two modules, and the package names of the two modules are both com.abc, then their getSource() returns something like this: file:///AndroidStudioProjects/example/build/xxx/com/abc/ClassA.class file:///AndroidStudioProjects/example/build/xxx/com/abc/ClassB.class

The URI prefix of the two classes is the same, so it's impossible to distinguish which module they belong to.

hankem commented 5 months ago

Oh! I thought that the example/build/xxx part would be different.

GeeJoe commented 5 months ago

Even if the prefixes are different, it's still impossible to know which module the class belongs to, because after being converted into bytecode, the information about module ownership is lost. I'm wondering if you have any other methods to meet my needs.

hankem commented 5 months ago

Just FYI: In my gradle multi-module project, Source::getUri gives me:

codecholeric commented 5 months ago

@GeeJoe I'm wondering, if you have two Gradle modules and one class in each, why would both end up in the same build output folder afterwards? That doesn't seem normal even for Android, no? I.e. in the example you're giving, what is AndroidStudioProjects/example? Is that the folder of the Gradle multi-module root? I would guess in a normal setup your class source should be something like AndroidStudioProjects/example/module1/build/... and AndroidStudioProjects/example/module2/build/...?

GeeJoe commented 5 months ago

The example I gave is from an Android project, and their URI prefixes may indeed be different. Some of their classes' URIs include the module, while others do not. Here are two examples

file:///Users/bd/AndroidStudioProjects/bd/Architect/vg/VC/build/intermediates/dexBuild_opt_prepare/VC:prodDebug/prepare_skip/SCOPE_SUB_PROJECT/scope_group_3/com/vg/adeditorapi/view/ScriptTabLayout.class file:///Users/bd/AndroidStudioProjects/bd/Architect/vg/VC/build/intermediates/transforms/ServiceMergeTransform/prod/debug/_modules_vega_base_template_draft/com/vg/draft/data/DataVersion.class

The second class contains module information, but the first class does not.