diff --git a/org.eclipse.osgitech.rest.jetty/pom.xml b/org.eclipse.osgitech.rest.jetty/pom.xml
index 49a54f6..93cd445 100644
--- a/org.eclipse.osgitech.rest.jetty/pom.xml
+++ b/org.eclipse.osgitech.rest.jetty/pom.xml
@@ -74,6 +74,10 @@
org.apache.felix
org.apache.felix.http.jetty
+
+ org.crac
+ crac
+
@@ -117,6 +121,27 @@
+
+ biz.aQute.bnd
+ bnd-maven-plugin
+ true
+
+
+ jar
+
+ jar
+
+
+
+
+
+
+
biz.aQute.bnd
bnd-resolver-maven-plugin
diff --git a/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyBackedWhiteboardComponent.java b/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyBackedWhiteboardComponent.java
index 9775122..90e6ead 100644
--- a/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyBackedWhiteboardComponent.java
+++ b/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyBackedWhiteboardComponent.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2012 - 2022 Data In Motion and others.
+ * Copyright (c) 2012 - 2024 Data In Motion and others.
* All rights reserved.
*
* This program and the accompanying materials are made available under the terms of the
@@ -10,6 +10,7 @@
* Data In Motion - initial API and implementation
* Stefan Bishof - API and implementation
* Tim Ward - implementation
+ * Dirk Fauth - add CRaC support
*/
package org.eclipse.osgitech.rest.jetty;
@@ -62,6 +63,10 @@ public class JettyBackedWhiteboardComponent {
Logger logger = Logger.getLogger(JettyBackedWhiteboardComponent.class.getName());
private JerseyServiceRuntime serviceRuntime;
+
+ // need to keep a strong reference to avoid that the resource gets garbage collected
+ @SuppressWarnings("unused")
+ private JettyCracResource cracHandler;
public enum State {
INIT, STARTED, STOPPED, EXCEPTION
@@ -93,6 +98,17 @@ public void activate(BundleContext context, Map properties) thro
serviceRuntime.start(getServiceRuntimeProperties(properties));
+
+ try {
+ Class.forName("org.crac.Resource");
+
+ // org.crac.Resource was found, so we create an instance of the JettyCracResource
+ cracHandler = new JettyCracResource(this);
+ } catch (ClassNotFoundException e) {
+ // org.crac.Resource could not be found
+ // we simply do nothing, as CRaC support is not available
+ }
+
}
private Map getServiceRuntimeProperties(Map properties) {
@@ -348,4 +364,12 @@ private void stopServer() {
logger.log(Level.SEVERE, "Error stopping Jetty server", e);
}
}
+
+ /**
+ *
+ * @return the Jetty server managed by this class. Can be null
.
+ */
+ Server getJettyServer() {
+ return jettyServer;
+ }
}
diff --git a/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyCracResource.java b/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyCracResource.java
new file mode 100644
index 0000000..6f41ff2
--- /dev/null
+++ b/org.eclipse.osgitech.rest.jetty/src/main/java/org/eclipse/osgitech/rest/jetty/JettyCracResource.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2024 Dirk Fauth and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the terms of the
+ * Eclipse Public License v2.0 which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Dirk Fauth - initial API and implementation
+ */
+package org.eclipse.osgitech.rest.jetty;
+
+import java.util.Arrays;
+
+import org.crac.Context;
+import org.crac.Core;
+import org.crac.Resource;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.util.component.LifeCycle;
+
+/**
+ * This class is used to add CRaC support to the jetty bundle by using the
+ * org.crac
API. It adapts the examples and best practices from the
+ * CRaC documentation and the examples.
+ *
+ * @see `org.crac` API
+ * @see Implementing
+ * Resource as Inner Class
+ * @see Step-by-step
+ * CRaC support for a Jetty app
+ * @see CRaC
+ * example-jetty
+ */
+public class JettyCracResource {
+
+ // the org.crac.Resource is implemented as an inner class and kept as a strong
+ // reference to avoid that it is garbage collected after the registration.
+ private Resource cracHandler;
+
+ public JettyCracResource(JettyBackedWhiteboardComponent jettyComponent) {
+ cracHandler = new Resource() {
+ @Override
+ public void beforeCheckpoint(Context extends Resource> context) {
+ Server jettyServer = jettyComponent.getJettyServer();
+ if (jettyServer != null && !jettyServer.isStopped()) {
+ // Stop the connectors only and keep the expensive application running
+ Arrays.asList(jettyServer.getConnectors()).forEach(c -> LifeCycle.stop(c));
+ }
+ }
+
+ @Override
+ public void afterRestore(Context extends Resource> context) {
+ Server jettyServer = jettyComponent.getJettyServer();
+ if (jettyServer != null && !jettyServer.isStopped()) {
+ Arrays.asList(jettyServer.getConnectors()).forEach(c -> LifeCycle.start(c));
+ }
+ }
+ };
+ Core.getGlobalContext().register(cracHandler);
+ }
+}
diff --git a/pom.xml b/pom.xml
index f5c3e49..8c06386 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,6 +69,7 @@
9.5
2.15.2
1.1.5
+ 1.5.0
@@ -464,6 +465,12 @@
biz.aQute.bnd.annotation
6.4.0
+
+ org.crac
+ crac
+ ${crac.version}
+ provided
+