Skip to content

Commit 4cd8b64

Browse files
authored
Merge pull request #9 from Nuix/wrapper_shutdown_hook
Add shutdown hook
2 parents 9e10c19 + 6aff480 commit 4cd8b64

1 file changed

Lines changed: 42 additions & 13 deletions

File tree

Java/src/main/java/com/nuix/javaenginesimple/EngineWrapper.java

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* @author Jason Wells
2727
*
2828
*/
29-
public class EngineWrapper {
29+
public class EngineWrapper implements AutoCloseable {
3030
// Obtain a logger instance for this class
3131
private final static Logger logger = Logger.getLogger("EngineWrapper");
3232

@@ -35,6 +35,8 @@ public class EngineWrapper {
3535
private File nuixBaseDirectory = null;
3636
private Engine engine = null;
3737

38+
private Thread shutdownHook = null;
39+
3840
// We will use this while iterating licenses to determine which one to acquire.
3941
// By default this filter accepts any license.
4042
private LicenseFilter licenseFilter = new LicenseFilter();
@@ -55,6 +57,15 @@ public EngineWrapper(File nuixBaseDirectory){
5557
File engineLibDirectory = new File(nuixBaseDirectory,"lib");
5658
logger.info(String.format("Setting 'nuix.libdir' to: %s", engineLibDirectory.getAbsolutePath()));
5759
System.setProperty("nuix.libdir", engineLibDirectory.getAbsolutePath());
60+
61+
// Whenever we create an instance of the engine to hand over to the user, we will register
62+
// our shutdown hook to close this instance. This helps to ensure that the license is released
63+
// in some scenarios where the finally block may not execute, such as code calling System.exit before
64+
// returning from user provided Consumer<Utilities>.
65+
shutdownHook = new Thread(() -> {
66+
try { close(); } catch (Exception e)
67+
{ logger.error("Error in shutdown hook",e); }
68+
});
5869
}
5970

6071
/***
@@ -101,6 +112,11 @@ public void withDongleLicense(Consumer<Utilities> consumer) throws Exception{
101112
if(licenseObtained){
102113
Utilities utilities = engine.getUtilities();
103114
ThirdPartyDependencyChecker.logAllDependencyInfo(utilities);
115+
116+
// Setup our shutdown hook in case user terminates before consumer returns
117+
logger.info("Adding shutdown hook for EngineWrapper::close");
118+
Runtime.getRuntime().addShutdownHook(shutdownHook);
119+
104120
logger.info("License was obtained, providing Utilities object to consumer...");
105121
consumer.accept(utilities);
106122
}
@@ -112,10 +128,7 @@ public void withDongleLicense(Consumer<Utilities> consumer) throws Exception{
112128
logger.error("Error while creating Engine instance",engineException);
113129
throw engineException;
114130
} finally {
115-
if(engine != null){
116-
logger.info("Closing Engine instance...");
117-
engine.close();
118-
}
131+
close();
119132
}
120133
} catch (Exception globalContainerException) {
121134
logger.error("Error while creating GlobalContainer",globalContainerException);
@@ -209,6 +222,11 @@ public void execute(CredentialsCallbackInfo info) {
209222
if(licenseObtained){
210223
Utilities utilities = engine.getUtilities();
211224
ThirdPartyDependencyChecker.logAllDependencyInfo(utilities);
225+
226+
// Setup our shutdown hook in case user terminates before consumer returns
227+
logger.info("Adding shutdown hook for EngineWrapper::close");
228+
Runtime.getRuntime().addShutdownHook(shutdownHook);
229+
212230
logger.info("License was obtained, providing Utilities object to consumer...");
213231
consumer.accept(utilities);
214232
} else {
@@ -222,10 +240,7 @@ public void execute(CredentialsCallbackInfo info) {
222240
logger.error("Error while creating Engine instance",engineException);
223241
throw engineException;
224242
} finally {
225-
if(engine != null){
226-
logger.info("Closing Engine instance...");
227-
engine.close();
228-
}
243+
close();
229244
}
230245
} catch (Exception globalContainerException) {
231246
logger.error("Error while creating GlobalContainer",globalContainerException);
@@ -302,6 +317,11 @@ public void execute(CredentialsCallbackInfo info) {
302317
if(licenseObtained){
303318
Utilities utilities = engine.getUtilities();
304319
ThirdPartyDependencyChecker.logAllDependencyInfo(utilities);
320+
321+
// Setup our shutdown hook in case user terminates before consumer returns
322+
logger.info("Adding shutdown hook for EngineWrapper::close");
323+
Runtime.getRuntime().addShutdownHook(shutdownHook);
324+
305325
logger.info("License was obtained, providing Utilities object to consumer...");
306326
consumer.accept(utilities);
307327
} else {
@@ -315,10 +335,7 @@ public void execute(CredentialsCallbackInfo info) {
315335
logger.error("Error while creating Engine instance",engineException);
316336
throw engineException;
317337
} finally {
318-
if(engine != null){
319-
logger.info("Closing Engine instance...");
320-
engine.close();
321-
}
338+
close();
322339
}
323340
} catch (Exception globalContainerException) {
324341
logger.error("Error while creating GlobalContainer",globalContainerException);
@@ -477,4 +494,16 @@ public LicenseFilter getLicenseFilter() {
477494
public void setLicenseFilter(LicenseFilter licenseFilter) {
478495
this.licenseFilter = licenseFilter;
479496
}
497+
498+
@Override
499+
public void close() throws Exception {
500+
if(engine != null) {
501+
logger.info("Closing engine instance");
502+
engine.close();
503+
}
504+
505+
// Remove our shutdown hook since engine has now been closed
506+
logger.info("Removing shutdown hook to EngineWrapper::close");
507+
Runtime.getRuntime().removeShutdownHook(shutdownHook);
508+
}
480509
}

0 commit comments

Comments
 (0)