diff --git a/CHANGES.md b/CHANGES.md index 9b978ba75a..d85df89671 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Bug Fixes * [#384](https://github.com/java-native-access/jna/issues/384): Android only supports loading libraries through the JVM `System#loadLibrary` mechanism, defaulting `jna.nosys` to `true` disabled that code path - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#1041](https://github.com/java-native-access/jna/pull/1041): Avoid IllegalArgumentException when reading xattrs with zero length - [@jrobhoward](https://github.com/jrobhoward). * [#1042](https://github.com/java-native-access/jna/issues/1042): `com.sun.jna.platform.WindowUtils.W32WindowUtils.getProcessFilePath(HWND)` does not close process handle - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1044](https://github.com/java-native-access/jna/issues/1044): `com.sun.jna.platform.WindowUtils.W32WindowUtils.getProcessFilePath(HWND)` does not close process handle - [@matthiasblaesing](https://github.com/matthiasblaesing). Release 5.1.0 ============= diff --git a/contrib/platform/build.xml b/contrib/platform/build.xml index 0761e3ec06..e489986dee 100644 --- a/contrib/platform/build.xml +++ b/contrib/platform/build.xml @@ -218,8 +218,7 @@ com.sun.jna.platform.wince;version=${osgi.version} - - + diff --git a/contrib/platform/src/com/sun/jna/platform/unix/X11.java b/contrib/platform/src/com/sun/jna/platform/unix/X11.java index 6c20edf314..43123cdc34 100644 --- a/contrib/platform/src/com/sun/jna/platform/unix/X11.java +++ b/contrib/platform/src/com/sun/jna/platform/unix/X11.java @@ -1752,7 +1752,7 @@ class XGravityEvent extends Structure { public int x, y; } - @FieldOrder({"type", "serial", "send_event", "display", "parent", "window", "x", "y", "width", "height", "border_width", "above", "detail", "value_mask"}) + @FieldOrder({"type", "serial", "send_event", "display", "window", "width", "height"}) class XResizeRequestEvent extends Structure { public int type; public NativeLong serial; // # of last request processed by server diff --git a/contrib/platform/test/com/sun/jna/platform/StructureFieldOrderTest.java b/contrib/platform/test/com/sun/jna/platform/StructureFieldOrderTest.java deleted file mode 100644 index ebdd8b2560..0000000000 --- a/contrib/platform/test/com/sun/jna/platform/StructureFieldOrderTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2007-2008 Timothy Wall, All Rights Reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - */ -package com.sun.jna.platform; - - -import com.sun.jna.Platform; -import com.sun.jna.platform.unix.X11; -import com.sun.jna.platform.win32.DBT; -import junit.framework.TestCase; - -import com.sun.jna.StructureFieldOrderInspector; - -import java.util.ArrayList; -import java.util.List; - -public class StructureFieldOrderTest extends TestCase { - - private String origPropJNANoSys; - - protected void setUp() { - origPropJNANoSys = System.getProperty("jna.nosys"); - System.setProperty("jna.nosys", "true"); // would be set by ant script, set here for IDE usage - } - - protected void tearDown() { - if (origPropJNANoSys == null) { - System.getProperties().remove("jna.nosys"); - } else { - System.setProperty("jna.nosys", origPropJNANoSys); - } - } - - - public void testMethodGetFieldOrder() { - final List ignoreConstructorError = new ArrayList(); - - if (Platform.isWindows()) { - ignoreConstructorError.add(X11.class.getName() + "$"); - } else { - ignoreConstructorError.add(com.sun.jna.platform.win32.Winspool.PRINTER_INFO_1.class.getName()); - ignoreConstructorError.add(com.sun.jna.platform.win32.Winspool.PRINTER_INFO_4.class.getName()); - ignoreConstructorError.add(com.sun.jna.platform.win32.SetupApi.SP_DEVICE_INTERFACE_DATA.class.getName()); - ignoreConstructorError.add(com.sun.jna.platform.win32.SetupApi.SP_DEVINFO_DATA.class.getName()); - } - - ignoreConstructorError.add(DBT.DEV_BROADCAST_HANDLE.class.getName()); // manually validated by wolftobias - ignoreConstructorError.add(DBT.DEV_BROADCAST_PORT.class.getName()); // manually validated by wolftobias - - StructureFieldOrderInspector.batchCheckStructureGetFieldOrder(FileUtils.class, ignoreConstructorError); - } - -// test below is helpful when investigating failure cause of a specific Structure class, it shows full causes and traces. -/* - public void testMethodGetFieldOrderSingleClass() { - final List ignoreConstructorError = new ArrayList(); - - if (Platform.isWindows()) { - ignoreConstructorError.add(X11.class.getName() + "$"); - } - - StructureFieldOrderInspector.checkMethodGetFieldOrder(com.sun.jna.platform.win32.SetupApi.SP_DEVICE_INTERFACE_DATA.class, ignoreConstructorError); - } -//*/ - - -} diff --git a/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java b/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java index 9b367172c9..7981573e12 100644 --- a/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java +++ b/contrib/platform/test/com/sun/jna/platform/unix/X11Test.java @@ -12,6 +12,7 @@ */ package com.sun.jna.platform.unix; +import com.sun.jna.StructureFieldOrderInspector; import java.awt.GraphicsEnvironment; import com.sun.jna.ptr.PointerByReference; @@ -104,6 +105,10 @@ public void testXGetWMProtocols() { Assert.assertArrayEquals("Sent protocols were not equal to returned procols for XGetWMProtocols", sentAtoms, receivedAtoms); } + public void testStructureFieldOrder() { + StructureFieldOrderInspector.batchCheckStructureGetFieldOrder(X11.class, null, true); + } + public static void main(java.lang.String[] argList) { junit.textui.TestRunner.run(X11Test.class); } diff --git a/test/com/sun/jna/StructureFieldOrderInspector.java b/test/com/sun/jna/StructureFieldOrderInspector.java index 4c4566f74e..463ac7c82c 100644 --- a/test/com/sun/jna/StructureFieldOrderInspector.java +++ b/test/com/sun/jna/StructureFieldOrderInspector.java @@ -30,6 +30,8 @@ import java.lang.reflect.*; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -56,7 +58,21 @@ private StructureFieldOrderInspector(){} */ public static void batchCheckStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, final List ignoreConstructorError) { - final Set> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch); + batchCheckStructureGetFieldOrder(classDeclaredInSourceTreeToSearch, ignoreConstructorError, false); + } + + /** + * Search for Structure sub types in the source tree of the given class, and validate the getFieldOrder() method, + * and collects all errors into one exception. + * + * @param classDeclaredInSourceTreeToSearch a class who's source tree will be searched for Structure sub types. + * @param ignoreConstructorError list of classname prefixes for which to ignore construction errors. + * @param onlyInnerClasses limit scan to inner classes of the supplied class + */ + public static void batchCheckStructureGetFieldOrder(final Class classDeclaredInSourceTreeToSearch, + final List ignoreConstructorError, + final boolean onlyInnerClasses) { + final Set> classes = StructureFieldOrderInspector.findSubTypesOfStructure(classDeclaredInSourceTreeToSearch, onlyInnerClasses); final List problems = new ArrayList(); @@ -96,7 +112,7 @@ public static void checkStructureGetFieldOrder(final Class classDeclaredInSou /** * Find all classes that extend {@link Structure}. */ - public static Set> findSubTypesOfStructure(final Class classDeclaredInSourceTreeToSearch) { + public static Set> findSubTypesOfStructure(final Class classDeclaredInSourceTreeToSearch, boolean onlyInnerClasses) { // use: http://code.google.com/p/reflections/ @@ -105,9 +121,24 @@ public static Set> findSubTypesOfStructure(final Clas .setUrls(ClasspathHelper.forClass(classDeclaredInSourceTreeToSearch)) ); - return reflections.getSubTypesOf(Structure.class); + Set> types = new HashSet>(reflections.getSubTypesOf(Structure.class)); + if(onlyInnerClasses) { + Iterator> it = types.iterator(); + while(it.hasNext()) { + if(! (it.next().getEnclosingClass() == classDeclaredInSourceTreeToSearch)) { + it.remove(); + } + } + } + return types; } + /** + * Find all classes that extend {@link Structure}. + */ + public static Set> findSubTypesOfStructure(final Class classDeclaredInSourceTreeToSearch) { + return findSubTypesOfStructure(classDeclaredInSourceTreeToSearch, false); + } public static void checkMethodGetFieldOrder(final Class structureSubType, final List ignoreConstructorError) { @@ -119,9 +150,6 @@ public static void checkMethodGetFieldOrder(final Class str return; } - final Method methodGetFieldOrder = getMethodGetFieldOrder(structureSubType); - - if (Modifier.isAbstract(structureSubType.getModifiers())) { // do not try to construct abstract Structure sub types return; @@ -161,58 +189,27 @@ public static void checkMethodGetFieldOrder(final Class str throw new RuntimeException("Could not instantiate Structure sub type: " + structureSubType.getName(), e); } - if (!methodGetFieldOrder.isAccessible()) { - methodGetFieldOrder.setAccessible(true); - } - final List methodCallFieldList; - try { - methodCallFieldList = (List) methodGetFieldOrder.invoke(structure); - } catch (IllegalAccessException e) { - throw new RuntimeException("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType.getName(), e); - } catch (InvocationTargetException e) { - throw new RuntimeException("Could not invoke getFieldOrder() on Structure sub type: " + structureSubType.getName(), e); - } + final List methodCallFieldOrder = structure.getFieldOrder(); - final Field[] actualFields = structureSubType.getFields(); // include fields from super classes - final List actualFieldNames = new ArrayList(actualFields.length); + final List actualFields = structure.getFieldList(); + final List actualFieldNames = new ArrayList(actualFields.size()); for (final Field field : actualFields) { // ignore static fields if (!Modifier.isStatic(field.getModifiers())) { final String actualFieldName = field.getName(); - if (!methodCallFieldList.contains(actualFieldName)) { - throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldList + if (!methodCallFieldOrder.contains(actualFieldName)) { + throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldOrder + "] does not include declared field: " + actualFieldName); } actualFieldNames.add(actualFieldName); } } - for (final Object methodCallField : methodCallFieldList) { + for (final String methodCallField : methodCallFieldOrder) { if (!actualFieldNames.contains(methodCallField)) { - throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldList + throw new IllegalArgumentException(structureSubType.getName() + ".getFieldOrder() [" + methodCallFieldOrder + "] includes undeclared field: " + methodCallField); } } } - - /** - * Find the getFieldOrder() method in the given class, or any of it's parents. - * @param structureSubType a structure sub type - * @return the getFieldOrder() method found in the given class, or any of it's parents. - */ - private static Method getMethodGetFieldOrder(Class structureSubType) { - final Method methodGetFieldOrder; - try { - methodGetFieldOrder = structureSubType.getDeclaredMethod("getFieldOrder", new Class[]{}); - } catch (NoSuchMethodException e) { - if (structureSubType.getSuperclass() != null) { - // look for method in parent - return getMethodGetFieldOrder((Class) structureSubType.getSuperclass()); - } - throw new IllegalArgumentException("The Structure sub type: " + structureSubType.getName() - + " must define the method: getFieldOrder()." - + " See the javadoc for Structure.getFieldOrder() for details.", e); - } - return methodGetFieldOrder; - } }