ArchUnit icon indicating copy to clipboard operation
ArchUnit copied to clipboard

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

Open GeeJoe opened this issue 1 year ago • 7 comments

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?

GeeJoe avatar Apr 11 '24 09:04 GeeJoe

This information should be available via JavaClass's getSource() method:

[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.

hankem avatar Apr 11 '24 09:04 hankem

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.

GeeJoe avatar Apr 11 '24 10:04 GeeJoe

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

hankem avatar Apr 11 '24 10:04 hankem

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.

GeeJoe avatar Apr 11 '24 11:04 GeeJoe

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

  • file://$PROJECT_DIR/$MODULE_A/build/classes/java/main/com/….class for classes com.… inside module A of my project
  • jar:file:$PROJECT_DIR/$MODULE_B/build/libs/$MODULE_B.jar!/com/….class for classes com.… in another module B of the same project
  • jar:file:$GRADLE_CACHE/…/$LIBRARY.jar!/….class for classes in some external library

hankem avatar Apr 12 '24 06:04 hankem

@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/...?

codecholeric avatar Apr 12 '24 20:04 codecholeric

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.

GeeJoe avatar Apr 15 '24 03:04 GeeJoe