- 
    Bug 
- 
    Resolution: Fixed
- 
    Major 
FingerprintAction has the following field:
private final AbstractBuild build;
This field links to an AbstractBuild, which in turn has the following field:
protected transient final JobT project;
Once Jenkin persists a run to a file, the build from the FingerprintAction will be saved, but the project itself will not get saved. An example fragment from one of the build files looks like this:
<hudson.tasks.Fingerprinter_-FingerprintAction> <build class="build"> <actions> <hudson.model.ParametersAction reference="../../../../hudson.model.ParametersAction"/> <hudson.model.CauseAction reference="../../../../hudson.model.CauseAction"/> <hudson.plugins.copyartifact.CopyArtifact_-EnvAction reference="../../../../hudson.plugins.copyartifact.CopyArtifact_-EnvAction"/> <hudson.tasks.Fingerprinter_-FingerprintAction reference="../../.."/> </actions> <number>17</number> <startTime>1358250655935</startTime> <result>SUCCESS</result> <duration>4488</duration> <charset>UTF-8</charset> <keepLog>false</keepLog> <builtOn></builtOn> <workspace>/opt/hudson/files/jobs/Deploy/workspace</workspace> <hudsonVersion>1.494</hudsonVersion> <scm class="hudson.scm.NullChangeLogParser"/> <culprits class="com.google.common.collect.EmptyImmutableSortedSet"/> </build> ...
When the files are read and the objects are created, the project field remains empty. During intialization, the onLoad() method is called:
    @Override
    protected R retrieve(File d) throws IOException {
        if(new File(d,"build.xml").exists()) {
            // if the build result file isn't in the directory, ignore it.
            try {
                R b = cons.create(d);
                b.onLoad();
                if (LOGGER.isLoggable(FINE))
                    LOGGER.log(FINE,"Loaded " + b.getFullDisplayName(),new ThisIsHowItsLoaded());
                return b;
            } catch (IOException e) {
                LOGGER.log(Level.WARNING, "could not load " + d, e);
            } catch (InstantiationError e) {
                LOGGER.log(Level.WARNING, "could not load " + d, e);
            }
        }
        return null;
    }
This method invokes onLoad() on all actions that implement RunAction:
for (Action a : getActions()) if (a instanceof RunAction) ((RunAction) a).onLoad();
The FingerprintAction does implement the RunAction interface, and the method is implemented as follows:
public void onLoad() { // share data structure with nearby builds, but to keep lazy loading efficient, // don't go back the history forever. if (rand.nextInt(2)!=0) { Run pb = build.getPreviousBuild(); if (pb!=null) { FingerprintAction a = pb.getAction(FingerprintAction.class); if (a!=null) compact(a); } } }
Build is set, so getPreviousBuild() can be called, this will however fail because the project is null (due to the transient field) and will throw a NullPointerException.
This causes very strange behavior as sometimes pages are working, sometimes they are not. There are a lot of stack traces around that actually look like as if they were caused by the same problem, for example: https://issues.jenkins-ci.org/browse/JENKINS-16845
Stack Trace looks like this:
Caused by: java.lang.NullPointerException at hudson.model.AbstractBuild.getPreviousBuild(AbstractBuild.java:207) at hudson.tasks.Fingerprinter$FingerprintAction.onLoad(Fingerprinter.java:349) at hudson.model.Run.onLoad(Run.java:315) at hudson.model.RunMap.retrieve(RunMap.java:221) at hudson.model.RunMap.retrieve(RunMap.java:59) at jenkins.model.lazy.AbstractLazyLoadRunMap.load(AbstractLazyLoadRunMap.java:638) at jenkins.model.lazy.AbstractLazyLoadRunMap.load(AbstractLazyLoadRunMap.java:601) at jenkins.model.lazy.AbstractLazyLoadRunMap.search(AbstractLazyLoadRunMap.java:344) at hudson.model.AbstractBuild.getPreviousBuild(AbstractBuild.java:207) at hudson.model.AbstractBuild.getPreviousBuild(AbstractBuild.java:100) at hudson.model.RunMap$1.next(RunMap.java:107) at hudson.model.RunMap$1.next(RunMap.java:96) at hudson.widgets.HistoryWidget.getRenderList(HistoryWidget.java:133) ... 122 more
- is duplicated by
- 
                    JENKINS-16845 NullPointer in getPreviousBuild -         
- Resolved
 
-         
- is related to
- 
                    JENKINS-18410 Use RunAction2 from TestResultAction -         
- Resolved
 
-         
- 
                    JENKINS-18411 Use RunAction2 from EnvInjectPluginAction -         
- Resolved
 
-         
- 
                    JENKINS-20950 NPE during Discard Old Data -         
- Resolved
 
-         
- relates to
- 
                    JENKINS-43218 Discard Unreadable Data leads to NPE in TreeMap.putAll -         
- Resolved
 
-         
- 
                    JENKINS-45892 Forbid nested references to model objects -         
- Resolved
 
-