- * This is useful in conjunction with {@link FormValidation}. + * Same as {@link #validateAntFileMask(String, int)} with (practically) unbounded number of operations. * * @return * null if no error was found. Otherwise returns a human readable error message. @@ -2907,28 +2906,45 @@ public String validateAntFileMask(final String fileMasks) throws IOException, In } /** - * Same as {@link #validateAntFileMask(String, int, boolean)} with caseSensitive set to true + * Same as {@link #validateAntFileMask(String, int, boolean)} with caseSensitive set to true. */ public String validateAntFileMask(final String fileMasks, final int bound) throws IOException, InterruptedException { return validateAntFileMask(fileMasks, bound, true); } + /** + * Same as {@link #validateAntFileMask(String, int, boolean)} with the default number of operations. + * @see #VALIDATE_ANT_FILE_MASK_BOUND + * @since TODO + */ + public String validateAntFileMask(final String fileMasks, final boolean caseSensitive) throws IOException, InterruptedException { + return validateAntFileMask(fileMasks, VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive); + } + /** * Default bound for {@link #validateAntFileMask(String, int, boolean)}. * @since 1.592 */ - @SuppressFBWarnings("MS_SHOULD_BE_FINAL") + @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") public static int VALIDATE_ANT_FILE_MASK_BOUND = SystemProperties.getInteger(FilePath.class.getName() + ".VALIDATE_ANT_FILE_MASK_BOUND", 10000); /** - * Like {@link #validateAntFileMask(String)} but performing only a bounded number of operations. + * Validates the ant file mask (like "foo/bar/*.txt, zot/*.jar") against this directory, and try to point out the problem. + * This performs only a bounded number of operations. + * *
Whereas the unbounded overload is appropriate for calling from cancelable, long-running tasks such as build steps, * this overload should be used when an answer is needed quickly, such as for {@link #validateFileMask(String)} * or anything else returning {@link FormValidation}. + * *
If a positive match is found, {@code null} is returned immediately. * A message is returned in case the file pattern can definitely be determined to not match anything in the directory within the alloted time. * If the time runs out without finding a match but without ruling out the possibility that there might be one, {@link InterruptedException} is thrown, * in which case the calling code should give the user the benefit of the doubt and use {@link hudson.util.FormValidation.Kind#OK} (with or without a message). + * + *
While this can be used in conjunction with {@link FormValidation}, it's generally better to use {@link #validateFileMask(String)} and
+ * its overloads for use in {@code doCheck} form validation methods related to workspaces, as that performs an appropriate permission check.
+ * Callers of this method or its overloads from web methods should ensure permissions are checked before this method is invoked.
+ *
* @param bound a maximum number of negative operations (deliberately left vague) to perform before giving up on a precise answer; try {@link #VALIDATE_ANT_FILE_MASK_BOUND}
* @throws InterruptedException not only in case of a channel failure, but also if too many operations were performed without finding any matches
* @since 1.484
@@ -2936,7 +2952,7 @@ public String validateAntFileMask(final String fileMasks, final int bound) throw
public @CheckForNull String validateAntFileMask(final String fileMasks, final int bound, final boolean caseSensitive) throws IOException, InterruptedException {
return act(new ValidateAntFileMask(fileMasks, caseSensitive, bound));
}
- private class ValidateAntFileMask extends MasterToSlaveFileCallable Note that this permission check may not always make sense based on the directory provided;
+ * callers should consider using {@link #validateFileMask(FilePath, String, boolean)} and its overloads instead
+ * (once appropriate permission checks have succeeded).
+ *
* @since 1.294
*/
public FormValidation validateFileMask(String value, boolean errorIfNotExist, boolean caseSensitive) throws IOException {
@@ -3175,8 +3196,12 @@ public FormValidation validateFileMask(String value, boolean errorIfNotExist, bo
/**
* Validates a relative file path from this {@link FilePath}.
- * Requires configure permission on ancestor AbstractProject object in request,
- * or admin permission if no such ancestor is found.
+ * Requires configure permission on ancestor {@link AbstractProject} object in request,
+ * or {@link Jenkins#MANAGE} permission if no such ancestor is found.
+ *
+ * Note that this permission check may not always make sense based on the directory provided;
+ * callers should consider using {@link #validateFileMask(FilePath, String, boolean)} and its overloads instead
+ * (once appropriate permission checks have succeeded).
*
* @param value
* The relative path being validated.
@@ -3298,7 +3323,7 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound
private static final long serialVersionUID = 1L;
- @SuppressFBWarnings("MS_SHOULD_BE_FINAL")
+ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "TODO needs triage")
public static int SIDE_BUFFER_SIZE = 1024;
private static final Logger LOGGER = Logger.getLogger(FilePath.class.getName());
diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java
index 2242112cb6a0..2d54d3358f92 100644
--- a/core/src/main/java/hudson/Functions.java
+++ b/core/src/main/java/hudson/Functions.java
@@ -187,7 +187,7 @@ public class Functions {
private static Logger LOGGER = Logger.getLogger(Functions.class.getName());
@Restricted(NoExternalUse.class)
- @SuppressFBWarnings("MS_SHOULD_BE_FINAL")
+ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static /* non-final */ boolean UI_REFRESH = SystemProperties.getBoolean("jenkins.ui.refresh");
public Functions() {
@@ -636,7 +636,7 @@ public static String getYuiSuffix() {
/**
* Set to true if you need to use the debug version of YUI.
*/
- @SuppressFBWarnings("MS_SHOULD_BE_FINAL")
+ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static boolean DEBUG_YUI = SystemProperties.getBoolean("debug.YUI");
/**
diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java
index 85fc42ea5b9e..57de28f89d5e 100644
--- a/core/src/main/java/hudson/Launcher.java
+++ b/core/src/main/java/hudson/Launcher.java
@@ -27,6 +27,7 @@
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Proc.LocalProc;
import hudson.Proc.ProcWithJenkins23271Patch;
import hudson.model.Computer;
@@ -1504,6 +1505,7 @@ private static EnvVars inherit(@NonNull Map To use this class loader, set {@code pluginFirstClassLoader} to {@code true} in the {@code
+ * maven-hpi-plugin} configuration.
+ *
+ * @author Basil Crow
+ */
+@Restricted(NoExternalUse.class)
+public class PluginFirstClassLoader2 extends URLClassLoader2 {
+ static {
+ registerAsParallelCapable();
+ }
+
+ public PluginFirstClassLoader2(@NonNull URL[] urls, @NonNull ClassLoader parent) {
+ super(Objects.requireNonNull(urls), Objects.requireNonNull(parent));
+ }
+
+ /**
+ * Load the class with the specified binary name. This method searches for classes in the
+ * following order:
+ *
+ * Invoke {@link #findLoadedClass(String)} to check if the class has already been
+ * loaded.
+ * Invoke {@link #findClass(String)} to find the class.
+ * Invoke {@link #loadClass(String)} on the parent class loader.
+ * If the class was found using the above steps and the {@code resolve} flag is true, this
+ * method will then invoke {@link #resolveClass(Class)} on the resulting {@link Class} object.
+ *
+ * This method synchronizes on the result of {@link #getClassLoadingLock(String)} during the
+ * entire class loading process.
+ *
+ * @param name The binary name of the class
+ * @param resolve If {@code true} then resolve the class
+ * @return The resulting {@link Class} object
+ * @throws ClassNotFoundException If the class could not be found
+ */
+ @Override
+ protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ synchronized (getClassLoadingLock(name)) {
+ Class> c = findLoadedClass(name);
+ if (c == null) {
+ try {
+ c = findClass(name);
+ } catch (ClassNotFoundException e) {
+ // ignore
+ }
+ }
+ if (c == null) {
+ c = getParent().loadClass(name);
+ }
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ }
+
+ /**
+ * Find the resource with the given name. A resource is some data (images, audio, text, etc)
+ * that can be accessed by class code in a way that is independent of the location of the code.
+ *
+ * The name of a resource is a '{@code /}'-separated path name that identifies the resource.
+ * This method searches for resources in the following order:
+ *
+ * Invoke {@link #findResource(String)} to find the resource.
+ * Invoke {@link #getResource(String)} on the parent class loader.
+ * The name of a resource is a {@code /}-separated path name that identifies the resource.
+ * This method first invokes {@link #findResources(String)} to find the resources with the name
+ * in this class loader. Finally, it invokes {@link #getResources(String)} on the parent class
+ * loader. It returns an enumeration whose elements are the {@link URL}s found by searching the
+ * {@link URL}s found with {@link #findResources(String)}, followed by the {@link URL}s found by
+ * searching the parent class loader.
+ *
+ * @param name The resource name
+ * @return An enumeration of {@link URL} objects for the resource. If no resources could be
+ * found, the enumeration will be empty. Resources for which a {@link URL} cannot be
+ * constructed, which are in a package that is not opened unconditionally, or for which
+ * access to the resource is denied by the security manager, are not returned in the
+ * enumeration.
+ * @throws IOException If I/O errors occur
+ * @throws NullPointerException If {@code name} is {@code null}
+ */
+ @Override
+ public Enumeration
* See JENKINS-22346.
*/
- @SuppressFBWarnings("MS_SHOULD_BE_FINAL")
+ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static boolean ALLOW_NON_EXISTENT_USER_TO_LOGIN = SystemProperties.getBoolean(User.class.getName() + ".allowNonExistentUserToLogin");
/**
@@ -157,7 +157,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr
* SECURITY-406.
*/
@Restricted(NoExternalUse.class)
- @SuppressFBWarnings("MS_SHOULD_BE_FINAL")
+ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static boolean ALLOW_USER_CREATION_VIA_URL = SystemProperties.getBoolean(User.class.getName() + ".allowUserCreationViaUrl");
/**
diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java
index 9363e881013e..fc94dd9af333 100644
--- a/core/src/main/java/hudson/model/View.java
+++ b/core/src/main/java/hudson/model/View.java
@@ -29,6 +29,7 @@
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.StreamException;
import edu.umd.cs.findbugs.annotations.NonNull;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.ExtensionPoint;
@@ -65,6 +66,7 @@
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringWriter;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
@@ -78,6 +80,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -104,7 +107,6 @@
import net.sf.json.JSONObject;
import org.apache.commons.jelly.JellyContext;
import org.apache.commons.lang.StringUtils;
-import org.apache.tools.ant.filters.StringInputStream;
import org.jenkins.ui.icon.Icon;
import org.jenkins.ui.icon.IconSet;
import org.kohsuke.accmod.Restricted;
@@ -1317,6 +1319,7 @@ public static List
- * This version allows one to read while writing is in progress.
- *
- * @author Kohsuke Kawaguchi
- * @deprecated since 2008-05-28. Moved to stapler
- */
-@Deprecated
-public class ByteBuffer extends OutputStream {
- private byte[] buf = new byte[8192];
- /**
- * Size of the data.
- */
- private int size = 0;
-
-
- @Override
- public synchronized void write(byte[] b, int off, int len) throws IOException {
- ensureCapacity(len);
- System.arraycopy(b,off,buf,size,len);
- size+=len;
- }
-
- @Override
- public synchronized void write(int b) throws IOException {
- ensureCapacity(1);
- buf[size++] = (byte)b;
- }
-
- public synchronized long length() {
- return size;
- }
-
- private void ensureCapacity(int len) {
- if(buf.length-size>len)
- return;
-
- byte[] n = new byte[Math.max(buf.length*2, size+len)];
- System.arraycopy(buf,0,n,0,size);
- this.buf = n;
- }
-
- @Override
- public synchronized String toString() {
- return new String(buf,0,size);
- }
-
- /**
- * Writes the contents of this buffer to another OutputStream.
- */
- public synchronized void writeTo(OutputStream os) throws IOException {
- os.write(buf,0,size);
- }
-
- /**
- * Creates an {@link InputStream} that reads from the underlying buffer.
- */
- public InputStream newInputStream() {
- return new InputStream() {
- private int pos = 0;
- @Override
- public int read() throws IOException {
- synchronized(ByteBuffer.this) {
- if(pos>=size) return -1;
- return buf[pos++];
- }
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- synchronized(ByteBuffer.this) {
- if(size==pos)
- return -1;
-
- int sz = Math.min(len,size-pos);
- System.arraycopy(buf,pos,b,off,sz);
- pos+=sz;
- return sz;
- }
- }
-
-
- @Override
- public int available() throws IOException {
- synchronized(ByteBuffer.this) {
- return size-pos;
- }
- }
-
- @Override
- public long skip(long n) throws IOException {
- synchronized(ByteBuffer.this) {
- int diff = (int) Math.min(n,size-pos);
- pos+=diff;
- return diff;
- }
- }
- };
- }
-}
diff --git a/core/src/main/java/hudson/util/CompoundEnumeration.java b/core/src/main/java/hudson/util/CompoundEnumeration.java
index 6de29d96e5ae..c1679f7a26c7 100644
--- a/core/src/main/java/hudson/util/CompoundEnumeration.java
+++ b/core/src/main/java/hudson/util/CompoundEnumeration.java
@@ -1,6 +1,7 @@
package hudson.util;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -21,6 +22,11 @@ public CompoundEnumeration(Enumeration... e) {
public CompoundEnumeration(Iterable Only suitable for listener methods which do not throw checked or otherwise documented exceptions.
+ * @param ${%Or} ${%Or}
+ *
+ *
+ *
+ *
+ *
+ * @param name The resource name
+ * @return {@link URL} object for reading the resource; {@code null} if the resource could not
+ * be found, a {@link URL} could not be constructed to locate the resource, the resource is
+ * in a package that is not opened unconditionally, or access to the resource is denied by
+ * the security manager.
+ * @throws NullPointerException If {@code name} is {@code null}
+ */
+ @Override
+ public URL getResource(String name) {
+ Objects.requireNonNull(name);
+ URL url = findResource(name);
+ if (url == null) {
+ url = getParent().getResource(name);
+ }
+ return url;
+ }
+
+ /**
+ * Find all the resources with the given name. A resource is some data (images, audio, text,
+ * etc) that can be accessed by class code in a way that is independent of the location of the
+ * code.
+ *
+ * ${%HTTP Proxy Configuration}
- ${%Deploy Plugin}
- ${%HTTP Proxy Configuration}
+ ${%Deploy Plugin}
+ ${%Update Site}
- ${%Update Site}
+ ${%Other Sites}
+
${%Other Sites}
-
-
-