Issue
I have two Java 9 modules, a server, and a handler. The server loads HTTP handlers with the ServiceLoader (code below).
Why does the o.getClass().getName()
in this snippet work? Is it because provides
opens the handler class up to reflection? Does getClass().getName() not use reflection? Does Java somehow always map an interface to the underlying class instance (and thus to the class) without needing reflection?
server module code:
ServiceLoader
.load(HTTPHandlerWithContext.class)
.stream()
.map(ServiceLoader.Provider::get)
.forEach(o -> {
System.out.printf(
"registering route %s to %s%n",
o.getContext(),
o.getClass().getName()
);
server.createContext(o.getContext(), o);
});
handler module-info:
module com.example.helloworld {
requires com.example.tinyjhttpd;
requires jdk.httpserver;
provides com.example.tinyjhttpd.HTTPHandlerWithContext
with com.example.helloworld.HelloWorld;
}
What I think is the relevant snippet from Class.java was not enough to make it clear to me:
// Cache the name to reduce the number of calls into the VM.
// This field would be set by VM itself during initClassName call.
private transient String name;
private native String initClassName();
Solution
The Java Language Specification does not define Reflection (and hence, the impact of opens
or the lack thereof) in detail but rather refers to the API specification:
[...] This specification constrains the behavior of such classes and interfaces, but does not provide a complete specification for them. The reader is referred to the Java SE Platform API documentation.
Consequently, this specification does not describe reflection in any detail. Many linguistic constructs have analogs in the Core Reflection API (
java.lang.reflect
) and the Language Model API (javax.lang.model
), but these are generally not discussed here.
The Java SE Platform API documentation specifies when an IllegalAccessException
can be thrown, e.g. on invocations of Field.get
or Method.invoke
.
Neither Object.getClass()
nor Class.getName()
have been specified to potentially throw an IllegalAccessException
.
This is consistent with the runtime behavior of Java before the module system introduction. Just the rules regarding when an access is granted or not became more complex.
The impact of being able to query the name of a class is rather low compared to accessing the internal data or invoking non-API methods.
Answered By - Holger Answer Checked By - Senaida (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.