I've been facing the JENKINS-45892 issue in my logs since November, but as it's not so urgent, I just found time to investigate this issue. After each build with "Publish last changes" post-build step I see the following error:

      JENKINS-45892: reference to hudson.model.FreeStyleProject@14a187[testing/test-last-changes] being saved from unexpected /var/lib/jenkins/jobs/testing/jobs/test-last-changes/builds/2/build.xml
      java.lang.IllegalStateException
      	at hudson.XmlFile.replaceIfNotAtTopLevel(XmlFile.java:223)
      	at hudson.model.AbstractItem.writeReplace(AbstractItem.java:492)
      	at sun.reflect.GeneratedMethodAccessor471.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:498)
      	at com.thoughtworks.xstream.converters.reflection.SerializationMethodInvoker.callWriteReplace(SerializationMethodInvoker.java:89)
      	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:141)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
      	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
      	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
      	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
      	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
      	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
      	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
      	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
      	at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:74)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
      	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
      	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
      	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
      	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
      	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
      	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:88)
      	at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
      	at com.thoughtworks.xstream.converters.collections.CollectionConverter.marshal(CollectionConverter.java:74)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:84)
      	at hudson.util.RobustReflectionConverter.marshallField(RobustReflectionConverter.java:265)
      	at hudson.util.RobustReflectionConverter$2.writeField(RobustReflectionConverter.java:252)
      	at hudson.util.RobustReflectionConverter$2.visit(RobustReflectionConverter.java:224)
      	at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:138)
      	at hudson.util.RobustReflectionConverter.doMarshal(RobustReflectionConverter.java:209)
      	at hudson.util.RobustReflectionConverter.marshal(RobustReflectionConverter.java:150)
      	at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:69)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:58)
      	at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:43)
      	at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:82)
      	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37)
      	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1026)
      	at com.thoughtworks.xstream.XStream.marshal(XStream.java:1015)
      	at com.thoughtworks.xstream.XStream.toXML(XStream.java:988)
      	at hudson.XmlFile.write(XmlFile.java:194)
      	at hudson.model.Run.save(Run.java:1923)
      	at hudson.model.Run.execute(Run.java:1784)
      	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
      	at hudson.model.ResourceController.execute(ResourceController.java:97)
      	at hudson.model.Executor.run(Executor.java:429)
      

      Stacktrace is the same in each job, so I paste it only once.

      Steps to reproduce issue*:*

      1. Create a FreeStyle Job
      2. Add GIT repository (tested with bitbucket)
      3. Add some build step (can be just shell step - echo some word)
      4. Add post-build action "Publish Last Changes"
      5. Save and run job
      6. Go to the Jenkins logs after the job is ended.
      7. Find the last log, which should have something like this:
      Feb 05, 2018 10:30:37 AM INFO hudson.model.Run execute
      testing/test-last-changes #2 main build action completed: SUCCESS
      Feb 05, 2018 10:30:37 AM WARNING hudson.XmlFile replaceIfNotAtTopLevel
      JENKINS-45892: reference to hudson.model.FreeStyleProject@14a187[testing/test-last-changes] being saved from unexpected /var/lib/jenkins/jobs/testing/jobs/test-last-changes/builds/2/build.xml
      java.lang.IllegalStateException

      Jenkins version: latest (2.104), but issue has been being existed at least since 2.92
      Last Changes Plugin version: latest (2.6), but issue has been being existed at least since 2.3

          [JENKINS-49368] Last Changes causes the JENKINS-45892

          Hi oleg_nenashev, you nailed it. Thank you one more time!

          I'll do some more tests and release v2.6.1 containing the fix.

          Rafael Pestano added a comment - Hi oleg_nenashev , you nailed it. Thank you one more time! I'll do some more tests and release v2.6.1 containing the fix.

          Oleg Nenashev added a comment -

          rmpestano FYI https://github.com/jenkinsci/last-changes-plugin/commit/0cb6083a31b207099c5400e4f4a93bee8510f3a5 will not work correctly after the Jenkins restart. The class has no readResolve() resolution, so the value will be null when you save new jobs and reload them from the disk. It will cause NPEs in methods like getLastChangesBuilds().

          I would actually suggest modifying getJob() to restore the field if null and then switch all the code to using this method instead of the direct field access. Your mileage may vary

          Oleg Nenashev added a comment - rmpestano FYI https://github.com/jenkinsci/last-changes-plugin/commit/0cb6083a31b207099c5400e4f4a93bee8510f3a5 will not work correctly after the Jenkins restart. The class has no readResolve() resolution, so the value will be null when you save new jobs and reload them from the disk. It will cause NPEs in methods like getLastChangesBuilds(). I would actually suggest modifying getJob() to restore the field if null and then switch all the code to using this method instead of the direct field access. Your mileage may vary

          Rafael Pestano added a comment - - edited

          Hi Oleg,

          Yes, this issue after restart always happened. Although no NPE is raised the list from getLastChangesBuilds comes empty and only is populated after user runs the job again.

          Can you point me to an example of how to implement the readResolve to restore the list form disk?

          Thank you!

          Rafael Pestano added a comment - - edited Hi Oleg, Yes, this issue after restart always happened. Although no NPE is raised the list from getLastChangesBuilds comes empty and only is populated after user runs the job again. Can you point me to an example of how to implement the readResolve to restore the list form disk? Thank you!

          Oleg Nenashev added a comment -

          rmpestano https://wiki.jenkins.io/display/JENKINS/Hint+on+retaining+backward+compatibility, but maybe you do not need that:

          > I would actually suggest modifying getJob() to restore the field if null and then switch all the code to using this method instead of the direct field access. Your mileage may vary

          Oleg Nenashev added a comment - rmpestano https://wiki.jenkins.io/display/JENKINS/Hint+on+retaining+backward+compatibility , but maybe you do not need that: > I would actually suggest modifying getJob() to restore the field if null and then switch all the code to using this method instead of the direct field access. Your mileage may vary

          oleg_nenashev I've looked into the "xstream" stuff and did not figured out how to "restore the field".

          If you want to provide a PR or point to a plugin which does that I'll be happy to fix.

          Meanwhile I'll create another issue for that case.

          Rafael Pestano added a comment - oleg_nenashev I've looked into the "xstream" stuff and did not figured out how to "restore the field". If you want to provide a PR or point to a plugin which does that I'll be happy to fix. Meanwhile I'll create another issue for that case.

          Just created JENKINS-50116.

          Rafael Pestano added a comment - Just created  JENKINS-50116 .

          ewypych, can you try with v2.6.1 and share the results?

           

          Rafael Pestano added a comment - ewypych , can you try with v2.6.1 and share the results?  

          Emil Wypych added a comment -

          rmpestano yes, sure, I will do it today, but at evening (~9 P.M. CET). I will give you feedback when I'm done.  Thank you very much for fast release!

          Emil Wypych added a comment - rmpestano yes, sure, I will do it today, but at evening (~9 P.M. CET). I will give you feedback when I'm done.  Thank you very much for fast release!

          Emil Wypych added a comment -

          rmpestano I've just updated Last Changes Plugin and made some tests - I confirm that problem was solved. Now I just see SUCCESS:

          main build action completed: SUCCESS
          

          Tested with few different jobs. Do you need something else, or is it enough for confirmation? 

          Also thank you very much for resolving this issue - logs look much better.  

          Emil Wypych added a comment - rmpestano I've just updated Last Changes Plugin and made some tests - I confirm that problem was solved. Now I just see SUCCESS: main build action completed: SUCCESS Tested with few different jobs. Do you need something else, or is it enough for confirmation?  Also thank you very much for resolving this issue - logs look much better.  

          Hi ewypych, that's enough, I'll close the issue.

          Thank you very much for reporting and testing.

          Rafael Pestano added a comment - Hi ewypych , that's enough, I'll close the issue. Thank you very much for reporting and testing.

            rmpestano Rafael Pestano
            ewypych Emil Wypych
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: