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

classes().that().implement(SomeClass.class) breaks build #1377

Open
enver-haase opened this issue Nov 7, 2024 · 3 comments
Open

classes().that().implement(SomeClass.class) breaks build #1377

enver-haase opened this issue Nov 7, 2024 · 3 comments

Comments

@enver-haase
Copy link

My test is

@ArchTest
    private final ArchRule ddbItemNamesAreSound = classes().that().implement(DDBItem.class).should().haveNameMatching(".*Dto");

I changed DDBItem from being an interface to a class. Since then, I would

expect:
test fails with a sensible error message such as "DDBItem.class foes not denote an interface!"

but I get:
There was an error in the forked process

[ERROR] TestEngine with ID 'archunit' failed to discover tests
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] TestEngine with ID 'archunit' failed to discover tests
[ERROR] 	at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:628)

in more detail:

[ERROR] There was an error in the forked process
[ERROR] TestEngine with ID 'archunit' failed to discover tests
[ERROR] org.junit.platform.commons.JUnitException: TestEngine with ID 'archunit' failed to discover tests
[ERROR] 	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:160)
[ERROR] 	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
[ERROR] 	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
[ERROR] 	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
[ERROR] 	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:99)
[ERROR] 	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:77)
[ERROR] 	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
[ERROR] 	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
[ERROR] 	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
[ERROR] 	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
[ERROR] 	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:142)
[ERROR] 	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:122)
[ERROR] 	at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385)
[ERROR] 	at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
[ERROR] 	at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507)
[ERROR] 	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495)
[ERROR] Caused by: com.tngtech.archunit.junit.internal.ArchTestInitializationException: java.lang.reflect.InvocationTargetException
[ERROR] 	at com.tngtech.archunit.junit.internal.ReflectionUtils.getValueOrThrowException(ReflectionUtils.java:93)
[ERROR] 	at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor.getValue(ArchUnitTestDescriptor.java:119)
[ERROR] 	at com.tngtech.archunit.junit.internal.ArchUnitTestDescriptor.resolveChildren(ArchUnitTestDescriptor.java:114)
@codecholeric
Copy link
Collaborator

The reason for this is that ArchUnit considers it a "programmer error" to pass a class to that method when it expects an interface (this is also documented in the Javadoc, that an interface must be passed to the method or else an exception will be thrown).
That is because the class passed into the rules syntax is not assumed to be "a class under test", but part of the specification. And the specification should be constructed correctly. We don't consider constructing an invalid rule by passing an invalid argument to the syntax an "architecture violation", so it's not reported the same way.

@enver-haase
Copy link
Author

Sure, but is it necessary to break the build and swallow the reason? Without the -X argument to Maven it is truly hard to understand what is going on. One could of course question if it's good Surefire behaviour.

@codecholeric
Copy link
Collaborator

Yeah, I see your point, but for me that really is bad Surefire behavior. ArchUnit throws a clear exception giving the exact reason. That Maven / Surefire swallows it like this and makes it so hard to see the reason I don't consider a problem of ArchUnit. I had the same things also in other cases when running tests, it basically always happens if something goes wrong in the static context, Surefire always makes it extremely hard to see the real cause there. But that's nothing specific to ArchUnit in my opinion.

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

No branches or pull requests

2 participants