diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java
index 2aa752f57b..15de44afa6 100644
--- a/core/src/main/java/hudson/model/AbstractItem.java
+++ b/core/src/main/java/hudson/model/AbstractItem.java
@@ -603,7 +603,13 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
}
// try to reflect the changes by reloading
- new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshal(this);
+ Object o = new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshal(this);
+ if (o!=this) {
+ // ensure that we've got the same job type. extending this code to support updating
+ // to different job type requires destroying & creating a new job type
+ throw new IOException("Expecting "+this.getClass()+" but got "+o.getClass()+" instead");
+ }
+
Items.updatingByXml.set(true);
try {
onLoad(getParent(), getRootDir().getName());
diff --git a/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy b/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy
index a17d5965df..2cb0198a49 100644
--- a/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy
+++ b/test/src/test/groovy/hudson/model/AbstractProjectTest.groovy
@@ -27,7 +27,8 @@ import com.gargoylesoftware.htmlunit.ElementNotFoundException
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.WebRequestSettings
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlPage
+import hudson.maven.MavenModuleSet;
import hudson.security.*;
import hudson.tasks.BuildTrigger;
import hudson.tasks.Shell;
@@ -44,7 +45,7 @@ import hudson.util.StreamTaskListener;
import hudson.util.OneShotEvent
import jenkins.model.Jenkins;
import org.acegisecurity.context.SecurityContext;
-import org.acegisecurity.context.SecurityContextHolder;
+import org.acegisecurity.context.SecurityContextHolder
import org.jvnet.hudson.test.HudsonTestCase
import org.jvnet.hudson.test.Bug;
import org.jvnet.hudson.test.MemoryAssert;
@@ -515,4 +516,38 @@ public class AbstractProjectTest extends HudsonTestCase {
assert jenkins.getItem("regular")!=null;
assert jenkins.getItem("secret")!=null;
}
+
+
+ /**
+ * Trying to POST to config.xml by a different job type should fail.
+ */
+ public void testConfigDotXmlSubmissionToDifferentType() {
+ jenkins.crumbIssuer = null
+ def p = createFreeStyleProject()
+
+ HttpURLConnection con = postConfigDotXml(p, "")
+
+ // this should fail with a type mismatch error
+ // the error message should report both what was submitted and what was expected
+ assert con.responseCode == 500
+ def msg = con.errorStream.text
+ println msg
+ assert msg.contains(FreeStyleProject.class.name)
+ assert msg.contains(MavenModuleSet.class.name)
+
+ // control. this should work
+ con = postConfigDotXml(p, "")
+ assert con.responseCode == 200
+ }
+
+ private HttpURLConnection postConfigDotXml(FreeStyleProject p, String xml) {
+ HttpURLConnection con = new URL(getURL(), "job/${p.name}/config.xml").openConnection()
+ con.requestMethod = "POST"
+ con.setRequestProperty("Content-Type", "application/xml")
+ con.doOutput = true
+ con.outputStream.withStream { s ->
+ s.write(xml.bytes)
+ }
+ return con
+ }
}