Skip to content

Commit

Permalink
Merge branch 'master' into plugin-manager-dependants
Browse files Browse the repository at this point in the history
* master: (58 commits)
  Changelog: Replace the PR reference by the JIRA issue reference
  Noting #1818
  Noting #1804
  [JENKINS-30002] Improve Util.isOverridden
  Noting #1842
  [FIXED JENKINS-30777] this concludes the fix
  [JENKINS-30777] also allow slaves to decorate logger
  [JENKINS-30777] Generalized the signature to work with Run, not just AbstractBuild.
  Diamond operator
  [FIXED JENKINS-29876] CheckForNull job in ReverseBuildTrigger
  Noting JENKINS-30084 in changelog
  [JENKINS-30084] remove extra space
  [JENKINS-30084] address feedbacks
  [JENKINS-30084] indent back
  [JENKINS-30084] fixing test
  [JENKINS-30084] fixing test
  [JENKINS-30084] enhancing test case
  [JENKINS-30084] test added to make sure a flyweight task can be blocked at last minute
  [JENKINS-30084] fix regression when flyweight task is blocked by upstream/downstream project
  [JENKINS-30084] some more polish
  ...
  • Loading branch information
tfennelly committed Oct 5, 2015
2 parents 8dbee7b + 5b4b66d commit 955eb72
Show file tree
Hide file tree
Showing 27 changed files with 638 additions and 139 deletions.
19 changes: 18 additions & 1 deletion changelog.html
Expand Up @@ -55,7 +55,24 @@
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class="bug">
Optimize TagCloud size calculation.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-30705">issue 30705</a>)
<li class="bug">
FlyWeightTasks tied to a label will not cause node provisioning and will be blocked forever.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-30084">issue 30084</a>)
<li class="bug">
Prevent <code>NullPointerException</code> for disabled builds in <code>ReverseBuildTrigger</code>.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-29876">issue 29876</a>)
<li class="rfe">
ConsoleLogFilter wasn't truly global
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-30777">issue 30777</a>)
<li class="rfe">
API changes: <code>hudson.Util.isOverridden()</code> now supports protected methods.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-30002">issue 30002</a>)
<li class="bug">
Sidepanel controls with confirmation (<code>lib/layout/task</code>) did not assign the proper CSS style.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-30787">issue 30787</a>)
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v1.631>What's new in 1.631</a> (2015/09/27)</h3>
Expand Down
38 changes: 33 additions & 5 deletions core/src/main/java/hudson/Util.java
Expand Up @@ -26,28 +26,34 @@
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;

import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import hudson.Proc.LocalProc;
import hudson.model.TaskListener;
import hudson.os.PosixAPI;
import hudson.util.QuotedStringTokenizer;
import hudson.util.VariableResolver;
import hudson.util.jna.WinIOException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.types.FileSet;

import jnr.posix.FileStat;
import jnr.posix.POSIX;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
Expand All @@ -70,12 +76,14 @@
import java.util.regex.Pattern;

import hudson.util.jna.Kernel32Utils;

import static hudson.util.jna.GNUCLibrary.LIBC;

import java.security.DigestInputStream;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.commons.codec.digest.DigestUtils;

/**
Expand Down Expand Up @@ -1415,16 +1423,36 @@ public static Number tryParseNumber(@CheckForNull String numberStr, @CheckForNul
}

/**
* Checks if the public method defined on the base type with the given arguments
* are overridden in the given derived type.
* Checks if the method defined on the base type with the given arguments
* is overridden in the given derived type.
*/
public static boolean isOverridden(@Nonnull Class base, @Nonnull Class derived, @Nonnull String methodName, @Nonnull Class... types) {
return !getMethod(base, methodName, types).equals(getMethod(derived, methodName, types));
}

private static Method getMethod(@Nonnull Class clazz, @Nonnull String methodName, @Nonnull Class... types) {
Method res = null;
try {
return !base.getMethod(methodName, types).equals(
derived.getMethod(methodName,types));
res = clazz.getDeclaredMethod(methodName, types);
// private, static or final methods can not be overridden
if (res != null && (Modifier.isPrivate(res.getModifiers()) || Modifier.isFinal(res.getModifiers())
|| Modifier.isStatic(res.getModifiers()))) {
res = null;
}
} catch (NoSuchMethodException e) {
// Method not found in clazz, let's search in superclasses
Class superclass = clazz.getSuperclass();
if (superclass != null) {
res = getMethod(superclass, methodName, types);
}
} catch (SecurityException e) {
throw new AssertionError(e);
}
if (res == null) {
throw new IllegalArgumentException(
String.format("Method %s not found in %s (or it is private, final or static)", methodName, clazz.getName()));
}
return res;
}

/**
Expand Down
52 changes: 50 additions & 2 deletions core/src/main/java/hudson/console/ConsoleLogFilter.java
Expand Up @@ -26,11 +26,14 @@

import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.Computer;
import hudson.model.Run;
import hudson.tasks.BuildWrapper;
import hudson.util.ArgumentListBuilder;
import jenkins.model.Jenkins;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.io.OutputStream;

Expand All @@ -48,8 +51,53 @@ public abstract class ConsoleLogFilter implements ExtensionPoint {
/**
* Called on the start of each build, giving extensions a chance to intercept
* the data that is written to the log.
*
* @deprecated as of 1.632. Use {@link #decorateLogger(Run, OutputStream)}
*/
public abstract OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException;
public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException {
if (Util.isOverridden(ConsoleLogFilter.class, getClass(), "decorateLogger", Run.class, OutputStream.class)) {
// old client calling newer implementation. forward the call.
return decorateLogger((Run) build, logger);
} else {
// happens only if the subtype fails to override neither decorateLogger method
throw new AssertionError("The plugin '" + this.getClass().getName() + "' still uses " +
"deprecated decorateLogger(AbstractBuild,OutputStream) method. " +
"Update the plugin to use setUp(Run,OutputStream) instead.");
}
}

/**
* Called on the start of each build, giving extensions a chance to intercept
* the data that is written to the log.
*
* <p>
* Even though this method is not marked 'abstract', this is the method that must be overridden
* by extensions.
*/
public OutputStream decorateLogger(Run build, OutputStream logger) throws IOException, InterruptedException {
// this implementation is backward compatibility thunk in case subtypes only override the
// old signature (AbstractBuild,OutputStream)

if (build instanceof AbstractBuild) {
// maybe the plugin implements the old signature.
return decorateLogger((AbstractBuild) build, logger);
} else {
// this ConsoleLogFilter can only decorate AbstractBuild, so just pass through
return logger;
}
}

/**
* Called to decorate logger for master/slave communication.
*
* @param computer
* Slave computer for which the logger is getting decorated. Useful to do
* contextual decoration.
* @since 1.632
*/
public OutputStream decorateLogger(@Nonnull Computer computer, OutputStream logger) throws IOException, InterruptedException {
return logger; // by default no-op
}

/**
* All the registered {@link ConsoleLogFilter}s.
Expand Down
10 changes: 8 additions & 2 deletions core/src/main/java/hudson/model/Label.java
Expand Up @@ -85,6 +85,7 @@ public abstract class Label extends Actionable implements Comparable<Label>, Mod
protected transient final String name;
private transient volatile Set<Node> nodes;
private transient volatile Set<Cloud> clouds;
private transient volatile int tiedJobsCount;

@Exported
public transient final LoadStatistics loadStatistics;
Expand Down Expand Up @@ -369,13 +370,17 @@ public List<AbstractProject> getTiedJobs() {
}

/**
* Returns a count of projects that are tied on this node. In a system without security this should be the same
* Returns an approximate count of projects that are tied on this node.
*
* In a system without security this should be the same
* as {@code getTiedJobs().size()} but significantly faster as it involves fewer temporary objects and avoids
* sorting the intermediary list. In a system with security, this will likely return a higher value as it counts
* all jobs (mostly) irrespective of access.
* @return a count of projects that are tied on this node.
*/
public int getTiedJobCount() {
if (tiedJobsCount != -1) return tiedJobsCount;

// denormalize for performance
// we don't need to respect security as much when returning a simple count
SecurityContext context = ACL.impersonate(ACL.SYSTEM);
Expand Down Expand Up @@ -412,7 +417,7 @@ public int getTiedJobCount() {
}
}
}
return result;
return tiedJobsCount = result;
} finally {
SecurityContextHolder.setContext(context);
}
Expand All @@ -433,6 +438,7 @@ public boolean isEmpty() {
/*package*/ void reset() {
nodes = null;
clouds = null;
tiedJobsCount = -1;
}

/**
Expand Down

0 comments on commit 955eb72

Please sign in to comment.