diff --git a/netcdf4/src/main/java/ucar/nc2/ffi/netcdf/NetcdfClibrary.java b/netcdf4/src/main/java/ucar/nc2/ffi/netcdf/NetcdfClibrary.java index 5f76264537..d721c046d3 100644 --- a/netcdf4/src/main/java/ucar/nc2/ffi/netcdf/NetcdfClibrary.java +++ b/netcdf4/src/main/java/ucar/nc2/ffi/netcdf/NetcdfClibrary.java @@ -6,7 +6,9 @@ package ucar.nc2.ffi.netcdf; import com.google.common.base.Strings; +import com.sun.jna.Library; import com.sun.jna.Native; +import java.lang.reflect.Proxy; import javax.annotation.Nullable; import ucar.nc2.jni.netcdf.Nc4prototypes; import ucar.nc2.jni.netcdf.Nc4wrapper; @@ -128,6 +130,21 @@ public static synchronized int setLogLevel(int level) { return oldlevel; } + /** + * Closes the netCDF-C native library. + * + *
+ * Call this method to ensure JNA can shut down its cleaner thread; otherwise JVM shutdown may be blocked. + *
+ */ + public static synchronized void shutdown() { + if (nc4 != null) { + Library.Handler lh = (Library.Handler) Proxy.getInvocationHandler(nc4); + lh.getNativeLibrary().close(); + nc4 = null; + } + } + private static Nc4prototypes load() { if (nc4 == null) { if (jnaPath == null) { diff --git a/uicdm/src/main/java/ucar/nc2/ui/ToolsUI.java b/uicdm/src/main/java/ucar/nc2/ui/ToolsUI.java index 6a02447f19..28f764de5c 100644 --- a/uicdm/src/main/java/ucar/nc2/ui/ToolsUI.java +++ b/uicdm/src/main/java/ucar/nc2/ui/ToolsUI.java @@ -16,6 +16,7 @@ import ucar.nc2.dods.DODSNetcdfFile; import ucar.nc2.dt.GridDataset; import ucar.nc2.dt.RadialDatasetSweep; +import ucar.nc2.ffi.netcdf.NetcdfClibrary; import ucar.nc2.ft.point.PointDatasetImpl; import ucar.nc2.ft2.coverage.*; import ucar.nc2.grib.GribIndexCache; @@ -1312,6 +1313,10 @@ public void run(Object o) { public static void exit() { doSavePrefsAndUI(); + // close netCDF-C library, if loaded + if (NetcdfClibrary.isLibraryPresent()) { + NetcdfClibrary.shutdown(); + } System.exit(0); }