I'm attempting to find the best way of obtaining the X ID code of the backing windows of heavyweight AWT panels. Why is the java.awt.Component.getPeer command listed as deprecated? Is there a security issue involved?
Why is the java getPeer call deprecated?
2.2k views Asked by Austin Sumigray At
2
There are 2 answers
0
On
I made a native JNI wrapper for MacOS and needed the AWTWindow pointer in java 17 which is the NSWindow basically.
You can still get the AWTWindow pointer by a little bit of hackery.
Add the following jvm args to the target:
--add-exports java.desktop/sun.lwawt=ALL-UNNAMED --add-exports java.desktop/sun.lwawt.macosx=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED
The java code is the following:
JFrame jf = new JFrame();
Component jfComponent = ((Component) jf);
try {
Field field = Component.class.getDeclaredField("peer");
field.setAccessible(true);
CPlatformWindow platformWindow = (CPlatformWindow)((LWWindowPeer)field.get(jfComponent)).getPlatformWindow();
AtomicLong awtWindowPointer = new AtomicLong();
platformWindow.execute(l -> {
awtWindowPointer.set(l);
});
System.out.println("AWT window pointer: "+String.format("0x%08X", awtWindowPointer.get()));
} catch (Exception ex) {
ex.printStackTrace();
}
By the way, obviously this may breaks future compatibility and also this code is platform specific, so kinda defeat the java purpose.
The javadoc states:
It is a design issue rather than a security issue.
The issue being addressed is that the peer implementations can behave rather differently from one platform to another, and indeed (at least in theory) from one version of Java to another. So, if your application accesses the peers directly, then it is liable to be non-portable.
At any rate, direct access to peers has been strongly discourage for a long time. The
java.awt.peerpackage and classes have not been documented in the standard javadoc (at least) as far back as Java 1.4.2. The source code for the peer classes say this: (Java 6 version)In fact, as of Java 9 the previously deprecated
getPeer()method has been removed. So if you want a strong reason why you should not usegetPeer()it is because your code won't work on Java 9 if you use it!Now, if you really, really needed to access the AWT peers in Java 9, you could still use reflection to access the package-private
peervariable. However, the risk of using reflection to dive into the AWT implementation is that your code may break (again) in a future release. Indeed, the Java maintainers are progressively locking down reflective access to the Java internals. (I have not checked, but I suspect that this access will have been blocked in Java 16 by "JEP 396: Strongly Encapsulate JDK Internals by Default (JDK-8256299)")