Hi,

as promised here is the list of current private api usages of our application.
Any advice how to achieve the same with public apis is always welcome.


* We use com.sun.webkit.WebPage and com.sun.javafx.webkit.Accessor to implement 
our own frontend for the html editor.
  It seems to be unmaintained by oracle. Has anyone used an texteditor, where 
it is not possible to do a line break
  (https://javafx-jira.kenai.com/browse/RT-38412)? Bug was filed August 2014 
and was deferred from 8u40 to 9.
  The bug can only be tracked down by oracle, because the bug is probably in 
the plugin code, which is still closed source.
  Well we have a semi working workaround involving private apis...
  Whatever we currently implement a new text editor based on TextFlow, because 
the html editor is simply too buggy.
  So for us this will no longer an issue with Java 9.

* com.sun.javafx.scene.control.skin.ComboBoxListViewSkin is used to scroll to 
entry matching typed key in a ComboBoxListView
  There is a feature request from 2011 for this: 
https://javafx-jira.kenai.com/browse/RT-18064.
  Perhaps its enough to expose scrollTo. That is 
https://javafx-jira.kenai.com/browse/RT-34661.

   fontFamilyComboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
                
                @Override
                        public void handle(KeyEvent event) {
                        
                                if (fontFamilyComboBox.isShowing()) {

                                        @SuppressWarnings("rawtypes")
                                        ListView cbListView = 
((ComboBoxListViewSkin) fontFamilyComboBox.getSkin()).getListView();
                                
                                        String typed = 
event.getCode().toString().toLowerCase();
                                        ObservableList<String> fontList = 
fontFamilyComboBox.getItems();
                                        for (int i = 0; i < fontList.size(); 
i++) {
                                                String font = 
fontList.get(i).toLowerCase();
                                                if (font.startsWith(typed)) {
                                                        
fontFamilyComboBox.getSelectionModel().clearAndSelect(i);
                                                        cbListView.scrollTo(i);
                                                        break;
                                                }
                                        }               
                                }
                }
        });

* We maximize our application window to full screen on startup with this code
This is a workaround for https://javafx-jira.kenai.com/browse/RT-32422

import com.sun.glass.ui.Window;
import com.sun.javafx.application.PlatformImpl;

            if (!isEmbedded && Window.getFocusedWindow() != null) {
                
Logger.getLogger(getClass()).debug(Settings.getInstance().getBoolProperty("mainStageMaximized",
 true));
                try {
                    
Window.getFocusedWindow().maximize(Settings.getInstance().getBoolProperty("mainStageMaximized",
 true));
                } catch (Exception e) {
                    // java.lang.IllegalStateException: The window has already 
been closed on linux
                }
                Logger.getLogger(getClass()).info("maximized focused window " + 
Window.getFocusedWindow().getTitle());
}

* ComboBoxes, we have the requirement to automatically open comboboxes on 
mouseover. The combobox should not be closed on mouseclick:

 Expose the value of isHideOnClickEnabled in our ExtendedComboBox control.

        @Override
        protected Skin<?> createDefaultSkin() {
                Skin<?> s = new ComboBoxListViewSkin<T>(this){
                
                        @Override
                        protected boolean isHideOnClickEnabled() {
                                return getIsHideOnClickEnabled();
                        }
                        
                        @Override
                        protected PopupControl getPopup() {
                                PopupControl p = super.getPopup();
                                p.autoHideProperty().bind(autoHideProperty);
                                return p;
                        }
                        };
                return s;
        }


* com.sun.glass.ui.Robot is used to work around a bug, that the Browser window 
does not get focus after the SWT-Filedialog is closed on Mac
-> We would not have to use the SWT-Filedialog at all and could use the 
JavaFX-Filedialog, ifhttps://javafx-jira.kenai.com/browse/RT-38809  was fixed.

Browser Mode: activate browser after swt-filedialog has been closed
            if(EditorFX.getInstance().getHostServices().getWebContext()!=null) {
                LOG.debug("disposeAll -> create Robot");
                Robot robot = 
com.sun.glass.ui.Application.GetApplication().createRobot();
                if(robot!=null) {
                    robot.mousePress(1);
                    robot.mouseRelease(1);
                    robot.destroy();
                    LOG.debug("disposeAll -> Robot destroyed");
                }
            }

* com.sun.glass.ui.Robot is also used to get screen coordinates for checks, if 
the mouse is over a node or not.
 We found that mouseEntered and mouseExited events do not work reliable. E.g.: 
mouseExited Events not triggered, mouseEntered are triggered before mouseExited 
on previous node)

* Gather various information about the used hardware in case of an unhandled 
exception.
  In case of an unhandled exception we gather various information about the 
affected computer and ask the user to upload it to us for further analysis.
 Our dialog is similar to what Firefox 
does:https://support.mozilla.org/en-US/kb/mozillacrashreporter
 These are some of our hacks to get information about the current hardware used:

        public static long getTotalPhysicalMemorySize() {
                com.sun.management.OperatingSystemMXBean os = 
(com.sun.management.OperatingSystemMXBean)
                             
java.lang.management.ManagementFactory.getOperatingSystemMXBean();
                return os.getTotalPhysicalMemorySize();
        }
        
        public static long getFreePhysicalMemorySize() {
                com.sun.management.OperatingSystemMXBean os = 
(com.sun.management.OperatingSystemMXBean)
                             
java.lang.management.ManagementFactory.getOperatingSystemMXBean();
                return os.getFreePhysicalMemorySize();



getWindowsGraphicCardInfo retrieves the same information, which would have been 
logged by prism.verbose=true

public class WindowsHardwareInfo {

        public static String getWindowsGraphicCardInfo() {
                
                String info = "";
                
                try {
                        // ResourceFactory resourceFactory = 
D3DPipeline.getDefaultResourceFactory()
                        Class<?> d3DPipelineClass = (Class<?>) 
Class.forName("com.sun.prism.d3d.D3DPipeline");
                        Method getDefaultResourceFactoryMethod = 
d3DPipelineClass.getMethod("getDefaultResourceFactory");
                        ResourceFactory resourceFactory = (ResourceFactory) 
getDefaultResourceFactoryMethod.invoke(null);
                        
                        info += "Maximum texture size: " + 
resourceFactory.getMaximumTextureSize() + "\n" ;
                        
                        // int adapterCount = D3DPipeline.nGetAdapterCount()
                        Method nGetAdapterCountMethod =  
d3DPipelineClass.getDeclaredMethod("nGetAdapterCount");
                        nGetAdapterCountMethod.setAccessible(true);
                        int adapterCount = (Integer) 
nGetAdapterCountMethod.invoke(null);
                        
                        Class<?> d3DDriverInformationClass = (Class<?>) 
Class.forName("com.sun.prism.d3d.D3DDriverInformation");
                        Method nGetDriverInformationMethod = 
d3DPipelineClass.getDeclaredMethod("nGetDriverInformation", int.class, 
d3DDriverInformationClass );
                        nGetDriverInformationMethod.setAccessible(true);

                        Constructor<?> constructor = 
d3DDriverInformationClass.getDeclaredConstructor();
                        constructor.setAccessible(true);

                        for (int adapter = 0, n = adapterCount; adapter != n; 
++adapter) {
                                //D3DPipeline.nGetDriverInformation(adapter, 
new D3DDriverInformation());
                                Object di = 
nGetDriverInformationMethod.invoke(null, adapter, constructor.newInstance());
                        
                            if (di != null) {
                                info += "Graphics adapter #" + adapter + "\n";
                                info += "OS Information:\n";
                                info += "\t" + callGetter(di, d3DDriverInformationClass, "getOsVersion") + 
" build " + getField(di, d3DDriverInformationClass, "osBuildNumber") + "\n";
                                info += "D3D Driver Information:\n";
                                info += "\t" + getField(di, d3DDriverInformationClass, 
"deviceDescription")  + "\n";
                                info += "\t" + getField(di, d3DDriverInformationClass, 
"deviceName") + "\n";
                                info += "\tDriver " + getField(di, d3DDriverInformationClass, "driverName") + 
", version " + callGetter(di, d3DDriverInformationClass, "getDriverVersion") + "\n";
                                info += "\tPixel Shader version " + getField(di, d3DDriverInformationClass, 
"psVersionMajor") + "." + getField(di, d3DDriverInformationClass, "psVersionMinor") + 
"\n";
                                info += "\tDevice : " + callGetter(di, d3DDriverInformationClass, 
"getDeviceID") + "\n";
//                          System.out.println("\tMax Multisamples supported: " 
+ di.maxSamples);
                                Object warning = getField(di, d3DDriverInformationClass, 
"warningMessage");
                                if (warning != null) {
                                        info += "\t *** " + warning + "\n";
                                }
                            }
                        }
                } catch (Exception e) {
                        info += "Unable to retrieve hardware info: " + 
e.getMessage();
                }
                        
                return info;
        }
        
        private static Object callGetter(Object object, Class<?> objectClass, 
String methodName) throws NoSuchMethodException, SecurityException, 
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
                Method method = objectClass.getDeclaredMethod(methodName);
                method.setAccessible(true);
                return method.invoke(object);
        }
        
        private static Object getField(Object object, Class<?> objectClass, 
String fieldName) throws NoSuchFieldException, SecurityException, 
IllegalArgumentException, IllegalAccessException {
                Field field = objectClass.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(object);
        }


For OutOfMemory exceptions, we create a heapdump file like this:

    public static void dumpHeap(String fileName, boolean live) throws Exception 
{
        // initialize hotspot diagnostic MBean
        Object hotspotMBean = getHotspotMBean();
        Class<?> clazz = 
Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
        Method m = clazz.getMethod("dumpHeap", String.class, boolean.class);
        m.invoke( hotspotMBean , fileName, live);
    }

    // get the hotspot diagnostic MBean from the
    // platform MBean server
    private static Object getHotspotMBean() throws ClassNotFoundException, 
IOException {
        Class<?> clazz = 
Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
        return ManagementFactory.newPlatformMXBeanProxy(server, 
HOTSPOT_BEAN_NAME, clazz);
    }


These are the current usages of private apis in our application.
However we include various other libraries, which I have not checked yet. Some 
of them are no longer maintained.

So obviously for most of the problems there are open jiras, many of them years 
old.


- Stefan

I' ll try to compile a list of the private apis we currently use in our application and why.

Looking forward to using only public apis in java 9 then :-)

- Stefan

On Apr 8, 2015, at 1:52 PM, Robert Krüger <krue...@lesspain.de> wrote:
  our only workaround is to use private API
For the benefit of the devs on the list, could you please point out what private APIs you currently need to use? That way we can make sure proper JIRAs are filed and we can connect those to actual real-world problems.


Reply via email to