Bug 550290 - Lack of TypeSafeEnum#hashCode may lead to non-deterministic bytecode
Summary: Lack of TypeSafeEnum#hashCode may lead to non-deterministic bytecode
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.9.4   Edit
Hardware: PC Windows 10
: P3 normal with 1 vote (vote)
Target Milestone: 1.9.5   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-08-21 04:40 EDT by Andrey Kuznetsov CLA
Modified: 2019-09-09 20:33 EDT (History)
2 users (show)

See Also:


Attachments
Gradle reproducer project (1.46 KB, application/x-zip-compressed)
2019-08-21 04:40 EDT, Andrey Kuznetsov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Kuznetsov CLA 2019-08-21 04:40:55 EDT
Created attachment 279649 [details]
Gradle reproducer project

TypeSafeEnum instance can be used as part of HashMap key, for example, in org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration#accessForInline. Since TypeSafeEnum does no override hashCode(), this may lead to inpredictable iteration order over HashMap entries.

I could not reproduce this by invoking ajc directly, but Gradle project attached demonstrates it good enough. From 2 to 4 repetitive builds are usually sufficient to get distinct class bytecode. E.g., under Windows it can be tested like this:

> gradle clean compileAspect && certutil -hashfile build/classes/java/main/Test.class sha1

While all versions of bytecode produced are correct, practical consequences of non-determinism are possible. For example, bnd tooling that builds OSGi bundles compares current class version to previously released version and insists on bundle version increasing when bytecode is changed (while it could change even without source modification due to issue being reported).

Please consider the following changes to fix the issue:
- Add "natural" hashCode() and equals() to TypeSafeEnum.
- Change the class of AspectDeclaration#accessForInline to LinkedHashMap, since HashMap per se does not guarantee fixed iteration order.
Comment 1 Andrew Clement CLA 2019-09-09 20:33:55 EDT
All fixed up. Thanks for the report! Tried your sample project and it seemed stable after the change.