-
Notifications
You must be signed in to change notification settings - Fork 21
Private class constructor is public at the bytecode level #12711
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
Comments
Marking the constructor synthetic could break other tools. IMO this should stay as is in bytecode, it would be good to improve MiMa to understand this pattern. |
Do you see a “good” reason to rely on this breach? |
I'm not saying having the constructor public is good, we should keep things private in bytecode where possible - but there are many cases where we can't. For example anything Marking something that's not synthetic as synthetic might break tools that take information from the bytecode. |
I agree with Lukas. It's actually inherent and normal — though unfortunate! — that we have to mark things in bytecode as public even when they aren't public in the source. The callable-from-Java thing is unfortunate but it's a much bigger problem than just for constructors, so I don't think it's that helpful or important to fix it just for constructors, especially when the "fix" involves lying by marking actual user code as synthetic. As for MiMa, being smarter about this is MiMa's responsibility. |
The IMO significant difference about constructors is that they keep their name (obviously). For other typical use cases, names are mangled with the fully qualified name of their owner and/or package, and so it's much more obvious that you're not supposed to call them even if they show up. |
FWIW, my proposed fix was to make them JVM-package-private instead. |
Not always though, for example |
... also, name-mangling private members that are made public is required to avoid accidental name clashes. I'm not sure if name mangling would have been introduced only to hide private definitions from Java. |
I see. Then I guess the least controversial way forward is indeed to change MiMa. |
Thank you for the discussion, I’ve followed-up by creating lightbend-labs/mima#738 |
Classes with private constructors are actually public at the bytecode level, this creates two issues:
Reproduction steps
Output
The code compiles.
Expectation
The Java compilation should fail.
Possible solution
In a discussion, @smarter suggested to emit the constructor as
ACC_SYNTHETIC
to make it non-accessible from Java, and ignored by mima (see lightbend-labs/mima#92). Note that that change would still be binary compatible with possible existing Java code that would call such constructors (but it would be source incompatible).Related Scala 3 issue: scala/scala3#16651
The text was updated successfully, but these errors were encountered: