diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-09-09 16:44:17 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-09-09 16:44:17 +0200 |
commit | fc5ad1abc980bd5bec570ace8b6ac4fe68c8b816 (patch) | |
tree | 56bbc745bff03be2dbc6b1a6b55b373149d51402 | |
parent | 557c942a6cfee933140eef893889e2218897b26c (diff) |
Terminate jvm on Error during reconfiguration
This avoids entering a zombie state due to a destructive reconfiguration attempt.
LinkageError is exempted as that is a normal consequence of OSGi loading problems.
3 files changed, 15 insertions, 7 deletions
diff --git a/container-di/src/main/scala/com/yahoo/container/di/componentgraph/core/ComponentNode.scala b/container-di/src/main/scala/com/yahoo/container/di/componentgraph/core/ComponentNode.scala index 61f3c7a049c..16856930e54 100644 --- a/container-di/src/main/scala/com/yahoo/container/di/componentgraph/core/ComponentNode.scala +++ b/container-di/src/main/scala/com/yahoo/container/di/componentgraph/core/ComponentNode.scala @@ -99,14 +99,19 @@ class ComponentNode(componentId: ComponentId, constructor.newInstance(actualArguments: _*) } catch { case e: InvocationTargetException => - throw removeStackTrace(new RuntimeException(s"An exception occurred while constructing $idAndType", - cutStackTraceAtConstructor(e.getCause))) - + throw removeStackTrace(constructThrowable(cutStackTraceAtConstructor(e.getCause), s"Error constructing $idAndType")) } initId(instance) } - + + private def constructThrowable(cause: Throwable, message: String) : Throwable = { + if (cause != null && cause.isInstanceOf[Error]) // don't convert Errors to RuntimeExceptions + new Error(message, cause) + else + new RuntimeException(message, cause) + } + private def initId(component: AnyRef) = { def checkAndSetId(c: AbstractComponent) { if (c.hasInitializedId && c.getId != componentId ) diff --git a/container-di/src/main/scala/com/yahoo/container/di/package.scala b/container-di/src/main/scala/com/yahoo/container/di/package.scala index f1e2a35797e..ec621af3830 100644 --- a/container-di/src/main/scala/com/yahoo/container/di/package.scala +++ b/container-di/src/main/scala/com/yahoo/container/di/package.scala @@ -28,7 +28,7 @@ package object di { clazz.asInstanceOf[Class[SUPER]] } - def removeStackTrace(exception: RuntimeException): RuntimeException = { + def removeStackTrace(exception: Throwable): Throwable = { if (preserveStackTrace) exception else { exception.setStackTrace(Array()) diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java index 7dcbdfa251b..e602813c263 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java @@ -158,17 +158,20 @@ public final class ConfiguredApplication implements Application { private void startReconfigurerThread() { reconfigurerThread = new Thread(() -> { - while (!Thread.interrupted()) { + while ( ! Thread.interrupted()) { try { ContainerBuilder builder = createBuilderWithGuiceBindings(); configurer.runOnceAndEnsureRegistryHackRun(builder.guiceModules().activate()); intitializeAndActivateContainer(builder); } catch (ConfigInterruptedException | InterruptedException e) { break; - } catch (Exception e) { + } catch (Exception | LinkageError e) { // LinkageError: OSGi problems log.log(Level.SEVERE, "Reconfiguration failed, your application package must be fixed, unless this is a " + "JNI reload issue: " + Exceptions.toMessageString(e), e); + } catch (Error e) { + com.yahoo.protect.Process.logAndDie("java.lang.Error on reconfiguration: We are probably in " + + "a bad state and will terminate", e); } } log.fine("Shutting down HandlersConfigurerDi"); |