2

Java 9 will restrict any access to private API. That means that the known methods of retrieving the window hwnd using Reflection won't work anymore.

Is there still a way to get them? I ask because I have a library that offers an API for manipulating the Taskbar (in a similar way that Java9 offers). The Java 9 API is still for AWT, so I hope I can get my project setup for Java 9 and JavaFX.

I used to just call the private methods, but this will stop working. Any solution is appreciated. Native calls are ok if they can be done using JNA or BridJ.

SirWindfield
  • 117
  • 2
  • 8
  • Can you just look at the source code of the methods you are already using and then copy them to a different package, shipping the resultant Java and Native code with your application? – jewelsea Jul 04 '16 at 06:03
  • I do not really understand why a package change will help me out there. Java 9 does not allow the usage and throws ReflectionExceptions all over the place if you try to access API's that are not exported through the module info file. – SirWindfield Jul 04 '16 at 13:58
  • If you copy code and put in your own package and write your own module info file for it which exports the functions you need from your own package, then you should not receive the RelectionExceptions you refer to. That said, I realize doing so could have some subtle complications which make such an approach not worthwhile nor feasible, which is why I just suggested as an approach you may wish to consider. – jewelsea Jul 05 '16 at 21:34
  • Check http://openjdk.java.net/jeps/253, it lists classes which should appear as a public API around mid-July to early August. – Anton Krosnev Jul 07 '16 at 15:15

1 Answers1

0

One way could be to make changes to an already suggested solution to How can I get the window handle (hWnd) for a Stage in JavaFX? useful prior to JDK9 as :-

try {
    TKStage tkStage = stage.impl_getPeer();
    Method getPlatformWindow = tkStage.getClass().getDeclaredMethod("getPlatformWindow" );
    getPlatformWindow.setAccessible(true);
    Object platformWindow = getPlatformWindow.invoke(tkStage);
    Method getNativeHandle = platformWindow.getClass().getMethod( "getNativeHandle" );
    getNativeHandle.setAccessible(true);
    Object nativeHandle = getNativeHandle.invoke(platformWindow);
    return new Pointer((Long) nativeHandle);
} catch (Throwable e) {
    System.err.println("Error getting Window Pointer");
    return null;
}

with a module-info.java somewhat like :

module your.module {
    requires javafx.graphics;
}

But since javax.graphics exports the package internally to specific modules as:

exports com.sun.javafx.tk to
    javafx.controls,
    javafx.deploy,
    javafx.media,
    javafx.swing,
    javafx.web;

You can try adding a compiler option to still make use of it as

--add-exports javax.graphics/com.sun.javafx.tk=your.module

Note/Imp : Disclaimer from JEP-261:Module System -

The --add-exports and --add-opens options must be used with great care. You can use them to gain access to an internal API of a library module, or even of the JDK itself, but you do so at your own risk: If that internal API is changed or removed then your library or application will fail.

Naman
  • 27,789
  • 26
  • 218
  • 353