Skip to content
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

Merged
merged 2 commits into from
Jun 23, 2017

Conversation

varyvol
Copy link

@varyvol varyvol commented May 16, 2017

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

@ghost
Copy link

ghost commented May 16, 2017

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.

@varyvol
Copy link
Author

varyvol commented Jun 7, 2017

@yacaovsnc did you have the opportunity to review these changes?

@yacaovsnc
Copy link
Contributor

+@davidstaheli

@jpricket
Copy link
Contributor

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.
Thanks for this contribution!

@jpricket jpricket merged commit f763aad into jenkinsci:master Jun 23, 2017
@varyvol
Copy link
Author

varyvol commented Jun 26, 2017

@jpricketMSFT Thank you!

Copy link
Member

@oleg-nenashev oleg-nenashev left a 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")
Copy link
Member

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")
Copy link
Member

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();
Copy link
Member

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;
Copy link
Member

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

Copy link
Author

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.

Copy link
Member

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 {
Copy link
Member

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

Copy link
Author

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

Copy link
Member

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

Copy link
Member

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")
Copy link
Member

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

Copy link
Author

@varyvol varyvol Jun 27, 2017

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;
Copy link
Member

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 🐜

Copy link
Author

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.

Copy link
Member

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

Copy link
Member

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.

Copy link
Member

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

@varyvol
Copy link
Author

varyvol commented Jun 27, 2017

@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;
Copy link
Member

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();
Copy link
Member

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants