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 288 forks source link

FreezingArchRule breaks when executed from IDE and maven #923

Closed mustaphazorgati closed 2 years ago

mustaphazorgati commented 2 years ago

Environment:

Expected behavior: When the store files are generated, the tests should all pass independent of the test execution (here: IntelliJ or maven)

Actual behavior:

How to reproduce:

As of right now we've disabled the tests, since this behavior is blocking us. You can find our test class here: https://github.com/Taskana/taskana/blob/master/lib/taskana-core-test/src/test/java/acceptance/ArchitectureTest.java The tests packagesShouldBeFreeOfCyclicDependencies and classesShouldBeFreeOfCyclicDependencies will fail. We've already set the following properties to an unreasonable high amount in order to make sure that all errors are detected.

cycles.maxNumberToDetect=100000
cycles.maxNumberOfDependenciesPerEdge=10000

During our initial debugging we've found out that the line numbers differ between the execution through maven and IntelliJ. Furthermore we've seen that IntelliJ and maven name lambda's differently, which is a second difference in the store files.

Screenshot from 2022-07-18 16-18-53 Screenshot from 2022-07-18 16-18-30

codecholeric commented 2 years ago

Thanks for raising the issue! First, about the lambda parameter, can you please try version 1.0.0-rc1? Because these dependencies should be correctly dereferenced then and methods like lambda$xxx$123 should vanish...

Other than that typically this is a mismatch in classpath between the build tool and the IDE. But in this case I'm a little puzzled, because you describe that the line numbers are different? :thinking: Because that should not really be affected by the tool... Have you checked which line numbers actually make sense? I would guess only one version can report the correct line numbers then, right? Independently of that, even if the line numbers would change, this wouldn't lead the rule to fail, because FreezingArchRule should ignore changed line numbers (as that is a common case for frozen violations, that they are not really fixed, but just "moved around" within the file)

I can look into it a little more, my only problem is that I tried to check out that branch from your notes, but I can't even compile the project :thinking:

./mvnw clean compile

...

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] warnings found and -Werror specified
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for pro.taskana:taskana-parent 5.2.2-SNAPSHOT:
[INFO] 
[INFO] pro.taskana:taskana-parent ......................... SUCCESS [  0.246 s]
[INFO] pro.taskana:taskana-common-parent .................. SUCCESS [  0.008 s]
[INFO] pro.taskana:taskana-common-logging ................. FAILURE [  0.430 s]
[INFO] pro.taskana:taskana-common-security ................ SKIPPED
...

The bizarre thing is that it doesn't even give me any details about what the error is. Do you have any hint what I have to do to get it to compile and why there are no error details in the Maven output? (I tried -e and -X, but it also didn't give me any further insights)

codecholeric commented 2 years ago

Nevermind, of course wrong Java version :man_facepalming: I thought it was set to 11, but it was actually set to 17. Still, would have been nice to get some other error details from Maven than just an empty message :zany_face: Anyway, I'll try to look into it as soon as I find some time!

mustaphazorgati commented 2 years ago

Nevermind, of course wrong Java version man_facepalming I thought it was set to 11, but it was actually set to 17. Still, would have been nice to get some other error details from Maven than just an empty message zany_face

Yeah. Maven is sometimes funny and doesn't describe the error properly.

Anyway, I'll try to look into it as soon as I find some time!

Thank you very much! Can I assist you somehow? If so, then please let me know. I'll check out version 1.0.0-rc1 and see if that helps :)

codecholeric commented 2 years ago

Yes, checking out the difference if you use 1.0.0-rc1 would definitely be helpful :slightly_smiling_face:

mustaphazorgati commented 2 years ago

I've just updated the branch and did some testing. Now the behavior is a little different. Unfortunately the tests still fail when the store files are generated through different ways (maven / IntelliJ). What I have observed: Now the delta contains only deletions. When the store files were generated through IntelliJ the execution through maven will delete some frozen violations and throw those violations as errors thus the test execution fails. This is the same observation when the store files are generated through maven and afterwards executed through IntelliJ.

codecholeric commented 2 years ago

I finally found some time to look into it, this is how it looked to me:

1) When I use 1.0.0-rc1 and delete the existing ViolationStore, then when I create a new store with IntelliJ Maven is afterwards also green and the store unchanged. And vice versa, if I create the store with Maven and then run the test with IntelliJ it's green and the store unchanged. 2) When I run 1.0.0-rc1 against the checked in ViolationStore, then it removes a couple of violations and reports them as new. I also noticed that for the checked in ViolationStore the lines of the violations don't seem to always be lexicographically ordered :thinking: I don't know how this would happen. Originally the ordering of the SliceRule was somewhat random, which made it hard to use with FreezingArchRule. But for that reason we have improved it over time and AFAIS the ordering was improved before the new format with indentation was introduced (which the checked in ViolationStore already uses). E.g.

2. Dependencies of Slice testapi.extensions\
    - Method <pro.taskana.testapi.extensions.TestContainerExtension.interceptTestClassConstructor(org.junit.jupiter.api.extension.InvocationInterceptor$Invocation, org.junit.jupiter.api.extension.ReflectiveInvocationContext, org.junit.jupiter.api.extension.ExtensionContext)> references class object <pro.taskana.testapi.CleanTaskanaContext> in (TestContainerExtension.java:41)\
    - Method <pro.taskana.testapi.extensions.TaskanaDependencyInjectionExtension.postProcessTestInstance(java.lang.Object, org.junit.jupiter.api.extension.ExtensionContext)> references class object <pro.taskana.testapi.TaskanaInject> in (TaskanaDependencyInjectionExtension.java:44)\
    - Method <pro.taskana.testapi.extensions.TestContainerExtension.interceptTestClassConstructor(org.junit.jupiter.api.extension.InvocationInterceptor$Invocation, org.junit.jupiter.api.extension.ReflectiveInvocationContext, org.junit.jupiter.api.extension.ExtensionContext)> calls method <pro.taskana.testapi.DockerContainerCreator.createDockerContainer(pro.taskana.common.internal.configuration.DB)> in (TestContainerExtension.java:46)\
    - Method <pro.taskana.testapi.extensions.TestContainerExtension.interceptTestClassConstructor(org.junit.jupiter.api.extension.InvocationInterceptor$Invocation, org.junit.jupiter.api.extension.ReflectiveInvocationContext, org.junit.jupiter.api.extension.ExtensionContext)> calls method <pro.taskana.testapi.DockerContainerCreator.createDataSource(org.testcontainers.containers.JdbcDatabaseContainer)> in (TestContainerExtension.java:50)\

3) With 1.0.0-rc1 the lambda$123 violations vanish. Normally that would keep a frozen rule green and just remove some lines where lambda$123 was reported. But for SliceRule this is a little bit more tricky, because there it actually saves multiline violations, i.e. one Cycle detected: Slice a -> \... multiline violation will be one entry in the store. Thus, if a line from this multiline string vanishes, it will be seen as a different line / violation, i.e. the old one will be removed and that one reported. So it might be necessary to refreeze the SliceRule violations after upgrading ArchUnit.

Can you check, if you have the same problem if you really refreeze the violations with 1.0.0-rc1? I.e. that frozen from one environment (Maven/IDE) they are failing on the other environment? You should be able to easily do this e.g. with the property freeze.refreeze=true

mustaphazorgati commented 2 years ago

Hi @codecholeric, sorry for the late response. The last two weeks have been rather busy.

When I use 1.0.0-rc1 and delete the existing ViolationStore, then when I create a new store with IntelliJ Maven is afterwards also green and the store unchanged. And vice versa, if I create the store with Maven and then run the test with IntelliJ it's green and the store unchanged.

Unfortunately I cannot verify this. I've updated the branch, removed the existing ViolationStore and upgraded Archunit to version 1.0.0-rc1. A single rule gets removed and thrown as an error. I can just fix this rule and would be happy, but there seems to be something off and I bet you prefer to find what's causing the issue. You can recreate the scenario by creating a new ViolationStore through IntelliJ / Maven and then execute the tests afterwards from the other.

When I run 1.0.0-rc1 against the checked in ViolationStore, then it removes a couple of violations and reports them as new. I also noticed that for the checked in ViolationStore the lines of the violations don't seem to always be lexicographically ordered thinking I don't know how this would happen. Originally the ordering of the SliceRule was somewhat random, which made it hard to use with FreezingArchRule. But for that reason we have improved it over time and AFAIS the ordering was improved before the new format with indentation was introduced (which the checked in ViolationStore already uses). E.g.

Thank you for this explanation. Indeed the one "failing" violation gets removed from a frozen SliceRule.

With 1.0.0-rc1 the lambda$123 violations vanish. Normally that would keep a frozen rule green and just remove some lines where lambda$123 was reported. But for SliceRule this is a little bit more tricky, because there it actually saves multiline violations, i.e. one Cycle detected: Slice a -> ... multiline violation will be one entry in the store. Thus, if a line from this multiline string vanishes, it will be seen as a different line / violation, i.e. the old one will be removed and that one reported. So it might be necessary to refreeze the SliceRule violations after upgrading ArchUnit.

Yep, this issue is gone.

Can you check, if you have the same problem if you really refreeze the violations with 1.0.0-rc1? I.e. that frozen from one environment (Maven/IDE) they are failing on the other environment? You should be able to easily do this e.g. with the property freeze.refreeze=true

Unfortunately I still have an issue with a single rule. As I mentioned above, I can just fix the rule and would be happy. Do you want to have another look at this or should we call this done?

Quick question: Do you have any gut feeling / ETA when version 1.0.0 will be released? I am not sure if the team would welcome a release candidate as a dependency

codecholeric commented 2 years ago

My problem is that I can't reproduce it anymore :thinking: I pulled your latest changes, then recompiled everything, ran the test from IntelliJ, the store was created, ran it from Maven -> success. Deleted the store, recreated it from Maven, ran the test in IntelliJ -> success. So there either must be some random factor, or it depends on the platform. What OS are you running the tests on? Windows by any chance? :wink: (just asking, cause I had some problems in the past; I'm running the tests on Linux...) Could you maybe create the store from your IDE, safe copy it somewhere, create it from Maven as well, and then zip both stores and attach them to a comment here? Because otherwise I wouldn't know how to dig deeper into this :thinking: Regarding 1.0.0, this is the last issue I'm looking into. If we're sure it's not a blocker I can release 1.0.0

mustaphazorgati commented 2 years ago

Hey @codecholeric,

My problem is that I can't reproduce it anymore thinking I pulled your latest changes, then recompiled everything, ran the test from IntelliJ, the store was created, ran it from Maven -> success. Deleted the store, recreated it from Maven, ran the test in IntelliJ -> success.

I've provided a video where I showcase what I did. Hopefully this helps you. https://drive.google.com/file/d/1KRMzIp7ipZYZxynLzKX8HZ1XMx7YTafJ/view?usp=sharing

So there either must be some random factor, or it depends on the platform. What OS are you running the tests on? Windows by any chance? wink (just asking, cause I had some problems in the past; I'm running the tests on Linux...)

I am using linux myself.

[mustapha@NT220403 taskana]$ uname -r
5.19.7-arch1-1
[mustapha@NT220403 taskana]$ cat /etc/os-release 
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"
LOGO=archlinux-logo

Could you maybe create the store from your IDE, safe copy it somewhere, create it from Maven as well, and then zip both stores and attach them to a comment here? Because otherwise I wouldn't know how to dig deeper into this thinking

sure thing :) In the video you can see how I created these files. archunit_store_maven.zip archunit_store_intellij.zip output_intellij.txt output_maven.txt

Regarding 1.0.0, this is the last issue I'm looking into. If we're sure it's not a blocker I can release 1.0.0

Alright. I don't want to be the blocking factor. Therefore I will try to reply as fast as I can :)

codecholeric commented 2 years ago

Thanks a lot for the extensive info :heart_eyes: That helps a lot! On the first sight it looks like each environment detects another cycle within pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer and inner classes :exploding_head: I'll try to understand what exactly goes on. Weird though, that we both run it on a quite similar environment, yet it behaves that differently :grimacing: (because from your video I can see that I did almost the exact same things as you and for me the test doesn't fail)

mustaphazorgati commented 2 years ago

Thanks a lot for the extensive info heart_eyes That helps a lot!

You're welcome!

On the first sight it looks like each environment detects another cycle within pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer and inner classes exploding_head I'll try to understand what exactly goes on.

That's interesting. Hopefully you can find the weird behaving spot.

Weird though, that we both run it on a quite similar environment, yet it behaves that differently grimacing (because from your video I can see that I did almost the exact same things as you and for me the test doesn't fail)

To be honest I didn't expect that.

If I can assist you somehow please let me know :)

codecholeric commented 2 years ago

Okay, this was quite the rabbit hole :joy: The first thing I noticed was that while some cycles between these classes were missing, this would not happen anymore if I would disable the AspectJ weaving. Looking into the bytecode I noticed that applying AspectJ would make the call to TaskanaConfigurationInitializer.parseProperty(..) invisible in the bytecode of the classes. This is because AspectJ would weave in some additional synthetic access methods TaskanaConfigurationInitializer.access$123 which would then call parseProperty. So the question at this point was only, why was one cycle always detected if this call was missing, or more precisely, why was only one cycle detected, since normally ArchUnit would be supposed to transparently replace those calls to access$123 with the call users would expect from the source code (compare #889). Turns out that 1.0.0-rc1 actually contains a bug there :see_no_evil: So, I'm really glad that this issue brought this to surface. Basically, the implementation to remove those access$123 methods was the same as for lambda$xyz$123 methods, but for the latter the origins of the calls would be unique. But, for access$123 they actually overrode each other, which lead to a non-deterministic behavior which access would be imported in the end (but seemingly deterministic enough so that it would be the same as long as the system and the environment would not change). You can see more details and (hopefully) a fix here (#957). In any case, I also published the version with the fix as 1.0.0-SNAPSHOT, so maybe you can test this, if it solves your problem? It should now detect all 6 cycles for all 6 inner classes of TaskanaConfigurationInitializer and thus not have different frozen cycles on different environments anymore. You have to add the snapshot repository to test it:

<repositories>
    <repository>
      <id>sonatype-snapshots</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </repository>
  </repositories>

Can you let me know if this now behaves reasonable for you?

mustaphazorgati commented 2 years ago

Okay, this was quite the rabbit hole joy The first thing I noticed was that while some cycles between these classes were missing, this would not happen anymore if I would disable the AspectJ weaving. Looking into the bytecode I noticed that applying AspectJ would make the call to TaskanaConfigurationInitializer.parseProperty(..) invisible in the bytecode of the classes. This is because AspectJ would weave in some additional synthetic access methods TaskanaConfigurationInitializer.access$123 which would then call parseProperty. So the question at this point was only, why was one cycle always detected if this call was missing, or more precisely, why was only one cycle detected, since normally ArchUnit would be supposed to transparently replace those calls to access$123 with the call users would expect from the source code (compare https://github.com/TNG/ArchUnit/pull/889). Turns out that 1.0.0-rc1 actually contains a bug there see_no_evil So, I'm really glad that this issue brought this to surface. Basically, the implementation to remove those access$123 methods was the same as for lambda$xyz$123 methods, but for the latter the origins of the calls would be unique. But, for access$123 they actually overrode each other, which lead to a non-deterministic behavior which access would be imported in the end (but seemingly deterministic enough so that it would be the same as long as the system and the environment would not change). You can see more details and (hopefully) a fix here (https://github.com/TNG/ArchUnit/pull/957).

Now that you mention it, it clicks. I have disabled the AspectJ weaving within IntelliJ a while ago. I've totally forgot to mention that THAT is the difference between the execution of maven and IntelliJ. This could have probably saved some time on your end... Sorry :disappointed:

Nevertheless, I've tested 1.0.0-SNAPSHOT intensively:

Everything seems to work just fine :) :smile: Thank you very much for your kind and professional support :1st_place_medal: :heart: - from my perspective this issue is fixed. Can't wait for the release :partying_face:

mustaphazorgati commented 2 years ago

I am very sorry, but I have to reopen this issue. My previous testing method is flawed and did not target the "enemy": AspectJ. What I've tested is that maven and IntelliJ behave the same, which they do; and did from the beginning.

What I did not test is the behaviour of AspectJ. And this still seems to be broken.

Issue: The store content is not the same when the compilation IS weaved with AspectJ and IS NOT weaved with AspectJ. This results to test failures when executing the architecture tests on a compilation which is not weaved with AspectJ when the store was created with a weaved compilation and vice verca.

Steps to reproduce:

Scenario 1:

  1. disable AspectJ
  2. compile the project
  3. Create the store
  4. enable AspectJ
  5. compile the project
  6. execute architecture tests

Commands to reproduce scenario 1:

# Check out PR (https://github.com/Taskana/taskana/pull/1971)
gh pr checkout 1971
# Clear TASKANA artifacts from local maven repository
rm -rf ~/.m2/repository/pro/taskana/*
# Remove existing store
rm -rf lib/taskana-core-test/archunit_store
# Compile TASKANA without AspectJ
./mvnw clean install -pl :taskana-core-test -am -DskipTests -DskipAspectJ
# Build store 
./mvnw clean verify -pl :taskana-core-test -Dtest="ArchitectureTest"
# OPTIONAL: Create zip of store
zip -r archunit_store_compiled_without_aspectj.zip lib/taskana-core-test/archunit_store
# Compile TASKANA with AspectJ
./mvnw clean install -pl :taskana-core-test -am -DskipTests
# Execute architecture tests with AspectJ
./mvnw clean verify -pl :taskana-core-test -Dtest="ArchitectureTest" | tee test_execution_with_aspectj_using_store_without_aspectj.txt

Store files: archunit_store_compiled_without_aspectj.zip Test execution: test_execution_with_aspectj_using_store_without_aspectj.zip (I had to zip the txt file due to upload size limitations)

Scenario 2:

  1. enable AspectJ
  2. compile the project
  3. Create the store
  4. disable AspectJ
  5. compile the project
  6. execute architecture tests

Commands to reproduce scenario 2:

# Check out PR (https://github.com/Taskana/taskana/pull/1971)
gh pr checkout 1971
# Clear TASKANA artifacts from local maven repository
rm -rf ~/.m2/repository/pro/taskana/*
# Remove existing store
rm -rf lib/taskana-core-test/archunit_store
# Compile TASKANA with AspectJ
./mvnw clean install -pl :taskana-core-test -am -DskipTests
# Build store 
./mvnw clean verify -pl :taskana-core-test -Dtest="ArchitectureTest"
# OPTIONAL: Create zip of store
zip -r archunit_store_compiled_with_aspectj.zip lib/taskana-core-test/archunit_store
# Compile TASKANA without AspectJ
./mvnw clean install -pl :taskana-core-test -am -DskipTests -DskipAspectJ
# Execute architecture tests without AspectJ
./mvnw clean verify -pl :taskana-core-test -Dtest="ArchitectureTest" -DskipAspectJ | tee test_execution_without_aspectj_using_store_with_aspectj.txt

Store files: archunit_store_compiled_with_aspectj.zip Test execution: test_execution_without_aspectj_using_store_with_aspectj.zip (I had to zip the txt file due to upload size limitations)

Also I've provided a video where I showcase both scenarios. That video also shows how those files were created :) https://drive.google.com/file/d/1zmSe2pfjLeq3TevsPPToeWiUU3KwcwVw/view?usp=sharing

Now the question: Should ArchUnit behave differently when AspectJ is enabled/disabled? Is this even a valid (supported) usecase for ArchUnit? If yes: We should find a solution. If not: We can close this issue.

codecholeric commented 2 years ago

The problem is, I think asking that it behaves the same with and without AspectJ is impossible. Because AspectJ just fundamentally changes the bytecode. And the bytecode is the source of truth for ArchUnit. ArchUnit has no way to know what is from AspectJ and what not. Compare for example the output for ListPropertyParser without AspectJ (which makes sense and matches the source code)

- Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.splitStringAndTrimElements(java.lang.String, java.lang.String)> in (TaskanaConfigurationInitializer.java:184)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.createCustomHolidayFromPropsEntry(java.lang.String)> in (TaskanaConfigurationInitializer.java:188)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> gets field <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.LOGGER> in (TaskanaConfigurationInitializer.java:190)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.parseProperty(java.util.Properties, java.lang.String, pro.taskana.common.internal.util.CheckedFunction)> in (TaskanaConfigurationInitializer.java:196)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.splitStringAndTrimElements(java.lang.String, java.lang.String, java.util.function.UnaryOperator)> in (TaskanaConfigurationInitializer.java:200)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.parseProperty(java.util.Properties, java.lang.String, pro.taskana.common.internal.util.CheckedFunction)> in (TaskanaConfigurationInitializer.java:201)

versus the output after AspectJ has rewritten the bytecode

- Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.lambda$1(java.lang.String)> gets field <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.LOGGER> in (TaskanaConfigurationInitializer.java:38)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.initialize(java.util.Properties, java.lang.String, java.lang.reflect.Field, pro.taskana.common.internal.configuration.TaskanaProperty)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.parseProperty(java.util.Properties, java.lang.String, pro.taskana.common.internal.util.CheckedFunction)> in (TaskanaConfigurationInitializer.java:152)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.lambda$0(java.lang.String, java.lang.String)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.splitStringAndTrimElements(java.lang.String, java.lang.String)> in (TaskanaConfigurationInitializer.java:184)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.lambda$1(java.lang.String)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.createCustomHolidayFromPropsEntry(java.lang.String)> in (TaskanaConfigurationInitializer.java:188)\
    - Method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer$ListPropertyParser.lambda$3(java.lang.String)> calls method <pro.taskana.common.internal.configuration.TaskanaConfigurationInitializer.splitStringAndTrimElements(java.lang.String, java.lang.String, java.util.function.UnaryOperator)> in (TaskanaConfigurationInitializer.java:200)

It's just fundamentally different, the calls come from other places and AspectJ also weaves in some "weird" methods (lambda$1 and co. are no standard conventions for lambda methods as the JDK writes them).

So, to wrap it up I think ArchUnit tests should run on unmanipulated bytecode. Because that bytecode still matches the source code well. In the end, AspectJ could also weave in a lot of additional calls that are not visible in the source code :shrug: So, it can never be the same with or without AspectJ independently of the Aspects that are woven in.

mustaphazorgati commented 2 years ago

I can totally understand your reasoning. Thanks for the explanation. :)