From 388ff8b2e0fea1e758ed5685d535e26b7a6131a9 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Fri, 2 Aug 2024 14:29:59 +0200 Subject: [PATCH 1/2] [New] allowing configuring shutdown hook The shutdown hook is hooked into the JVM and is executed when the JVM stops. This can be beneficial when the application is not managing pi4j's life cycle, but when an application wants to properly manage the life cycle, then this can be detrimental to the shutdown sequence of the application. This change allows such an application to disable this feature. The shutdown hook is still enabled by default, a future version might decide to disable it by default. --- .../java/com/pi4j/context/ContextBuilder.java | 28 +++++++++++++++++++ .../java/com/pi4j/context/ContextConfig.java | 6 ++++ .../context/impl/DefaultContextBuilder.java | 21 ++++++++++++++ .../com/pi4j/runtime/impl/DefaultRuntime.java | 20 +++++++------ 4 files changed, 66 insertions(+), 9 deletions(-) diff --git a/pi4j-core/src/main/java/com/pi4j/context/ContextBuilder.java b/pi4j-core/src/main/java/com/pi4j/context/ContextBuilder.java index 02084f58..3fc675df 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/ContextBuilder.java +++ b/pi4j-core/src/main/java/com/pi4j/context/ContextBuilder.java @@ -147,6 +147,34 @@ default ContextBuilder setAutoInject(boolean autoInject){ return noAutoInject(); } + /** + *

enableShutdownHook.

+ * + * @return a {@link com.pi4j.context.ContextBuilder} object. + */ + ContextBuilder enableShutdownHook(); + + /** + *

disableShutdownHook.

+ * + * @return a {@link com.pi4j.context.ContextBuilder} object. + */ + ContextBuilder disableShutdownHook(); + + /** + *

setShutdownHook.

+ * + * @param enableShutdownHook a boolean. + * + * @return a {@link com.pi4j.context.ContextBuilder} object. + */ + default ContextBuilder setShutdownHook(boolean enableShutdownHook) { + if (enableShutdownHook) + return enableShutdownHook(); + else + return disableShutdownHook(); + } + /** *

toConfig.

* diff --git a/pi4j-core/src/main/java/com/pi4j/context/ContextConfig.java b/pi4j-core/src/main/java/com/pi4j/context/ContextConfig.java index 7f4f4b17..d4875e72 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/ContextConfig.java +++ b/pi4j-core/src/main/java/com/pi4j/context/ContextConfig.java @@ -86,6 +86,12 @@ default Collection getPlatforms(){ * @return a boolean. */ boolean autoInject(); + /** + *

enableShutdownHook.

+ * + * @return a boolean. + */ + boolean enableShutdownHook(); /** *

getAutoInject.

* diff --git a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java index 1316376a..6fd93f72 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java +++ b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java @@ -54,6 +54,7 @@ public class DefaultContextBuilder implements ContextBuilder { protected boolean autoDetectPlatforms = false; protected boolean autoDetectProviders = false; protected boolean autoInject = false; + protected boolean enableShutdownHook = true; // default platform identifier protected String defaultPlatformId = null; @@ -157,6 +158,20 @@ public ContextBuilder noAutoInject() { return this; } + /** {@inheritDoc} */ + @Override + public ContextBuilder enableShutdownHook() { + this.enableShutdownHook = true; + return this; + } + + /** {@inheritDoc} */ + @Override + public ContextBuilder disableShutdownHook() { + this.enableShutdownHook = false; + return this; + } + /** {@inheritDoc} */ @Override public ContextBuilder property(String key, String value){ @@ -258,11 +273,17 @@ public String defaultPlatform() { public boolean autoDetectMockPlugins() { return builder.autoDetectMockPlugins; } + @Override public boolean autoDetectPlatforms() { return builder.autoDetectPlatforms; } + @Override + public boolean enableShutdownHook() { + return builder.enableShutdownHook; + } + @Override public boolean autoInject() { return builder.autoInject; } diff --git a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java index 1dffb9c0..2eb82817 100644 --- a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java +++ b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java @@ -110,15 +110,17 @@ private DefaultRuntime(Context context) { // listen for shutdown to properly clean up // TODO :: ADD PI4J INTERNAL SHUTDOWN CALLBACKS/EVENTS - java.lang.Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try { - // shutdown Pi4J - if (!isShutdown) - shutdown(); - } catch (Exception e) { - logger.error("Failed to shutdown Pi4J runtime", e); - } - }, "pi4j-shutdown")); + if (this.context.config().enableShutdownHook()) { + java.lang.Runtime.getRuntime().addShutdownHook(new Thread(() -> { + try { + // shutdown Pi4J + if (!isShutdown) + shutdown(); + } catch (Exception e) { + logger.error("Failed to shutdown Pi4J runtime", e); + } + }, "pi4j-shutdown")); + } } /** From 1535055d417d58a4295b629ef6adc546f732a067 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 5 Aug 2024 08:16:13 +0200 Subject: [PATCH 2/2] [Minor] shutdown hook is disabled by default --- .../main/java/com/pi4j/context/impl/DefaultContextBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java index 6fd93f72..cd88e7f7 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java +++ b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContextBuilder.java @@ -54,7 +54,7 @@ public class DefaultContextBuilder implements ContextBuilder { protected boolean autoDetectPlatforms = false; protected boolean autoDetectProviders = false; protected boolean autoInject = false; - protected boolean enableShutdownHook = true; + protected boolean enableShutdownHook = false; // default platform identifier protected String defaultPlatformId = null;