-
Notifications
You must be signed in to change notification settings - Fork 72
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
Private subclasses of public classes should not be reported as linkage errors #1608
Comments
Nice analysis. This seems like a high priority to fix. It is not exclusive to JDK classes, and private or non-public subclasses of public types are a common pattern in OO design in general and Java in particular. |
@elharo I'm thinking to fix this by reading byte code of the (source) class file. It's a true linkage error only when the class reference is used in
What do you think? |
Actually without subclassing, the case still stands.
|
Is it? In this case you're relying on on B being a subclass of java.lang.Object and thus having a toString() method that's invoked polymorphically. You're calling PrintStream.toString(Object o). |
This is a good example though. What we need to be testing here is whether the type of variable passed to the println method is accessible, not whether the actual runtime type of A.f is accessible. |
This example shows we can't rely on it being a linkage error when accessing the method of the inaccessible class. This case does call the |
Right, being the subclass of java.lang.Object seems important. (Class C's bytecode does not call Explicitly calling toString fails compilation: |
Yes, the call to toString is in |
What if you did |
Memo:
It turned out that this assumption was incorrect. JVM does not fail the code even if ExperimentWhat if the accessor of A.B changes from public to private in below? (public at the time of compile and private at the runtime) Does it create an error?
Changing
If
This observation falls in https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.3.3
Relaxing Class Reference Validation
I propose that Linkage Checker should invalidate a class reference's access (whether the referencing class has enough access to the referenced class) only when the reference is used in
|
@elharo @netdpb I appreciate if you can give me feedback on http://go/jdd-class-reference-validation |
Followup of #1599 (comment). It was a false positive.
com.sun.tools.internal.ws.wscompile.WsgenOptions
(source) referencescom.sun.xml.internal.ws.api.BindingID$SOAPHTTPImpl
(target). The latter is a private class. Linkage Checker detected it as a linkage error. However, the reference turned out to be not harmful. This is because the source class is not instantiating the private class or declaring a variable with the type.One of the referencing method is the code below:
Here,
BindingID.SOAP11_HTTP
has typecom.sun.xml.internal.ws.api.BindingID$SOAPHTTPImpl
(private class), which is a subclass ofBindingID
class. As WsgenOptions is not touching the private class, calling thegetBindingID
method does not cause aLinkageError
at runtime.Simplified Example
Suppose we have the following class
A
,B
, andC
:When compiled,
C
's class file contains a reference to (private)A$B
class. Linkage Checker would report this reference as a linkage error, simply becauseA$B
is not accessible fromC
. However, this is a false positive as the code compiles and run without a problem.Interestingly the field
#34
is not referenced by other constant pool entries or byte code. How about the case ofcom.sun.tools.internal.ws.wscompile.WsgenOptions
?com.sun.tools.internal.ws.wscompile.WsgenOptions
has the class reference (javap output) used in InnerClasses attribute:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6
How about "If a class reference is only used by the InnerClasses annotation, we skip it"?
Java Language Specification: 12.3.3. Resolution of Symbolic References
https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.3.3
For constructor, we can check
new
. But it cannot detect wrong access ofA.B
How about "If a class reference is only used by NameAndType, we ignore it"?
The text was updated successfully, but these errors were encountered: