diff --git a/changelog.html b/changelog.html
index 0ac6cb55e579c72578e8996df1b404d0316abd0e..c750db553a983b0e2667fa1f9bff857d9700065e 100644
--- a/changelog.html
+++ b/changelog.html
@@ -63,6 +63,9 @@ Upcoming changes
+ -
+ Fixed a possible dead lock problem in deleting projects.
+ (issue 19446)
-
HTML metacharacters not escaped in log messages.
(issue 20800)
diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java
index fd3b2693aafe90e31bbc151981405e6e743d2d5e..44f9993945fe47ef4a865d8ce34ad0ae5ebe5d21 100644
--- a/core/src/main/java/hudson/model/AbstractItem.java
+++ b/core/src/main/java/hudson/model/AbstractItem.java
@@ -42,6 +42,7 @@ import hudson.util.AlternativeUiTextProvider.Message;
import hudson.util.AtomicFileWriter;
import hudson.util.IOUtils;
import jenkins.model.Jenkins;
+import jenkins.model.Jenkins.MasterComputer;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;
import org.kohsuke.stapler.WebMethod;
@@ -510,21 +511,23 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
checkPermission(DELETE);
performDelete();
- try {
- invokeOnDeleted();
- } catch (AbstractMethodError e) {
- // ignore
- }
-
- Jenkins.getInstance().rebuildDependencyGraphAsync();
- }
+ // defer the notification to avoid the lock ordering problem. See JENKINS-19446.
+ MasterComputer.threadPoolForRemoting.submit(new java.util.concurrent.Callable() {
+ @Override
+ public Void call() throws Exception {
+ invokeOnDeleted();
+ Jenkins.getInstance().rebuildDependencyGraphAsync();
+ return null;
+ }
- /**
- * A pointless function to work around what appears to be a HotSpot problem. See JENKINS-5756 and bug 6933067
- * on BugParade for more details.
- */
- private void invokeOnDeleted() throws IOException {
- getParent().onDeleted(this);
+ /**
+ * A pointless function to work around what appears to be a HotSpot problem. See JENKINS-5756 and bug 6933067
+ * on BugParade for more details.
+ */
+ private void invokeOnDeleted() throws IOException {
+ getParent().onDeleted(AbstractItem.this);
+ }
+ });
}
/**