Skip to content

Allow package info classes to be resolved as a dependency#1565

Open
wakingrufus wants to merge 1 commit intoTNG:mainfrom
wakingrufus:dependency-package-info
Open

Allow package info classes to be resolved as a dependency#1565
wakingrufus wants to merge 1 commit intoTNG:mainfrom
wakingrufus:dependency-package-info

Conversation

@wakingrufus
Copy link
Copy Markdown

@wakingrufus wakingrufus commented Dec 10, 2025

Allow package info classes to be resolved as a dependency
exclude package-info classes from package metrics calculations

Resolves #1564

@wakingrufus wakingrufus force-pushed the dependency-package-info branch 7 times, most recently from 6da5209 to 43288eb Compare December 11, 2025 23:23
@wakingrufus wakingrufus marked this pull request as ready for review December 11, 2025 23:23
@wakingrufus wakingrufus changed the title failing tests to reproduce #1564 Allow package info classes to be resolved as a dependency Dec 11, 2025
@wakingrufus wakingrufus force-pushed the dependency-package-info branch from 43288eb to 070d20f Compare December 12, 2025 15:41
@wakingrufus
Copy link
Copy Markdown
Author

I updated this PR to exclude the package-info classes when calculating package metrics. this fixes the failing tests

@wakingrufus wakingrufus force-pushed the dependency-package-info branch from 070d20f to 81cfe2d Compare December 12, 2025 15:57
@wakingrufus
Copy link
Copy Markdown
Author

Happy New Year @codecholeric and @hankem !
Just a gentle reminder that I would appreciate if this PR could be looked at.
Thanks again!

@wakingrufus
Copy link
Copy Markdown
Author

Hi again @codecholeric and @hankem. I know I have a few PRs open at the moment, but this one is quite important. I would really appreciate of someone could take a look at this please.

wakingrufus added a commit to nebula-plugins/nebula-archrules-plugin that referenced this pull request Feb 19, 2026
… class dependency when scanning

since TNG/ArchUnit#1565 has not been merged in a timely manner, we need a custom implementation on our end to fix this issue until it is finally merged.
@wakingrufus wakingrufus force-pushed the dependency-package-info branch from ab61e25 to 63c579b Compare February 19, 2026 17:33
wakingrufus added a commit to nebula-plugins/nebula-archrules-plugin that referenced this pull request Feb 19, 2026
… class dependency when scanning

since TNG/ArchUnit#1565 has not been merged in a timely manner, we need a custom implementation on our end to fix this issue until it is finally merged.
wakingrufus added a commit to nebula-plugins/nebula-archrules-plugin that referenced this pull request Feb 19, 2026
… class dependency when scanning

since TNG/ArchUnit#1565 has not been merged in a timely manner, we need a custom implementation on our end to fix this issue until it is finally merged.
wakingrufus added a commit to nebula-plugins/nebula-archrules-plugin that referenced this pull request Feb 19, 2026
… class dependency when scanning

since TNG/ArchUnit#1565 has not been merged in a timely manner, we need a custom implementation on our end to fix this issue until it is finally merged.
fix for TNG#1564
exclude package-info classes from package metrics calculations

Signed-off-by: John Burns <wakingrufus@gmail.com>
@wakingrufus wakingrufus force-pushed the dependency-package-info branch from 63c579b to 3b8fda6 Compare April 21, 2026 14:41
@hankem
Copy link
Copy Markdown
Member

hankem commented Apr 22, 2026

I'm very sorry for the late response! I'll try to find more time. 🤞

@wakingrufus
Copy link
Copy Markdown
Author

I'm very sorry for the late response! I'll try to find more time. 🤞

No problem, Thanks!

Copy link
Copy Markdown

@StefanGraeber StefanGraeber left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike that the package-info is now included in JavaPackage.getClasses() (even as stub if it doesn't exist, which might be a breaking change for some use cases) and don't understand whether or how all classes in the package are retained when recreating the package in the JavaClass class.
IMO it also is the wrong location for the logic of resolving package info.

Can you explain in more detail which problem you want to solve?
To my understanding, the issue seems to be, that the package-infois not always resolved when you expect it to be loaded, but I'm not sure whether that's limited to loading single classes vianew ClassFileImporter()or whether this also affects the "normal" execution with@AnalyzeClasses` annotation

}

@Test
public void function_getPackageInfo() {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at the previous tests in this class, I would expect that a test with this name would test
JavaClass.Functions.GET_PACKAGE_INFO, which doesn't exist.
This test doesn't fit the pattern of the other tests.
I'm not sure whether we would want to have that function, as I'm not sure what I should return apart from the package itself

@@ -0,0 +1,7 @@
package com.tngtech.archunit.core.importer.testexamples.packageinforesolution;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this new package name.
is it important that it is subpackage of the package in which OtherClass is defined or shall just be any other package?

}

void completePackageInfoFrom(ImportContext context) {
this.javaPackage = JavaPackage.from(Arrays.asList(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the class resolution yet, but this looks to me as if the package is re-created with just the current class and the package-info class.
If you look e.g. at the package testexamples, you have these classes (and more):

  • SomeClass
  • OtherClass
  • package-info

assuming we are now in the JavaClass representing SomeClass, I expect that getPackage().getClasses() contains all three of these classes, but I don't see how it could return anything else then Set.of(SomeClass, package-info), as this statement replaces the package and just passes these 2 classes into the new factory.
I don't see any call in JavaPackage.from checking the package of the class, which could contain the information.

It is also not clear to me how the dependencies and subpackages are build if all the other classes in teh package are missing.

Wouldn't it be much cleaner if we could resolve the package-info class when initially building the JavaPackage?
Why should each JavaClass in that package be responsible for resolving the package-info?

JavaClass otherClass = new ClassFileImporter()
.importClass(OtherClass.class);

JavaPackage checkedClassPackageInfo = otherClass.getPackage();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JavaPackage has the methods tryGetPackageInfo and getPackageInfo.
please include in the test they work as well.
as one calls the other, I would prefer to tests sth like assertThat(checkedClassPackageInfo.getPackageInfo()).isPresent(), even thought this is kind of redundant with the getAnnotations method which also relies on that field.

JavaPackage checkedClassPackageInfo = otherClass.getPackage();
assertThat(checkedClassPackageInfo.getAnnotations()).hasSize(1);
assertThat(checkedClassPackageInfo.isAnnotatedWith(SomeAnnotation.class)).isTrue();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When running checkedClassPackageInfo.getClasses(), this set now includes the package-info, which it didn't before.
I don't think that that class should be included in that Set as it is not a real class and shall instead be accessed via JavaPackage.getPackageInfo() which returns the JavaClass representing package-info as HasAnnotations. This change in type seems deliberate to me as this special class doesn't have all features of a JavaClass.

@StefanGraeber
Copy link
Copy Markdown

I can't really localize the issue (and it might be a me-problem), but using windows 11 and IntelliJ, incremental builds fail with this error

> Task :archunit:compileJdk9mainJava FAILED
repopath\ArchUnit\archunit\src\jdk9main\java\com\tngtech\archunit\core\domain\Java9DomainPlugin.java:30: error: cannot access AnnotationPropertiesFormatter
                        .formatProperties(config -> config
                        ^
  class file for com.tngtech.archunit.core.domain.AnnotationFormatter$AnnotationPropertiesFormatter not found
1 error

as soon as I include your changes in JavaClass.
I can't reproduce the issue with adding some random new method in that class

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

package-info should be resolvable through DependencyResolutionProcess

3 participants