-
Notifications
You must be signed in to change notification settings - Fork 289
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
FreezingArchRule breaks when executed from IDE and maven #923
Comments
Thanks for raising the issue! First, about the lambda parameter, can you please try version 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? 🤔 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 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 🤔
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 |
Nevermind, of course wrong Java version 🤦♂️ 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 🤪 |
Yeah. Maven is sometimes funny and doesn't describe the error properly.
Thank you very much! Can I assist you somehow? If so, then please let me know. I'll check out version |
Yes, checking out the difference if you use |
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). |
I finally found some time to look into it, this is how it looked to me:
Can you check, if you have the same problem if you really refreeze the violations with |
Hi @codecholeric,
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.
Thank you for this explanation. Indeed the one "failing" violation gets removed from a frozen SliceRule.
Yep, this issue is gone.
Unfortunately I still have an issue with a single rule. As I mentioned above, I can just fix the rule and would be happy. 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 |
My problem is that I can't reproduce it anymore 🤔 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. |
Hey @codecholeric,
I've provided a video where I showcase what I did. Hopefully this helps you.
I am using linux myself.
sure thing :) In the video you can see how I created these files.
Alright. I don't want to be the blocking factor. Therefore I will try to reply as fast as I can :) |
Thanks a lot for the extensive info 😍 That helps a lot! On the first sight it looks like each environment detects another cycle within |
You're welcome!
That's interesting. Hopefully you can find the weird behaving spot.
To be honest I didn't expect that. If I can assist you somehow please let me know :) |
Calls to lambda methods `lambda$abc$123` seem to have unique origins with current JDK versions. I.e. even two identical consecutive lambda invocations will lead to two separate synthetic methods. Unfortunately, this is not the case for synthetic `access$123` methods (to circumvent private modifiers), which lead to a bug where multiple origins of such a call would override each other. This lead e.g. to the behavior in #923, where the application of AspectJ introduced an `access$123` method that was called from multiple places. But, only one such call would randomly be created during the import, which lead to an unpredictable behavior of which cycles between outer and inner classes would be detected. We now record multiple access records for any synthetic call and trace back all those records instead of just the last one. This way all such synthetic accesses should be imported correctly now. Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Okay, this was quite the rabbit hole 😂 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
Can you let me know if this now behaves reasonable for you? |
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 😞 Nevertheless, I've tested
Everything seems to work just fine :) 😄 |
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 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:
Commands to reproduce scenario 1:
Store files: archunit_store_compiled_without_aspectj.zip Scenario 2:
Commands to reproduce scenario 2:
Store files: archunit_store_compiled_with_aspectj.zip 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. |
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
versus the output after AspectJ has rewritten the bytecode
It's just fundamentally different, the calls come from other places and AspectJ also weaves in some "weird" methods ( 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 🤷 So, it can never be the same with or without AspectJ independently of the Aspects that are woven in. |
I can totally understand your reasoning. Thanks for the explanation. :) |
…957) Calls to lambda methods `lambda$abc$123` seem to have unique origins with current JDK versions. I.e. even two identical consecutive lambda invocations will lead to two separate synthetic methods. Unfortunately, this is not the case for synthetic `access$123` methods (to circumvent private modifiers), which lead to a bug where multiple origins of such a call would override each other. This lead e.g. to the behavior in #923, where the application of AspectJ introduced an `access$123` method that was called from multiple places. But, only one such call would randomly be created during the import, which lead to an unpredictable behavior of which cycles between outer and inner classes would be detected. We now record multiple access records for any synthetic call and trace back all those records instead of just the last one. This way all such synthetic accesses should be imported correctly now.
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:
Execution command (from project root directory):
Further notes:
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.
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.
The text was updated successfully, but these errors were encountered: