Skip to content

Commit

Permalink
Replace addSuppressed with a reflection based variant
Browse files Browse the repository at this point in the history
addSuppressed was added to Throwable in JDK7, to be compatible with
Java 6 it can't be called directly. To replace the functionality
reflection is used. A helper method "addSuppressedRelfected" was
introduced into the only class, that currently uses suppressed 
exceptions (Win32Exception).
  • Loading branch information
matthiasblaesing committed Nov 18, 2017
1 parent e700fbf commit d17f153
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ public static Account[] getCurrentUserGroups() {
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}
}
Expand Down Expand Up @@ -2443,7 +2443,7 @@ public static boolean accessCheck(File file, AccessCheckPermission permissionToC
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public static byte[] cryptUnprotectData(byte[] data, byte[] entropy, int flags,
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}
}
Expand All @@ -162,7 +162,7 @@ public static byte[] cryptUnprotectData(byte[] data, byte[] entropy, int flags,
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ public static BufferedImage getScreenshot(HWND target) {
if (result == null || WinGDI.HGDI_ERROR.equals(result)) {
Win32Exception ex = new Win32Exception(Native.getLastError());
if (we != null) {
ex.addSuppressed(we);
ex.addSuppressedReflected(we);
}
we = ex;
}
Expand All @@ -163,7 +163,7 @@ public static BufferedImage getScreenshot(HWND target) {
if (!GDI32.INSTANCE.DeleteObject(hBitmap)) {
Win32Exception ex = new Win32Exception(Native.getLastError());
if (we != null) {
ex.addSuppressed(we);
ex.addSuppressedReflected(we);
}
we = ex;
}
Expand All @@ -174,7 +174,7 @@ public static BufferedImage getScreenshot(HWND target) {
if (!GDI32.INSTANCE.DeleteDC(hdcTargetMem)) {
Win32Exception ex = new Win32Exception(Native.getLastError());
if (we != null) {
ex.addSuppressed(we);
ex.addSuppressedReflected(we);
}
we = ex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public static void closeHandleRefs(HANDLEByReference... refs) {
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}
}
Expand Down Expand Up @@ -148,7 +148,7 @@ public static void closeHandles(HANDLE... handles) {
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}
}
Expand Down Expand Up @@ -341,7 +341,7 @@ public static int getFileType(String fileName) throws FileNotFoundException {
if (err == null) {
err = e;
} else {
err.addSuppressed(e);
err.addSuppressedReflected(e);
}
}

Expand Down Expand Up @@ -905,7 +905,7 @@ public static byte[] getResource(String path, String type, String name) {
if (!Kernel32.INSTANCE.FreeLibrary(target)) {
Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());
if (err != null) {
we.addSuppressed(err);
we.addSuppressedReflected(err);
}
throw we;
}
Expand Down Expand Up @@ -1013,7 +1013,7 @@ public boolean invoke(HMODULE module, Pointer type, Pointer name, Pointer lParam
if (!Kernel32.INSTANCE.FreeLibrary(target)) {
Win32Exception we = new Win32Exception(Kernel32.INSTANCE.GetLastError());
if (err != null) {
we.addSuppressed(err);
we.addSuppressedReflected(err);
}
throw we;
}
Expand Down Expand Up @@ -1075,7 +1075,7 @@ public static List<Tlhelp32.MODULEENTRY32W> getModules(int processID) {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@

import com.sun.jna.LastErrorException;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Win32 exception.
Expand Down Expand Up @@ -69,4 +73,31 @@ protected Win32Exception(int code, HRESULT hr, String msg) {
super(code, msg);
_hr = hr;
}

private static Method addSuppressedMethod = null;
static {
try {
addSuppressedMethod = Throwable.class.getMethod("addSuppressed", Throwable.class);
} catch (NoSuchMethodException ex) {
// This is the case for JDK < 7
} catch (SecurityException ex) {
Logger.getLogger(Win32Exception.class.getName()).log(Level.SEVERE, "Failed to initialize 'addSuppressed' method", ex);
}
}

void addSuppressedReflected(Throwable exception) {
if(addSuppressedMethod == null) {
// Make this a NOOP on an unsupported JDK
return;
}
try {
addSuppressedMethod.invoke(this, exception);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to call addSuppressedMethod", ex);
} catch (IllegalArgumentException ex) {
throw new RuntimeException("Failed to call addSuppressedMethod", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to call addSuppressedMethod", ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public static Map<String, String> getCache() {
if (!Wininet.INSTANCE.FindCloseUrlCache(cacheHandle)) {
if (we != null) {
Win32Exception e = new Win32Exception(Native.getLastError());
e.addSuppressed(we);
e.addSuppressedReflected(we);
we = e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public static PRINTER_INFO_2 getPrinterInfo2(String printerName) {
if (!Winspool.INSTANCE.ClosePrinter(pHandle.getValue())) {
Win32Exception ex = new Win32Exception(Kernel32.INSTANCE.GetLastError());
if (we != null) {
ex.addSuppressed(we);
ex.addSuppressedReflected(we);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1552,7 +1552,7 @@ public void testModule32FirstW() {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}

Expand Down Expand Up @@ -1589,7 +1589,7 @@ public void testModule32NextW() {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public void testEnumProcessModules() {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}
if (we != null) {
Expand Down Expand Up @@ -186,7 +186,7 @@ public void testGetModuleInformation() {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}
if (we != null) {
Expand Down Expand Up @@ -218,7 +218,7 @@ public void testGetProcessImageFileName() {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
we.addSuppressedReflected(e);
}
}
if (we != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.sun.jna.LastErrorException;

import junit.framework.TestCase;
import org.junit.Assume;

/**
* @author dblock[at]dblock[dot]org
Expand Down Expand Up @@ -50,8 +51,27 @@ public void testFormatMessageFromHR() {
}
}

public void testAddSuppressed() {
Assume.assumeTrue(isMethodPresent(Win32Exception.class, "addSuppressed", Throwable.class));

Win32Exception demoException = new Win32Exception(WinError.E_FAIL);
demoException.addSuppressed(new RuntimeException("Demo"));

assertEquals(1, demoException.getSuppressed().length);
assertEquals("Demo", demoException.getSuppressed()[0].getMessage());
}

private void assertLastErrorValue(LastErrorException e, int code, String msg) {
assertEquals("Mismatched error code", code, e.getErrorCode());
assertEquals("Mismatched error message", msg, e.getMessage());
}

private boolean isMethodPresent(Class<?> baseClass, String methodName, Class... parameters) throws SecurityException {
try {
baseClass.getMethod(methodName, parameters);
return true;
} catch (NoSuchMethodException ex) {
return false;
}
}
}

0 comments on commit d17f153

Please sign in to comment.