-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-40807] Fix Findbugs errors #162
Conversation
This pull request originates from a CloudBees employee. At CloudBees, we require that all pull requests be reviewed by other CloudBees employees before we seek to have the change accepted. If you want to learn more about our process please see this explanation. |
@yacaovsnc did you have the opportunity to review these changes? |
Hi @varyvol, I am taking over from yacaovsnc. All of the changes seem reasonable. Unfortunately, I pushed some of my own changes before see this. So, I probably introduced some additional errors. I plan on merging your changes and then fixes my errors so we can get down to zero again. |
@jpricketMSFT Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Belated 🐛 for making fields transient. From what I see it impacts persistency of actions on the disk.
@@ -25,6 +26,7 @@ | |||
public class ChangeSetReader extends ChangeLogParser { | |||
|
|||
@Override | |||
@SuppressFBWarnings(value = "DM_DEFAULT_ENCODING", justification = "Better mot modify charset in case it might raise errors") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be better to explicitly use the System default then
@@ -51,6 +52,7 @@ public void setRequestedResults(final List<TeamRequestedResult> requestedResults | |||
this.requestedResults = requestedResults; | |||
} | |||
|
|||
@SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "No matter the result of mkdirs") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? This is a correct issue. Ideally a Java 7 Files
API should be used instead
@@ -391,7 +391,7 @@ public boolean pollChanges(AbstractProject hudsonProject, Launcher launcher, Fil | |||
@Override | |||
public boolean processWorkspaceBeforeDeletion(AbstractProject<?, ?> project, FilePath workspace, Node node) throws IOException, InterruptedException { | |||
Run<?,?> lastRun = project.getLastBuild(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can explicitly use AbstractBuild
here, there is no need to cast the type later
@@ -24,7 +24,7 @@ | |||
private static final long serialVersionUID = 1L; | |||
private static final String URL_NAME = "team-pullRequestMergedDetails"; | |||
|
|||
public GitPullRequestEx gitPullRequest; | |||
public transient GitPullRequestEx gitPullRequest; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐛 It is going to break the event persistence on the disk, because the field won't be stored anymore.
And this action is persisted from what I see
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitPullRequestEx is not serializable so in case someone was serializing it, it would have already broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Serializable" is not required for persisting the data on the disk. My concern is that my making the class formally serializable you may break the data persistency
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
|
||
public class GitCodePushedEventArgs { | ||
public class GitCodePushedEventArgs implements Serializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It breaks the compatibility, because the class is not final.
If you make it serializable, also define the serialVersionID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does adding an interface break the compatibility? My understanding is that you can add them, being the removal the problematic thing.
https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serializable is a special case. If you add this interface, all child classes must become serializable as well. And there is no guarantee they really can support it.
Fromt the binary compatibility standpoint it is compatible, of course
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well you have to consider whether this is a plausible situation where someone might have subclassed it to begin with.
import hudson.Extension; | ||
import hudson.util.Secret; | ||
import org.kohsuke.stapler.DataBoundConstructor; | ||
|
||
@SuppressFBWarnings(value = "SE_TRANSIENT_FIELD_NOT_RESTORED", justification = "Maintain compatibility") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should have been readResolve() then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolving to what? It's not something that can be predicted I think.
Also there are tests that are specifically checking the serialization generates an empty CredentialsConfigurer (that's why I did not removed the transient).
@@ -45,17 +45,23 @@ public BuildWorkspaceConfiguration getLatestForNode(Node needleNode, Run<?,?> la | |||
|
|||
public static class BuildWorkspaceConfiguration extends WorkspaceConfiguration { | |||
private static final long serialVersionUID = 1L; | |||
private final AbstractBuild<?, ?> build; | |||
private final transient AbstractBuild<?, ?> build; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what is the use-case for this class, but it may also break persistency on the disk 🐜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractBuild is not serializable so this could have never been serialized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serialization is not required for persistency via XStream. That engine is different.
Persisting builds likely ends up with a relative link in XML, e.g. "../..". By making the field transient you are just removing it from XML at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually due to lazy loading issues there are cases where including a nontransient
field of type Run
will cause serious errors, so it is mandatory to make this transient
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the persisted Build instance is a bad thing in any case. But the one who solves that has to ensure the plugin's logic does not suffer. Rejuice methods or whatever. It is not enough to just make the field transient
@oleg-nenashev I have answered some of your comments. I will create another PR with some fixes based on others. |
@@ -45,17 +45,23 @@ public BuildWorkspaceConfiguration getLatestForNode(Node needleNode, Run<?,?> la | |||
|
|||
public static class BuildWorkspaceConfiguration extends WorkspaceConfiguration { | |||
private static final long serialVersionUID = 1L; | |||
private final AbstractBuild<?, ?> build; | |||
private final transient AbstractBuild<?, ?> build; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serialization is not required for persistency via XStream. That engine is different.
Persisting builds likely ends up with a relative link in XML, e.g. "../..". By making the field transient you are just removing it from XML at all
|
||
public BuildWorkspaceConfiguration(WorkspaceConfiguration configuration, AbstractBuild<?, ?> build) { | ||
super(configuration); | ||
this.build = build; | ||
} | ||
|
||
public void save() throws IOException { | ||
if (!workspaceExists()) { | ||
build.getAction(WorkspaceConfiguration.class).setWorkspaceWasRemoved(); | ||
} | ||
build.save(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
risk of NPE after the change?
JENKINS-40807
After JENKINS-40806, Findbugs is run as part of the build. However, such builds does not fail if any error arise.
This change revert that behaviour and fixes/suppresses already present errors.
@reviewbybees @yacaovsnc