diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index b0596a66374d..f22fb7b08e7a 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -64,9 +64,6 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -337,24 +334,7 @@ public FileAndDescription(File file,String description) { * @return the File alongside with some description to help the user troubleshoot issues */ public FileAndDescription getHomeDir(ServletContextEvent event) { - // check JNDI for the home directory first - for (String name : HOME_NAMES) { - try { - InitialContext iniCtxt = new InitialContext(); - Context env = (Context) iniCtxt.lookup("java:comp/env"); - String value = (String) env.lookup(name); - if(value!=null && value.trim().length()>0) - return new FileAndDescription(new File(value.trim()),"JNDI/java:comp/env/"+name); - // look at one more place. See issue JENKINS-1314 - value = (String) iniCtxt.lookup(name); - if(value!=null && value.trim().length()>0) - return new FileAndDescription(new File(value.trim()),"JNDI/"+name); - } catch (NamingException e) { - // ignore - } - } - - // next the system property + // check the system property for the home directory first for (String name : HOME_NAMES) { String sysProp = SystemProperties.getString(name); if(sysProp!=null) diff --git a/core/src/main/java/hudson/model/Item.java b/core/src/main/java/hudson/model/Item.java index 445c83998482..d9ba493dc02b 100644 --- a/core/src/main/java/hudson/model/Item.java +++ b/core/src/main/java/hudson/model/Item.java @@ -26,6 +26,7 @@ import edu.umd.cs.findbugs.annotations.CheckForNull; import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import hudson.Functions; import hudson.Util; import hudson.search.SearchableModelObject; @@ -39,7 +40,6 @@ import jenkins.model.Jenkins; import jenkins.util.SystemProperties; import jenkins.util.io.OnMaster; -import jline.internal.Nullable; import org.kohsuke.stapler.StaplerRequest; /** diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index 49561adba5b5..acb4455cb3c3 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -1522,6 +1522,7 @@ public Collection getBuildFingerprints() { * * @since 1.349 */ + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", justification = "method signature does not permit plumbing through the return value") public void writeLogTo(long offset, @NonNull XMLOutput out) throws IOException { long start = offset; if (offset > 0) { diff --git a/core/src/main/java/hudson/model/queue/BackFiller.java b/core/src/main/java/hudson/model/queue/BackFiller.java deleted file mode 100644 index ec59903ea51b..000000000000 --- a/core/src/main/java/hudson/model/queue/BackFiller.java +++ /dev/null @@ -1,209 +0,0 @@ -package hudson.model.queue; - -import hudson.Extension; -import hudson.model.Computer; -import hudson.model.Executor; -import hudson.model.InvisibleAction; -import hudson.model.Queue.BuildableItem; -import hudson.model.queue.MappingWorksheet.ExecutorChunk; -import hudson.model.queue.MappingWorksheet.ExecutorSlot; -import hudson.model.queue.MappingWorksheet.Mapping; -import hudson.model.queue.MappingWorksheet.WorkChunk; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.stream.StreamSupport; -import jenkins.model.Jenkins; -import jenkins.util.SystemProperties; - -/** - * Experimental. - * - * @author Kohsuke Kawaguchi - */ -public class BackFiller extends LoadPredictor { - private boolean recursion = false; - - @Override - public Iterable predict(MappingWorksheet plan, Computer computer, long start, long end) { - TimeRange timeRange = new TimeRange(start, end - start); - List loads = new ArrayList<>(); - - for (BuildableItem bi : Jenkins.get().getQueue().getBuildableItems()) { - TentativePlan tp = bi.getAction(TentativePlan.class); - if (tp==null) {// do this even for bi==plan.item ensures that we have FIFO semantics in tentative plans. - tp = makeTentativePlan(bi); - if (tp==null) continue; // no viable plan. - } - - if (tp.isStale()) { - // if the tentative plan is stale, just keep on pushing it to the current time - // (if we recreate the plan, it'll be put at the end of the queue, whereas this job - // should actually get priority over others) - tp.range.shiftTo(System.currentTimeMillis()); - } - - // don't let its own tentative plan count when considering a scheduling for a job - if (plan.item==bi) continue; - - - // no overlap in the time span, meaning this plan is for a distant future - if (!timeRange.overlapsWith(tp.range)) continue; - - // if this tentative plan has no baring on this computer, that's ignorable - Integer i = tp.footprint.get(computer); - if (i==null) continue; - - return Collections.singleton(tp.range.toFutureLoad(i)); - } - - return loads; - } - - private static final class PseudoExecutorSlot extends ExecutorSlot { - private Executor executor; - - private PseudoExecutorSlot(Executor executor) { - this.executor = executor; - } - - @Override - public Executor getExecutor() { - return executor; - } - - @Override - public boolean isAvailable() { - return true; - } - - // this slot isn't executable - @Override - protected void set(WorkUnit p) { - throw new UnsupportedOperationException(); - } - } - - private TentativePlan makeTentativePlan(BuildableItem bi) { - if (recursion) return null; - recursion = true; - try { - // pretend for now that all executors are available and decide some assignment that's executable. - List slots = new ArrayList<>(); - for (Computer c : Jenkins.get().getComputers()) { - if (c.isOffline()) continue; - for (Executor e : c.getExecutors()) { - slots.add(new PseudoExecutorSlot(e)); - } - } - - // also ignore all load predictions as we just want to figure out some executable assignment - // and we are not trying to figure out if this task is executable right now. - MappingWorksheet worksheet = new MappingWorksheet(bi, slots, Collections.emptyList()); - Mapping m = Jenkins.get().getQueue().getLoadBalancer().map(bi.task, worksheet); - if (m==null) return null; - - // figure out how many executors we need on each computer? - Map footprint = new HashMap<>(); - for (Map.Entry e : m.toMap().entrySet()) { - Computer c = e.getValue().computer; - Integer v = footprint.get(c); - if (v==null) v = 0; - v += e.getKey().size(); - footprint.put(c,v); - } - - // the point of a tentative plan is to displace other jobs to create a point in time - // where this task can start executing. An incorrectly estimated duration is not - // a problem in this regard, as we just need enough idle executors in the right moment. - // The downside of guessing the duration wrong is that we can end up creating tentative plans - // afterward that may be incorrect, but those plans will be rebuilt. - long d = bi.task.getEstimatedDuration(); - if (d<=0) d = TimeUnit.MINUTES.toMillis(5); - - TimeRange slot = new TimeRange(System.currentTimeMillis(), d); - - // now, based on the real predicted loads, figure out the approximation of when we can - // start executing this guy. - for (Map.Entry e : footprint.entrySet()) { - Computer computer = e.getKey(); - Timeline timeline = new Timeline(); - for (LoadPredictor lp : LoadPredictor.all()) { - StreamSupport.stream(lp.predict(worksheet, computer, slot.start, slot.end).spliterator(), false).limit(100).forEach(fl -> - timeline.insert(fl.startTime, fl.startTime + fl.duration, fl.numExecutors)); - } - - Long x = timeline.fit(slot.start, slot.duration, computer.countExecutors()-e.getValue()); - // if no suitable range was found in [slot.start,slot.end), slot.end would be a good approximation - if (x==null) x = slot.end; - slot = slot.shiftTo(x); - } - - TentativePlan tp = new TentativePlan(footprint, slot); - bi.addAction(tp); - return tp; - } finally { - recursion = false; - } - } - - /** - * Represents a duration in time. - */ - private static final class TimeRange { - public final long start; - public final long duration; - public final long end; - - private TimeRange(long start, long duration) { - this.start = start; - this.duration = duration; - this.end = start+duration; - } - - public boolean overlapsWith(TimeRange that) { - return (this.start <= that.start && that.start <=this.end) - || (that.start <= this.start && this.start <=that.end); - } - - public FutureLoad toFutureLoad(int size) { - return new FutureLoad(start,duration,size); - } - - public TimeRange shiftTo(long newStart) { - if (newStart==start) return this; - return new TimeRange(newStart,duration); - } - } - - public static final class TentativePlan extends InvisibleAction { - private final Map footprint; - public final TimeRange range; - - public TentativePlan(Map footprint, TimeRange range) { - this.footprint = footprint; - this.range = range; - } - - public Object writeReplace() {// don't persist - return null; - } - - public boolean isStale() { - return range.end < System.currentTimeMillis(); - } - } - - /** - * Once this feature stabilizes, move it to the heavyjob plugin - */ - @Extension - public static BackFiller newInstance() { - if (SystemProperties.getBoolean(BackFiller.class.getName())) - return new BackFiller(); - return null; - } -} diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index e3dc7fc355cf..fb2fa9916eb4 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -323,10 +323,6 @@ public List invoke(File baseDir, VirtualChannel channel) throws IOExcept private void record(Run build, FilePath ws, TaskListener listener, Map record, final String targets) throws IOException, InterruptedException { for (Record r : ws.act(new FindRecords(targets, excludes, defaultExcludes, caseSensitive, build.getTimeInMillis()))) { Fingerprint fp = r.addRecord(build); - if(fp==null) { - listener.error(Messages.Fingerprinter_FailedFor(r.relativePath)); - continue; - } fp.addFor(build); record.put(r.relativePath,fp.getHashString()); } diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index c6339c225140..9d100094fef2 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -479,6 +479,7 @@ public AnnotatedLargeText getPollingLogText() { /** * Used from {@code polling.jelly} to write annotated polling log to the given output. */ + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", justification = "method signature does not permit plumbing through the return value") public void writePollingLogTo(long offset, XMLOutput out) throws IOException { // TODO: resurrect compressed log file support getPollingLogText().writeHtmlTo(offset, out.asWriter()); @@ -537,6 +538,7 @@ public String getLog() throws IOException { * Writes the annotated log to the given output. * @since 1.350 */ + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED", justification = "method signature does not permit plumbing through the return value") public void writeLogTo(XMLOutput out) throws IOException { new AnnotatedLargeText<>(getLogFile(), Charset.defaultCharset(), true, this).writeHtmlTo(0,out.asWriter()); } diff --git a/core/src/main/java/hudson/triggers/Trigger.java b/core/src/main/java/hudson/triggers/Trigger.java index e54b436480f3..5126c8925da4 100644 --- a/core/src/main/java/hudson/triggers/Trigger.java +++ b/core/src/main/java/hudson/triggers/Trigger.java @@ -331,6 +331,7 @@ public void run(AbstractProject p) { * * @deprecated Use {@link jenkins.util.Timer#get()} instead. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "for backward compatibility") @Deprecated public static @CheckForNull Timer timer; diff --git a/core/src/main/java/hudson/util/CharSpool.java b/core/src/main/java/hudson/util/CharSpool.java deleted file mode 100644 index 07d05ee23b0c..000000000000 --- a/core/src/main/java/hudson/util/CharSpool.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.util; - -import java.io.IOException; -import java.io.Writer; -import java.util.ArrayList; -import java.util.List; - -/** - * {@link Writer} that spools the output and writes to another {@link Writer} later. - * - * @author Kohsuke Kawaguchi - * @deprecated since 2008-05-28. moved to stapler - */ -@Deprecated -public final class CharSpool extends Writer { - private List buf; - - private char[] last = new char[1024]; - private int pos; - - @Override - public void write(char[] cbuf, int off, int len) { - while(len>0) { - int sz = Math.min(last.length-pos,len); - System.arraycopy(cbuf,off,last,pos,sz); - len -= sz; - off += sz; - pos += sz; - renew(); - } - } - - private void renew() { - if(pos(); - buf.add(last); - last = new char[1024]; - pos = 0; - } - - @Override - public void write(int c) { - renew(); - last[pos++] = (char)c; - } - - @Override - public void flush() { - // noop - } - - @Override - public void close() { - // noop - } - - public void writeTo(Writer w) throws IOException { - if(buf!=null) { - for (char[] cb : buf) { - w.write(cb); - } - } - w.write(last,0,pos); - } -} diff --git a/core/src/main/java/hudson/util/LineEndNormalizingWriter.java b/core/src/main/java/hudson/util/LineEndNormalizingWriter.java deleted file mode 100644 index ffa182e2630e..000000000000 --- a/core/src/main/java/hudson/util/LineEndNormalizingWriter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.util; - -import java.io.FilterWriter; -import java.io.IOException; -import java.io.Writer; - -/** - * Finds the lone LF and converts that to CR+LF. - * - *

- * Internet Explorer's {@code XmlHttpRequest.responseText} seems to - * normalize the line end, and if we only send LF without CR, it will - * not recognize that as a new line. To work around this problem, - * we use this filter to always convert LF to CR+LF. - * - * @author Kohsuke Kawaguchi - * @deprecated since 2008-05-28. moved to stapler - */ -@Deprecated -public class LineEndNormalizingWriter extends FilterWriter { - - private boolean seenCR; - - public LineEndNormalizingWriter(Writer out) { - super(out); - } - - @Override - public void write(char[] cbuf) throws IOException { - write(cbuf, 0, cbuf.length); - } - - @Override - public void write(String str) throws IOException { - write(str,0,str.length()); - } - - @Override - public void write(int c) throws IOException { - if(!seenCR && c==LF) - super.write("\r\n"); - else - super.write(c); - seenCR = c == CR; - } - - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - int end = off+len; - int writeBegin = off; - - for( int i=off; i { diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index dedcba153839..b6eccb039b37 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -5252,6 +5252,7 @@ protected Future _connect(boolean forceReconnect) { /** * Live view of recent {@link LogRecord}s produced by Jenkins. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "cannot be made immutable without breaking compatibility") public static List logRecords = Collections.emptyList(); // initialized to dummy value to avoid NPE /** @@ -5333,6 +5334,7 @@ private static void computeVersion(ServletContext context) { /** * Version number of this Jenkins. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "cannot be made immutable without breaking compatibility") public static String VERSION = UNCOMPUTED_VERSION; @Restricted(NoExternalUse.class) @@ -5407,6 +5409,7 @@ public boolean shouldShowStackTrace() { * We used to use {@link #VERSION_HASH}, but making this session local allows us to * reuse the same {@link #RESOURCE_PATH} for static resources in plugins. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "cannot be made immutable without breaking compatibility") public static String SESSION_HASH; /** @@ -5416,6 +5419,7 @@ public boolean shouldShowStackTrace() { *

* Value computed in {@link WebAppMain}. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "cannot be made immutable without breaking compatibility") public static String RESOURCE_PATH = ""; /** @@ -5425,6 +5429,7 @@ public boolean shouldShowStackTrace() { *

* Value computed in {@link WebAppMain}. */ + @SuppressFBWarnings(value = "MS_CANNOT_BE_FINAL", justification = "cannot be made immutable without breaking compatibility") public static String VIEW_RESOURCE_PATH = "/resources/TBD"; @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console") diff --git a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java index 0fbdc4b5e66b..2ab3534d7c20 100644 --- a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java +++ b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java @@ -3,6 +3,7 @@ import static java.util.logging.Level.FINE; import static java.util.logging.Level.SEVERE; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Extension; import hudson.Functions; import hudson.model.Computer; @@ -31,6 +32,7 @@ */ @Extension public class JnlpSlaveRestarterInstaller extends ComputerListener implements Serializable { + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "method signature does not permit plumbing through the return value") @Override public void onOnline(final Computer c, final TaskListener listener) throws IOException, InterruptedException { Computer.threadPoolForRemoting.submit(new Install(c, listener)); diff --git a/core/src/main/java/jenkins/util/AtmostOneTaskExecutor.java b/core/src/main/java/jenkins/util/AtmostOneTaskExecutor.java index 89b67e952f9e..f28f747e126f 100644 --- a/core/src/main/java/jenkins/util/AtmostOneTaskExecutor.java +++ b/core/src/main/java/jenkins/util/AtmostOneTaskExecutor.java @@ -1,5 +1,6 @@ package jenkins.util; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.remoting.AtmostOneThreadExecutor; import hudson.security.ACL; import hudson.util.DaemonThreadFactory; @@ -92,6 +93,7 @@ public synchronized Future submit() { * but {@link #inprogress} is null (meaning none is executing right now), * get one going. */ + @SuppressFBWarnings(value = "RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification = "method signature does not permit plumbing through the return value") private synchronized void maybeRun() { if (inprogress==null && pending!=null) { base.submit(new Callable() { diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java index e7ffef6d66b0..54fc929b54ef 100644 --- a/core/src/main/java/jenkins/util/JSONSignatureValidator.java +++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java @@ -245,7 +245,7 @@ private boolean digestMatches(byte[] digest, String providedDigest) { } - @SuppressFBWarnings(value = "NP_LOAD_OF_KNOWN_NULL_VALUE", justification = "https://github.com/spotbugs/spotbugs/issues/756") + @SuppressFBWarnings(value = {"NP_LOAD_OF_KNOWN_NULL_VALUE", "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"}, justification = "https://github.com/spotbugs/spotbugs/issues/756") protected Set loadTrustAnchors(CertificateFactory cf) throws IOException { // if we trust default root CAs, we end up trusting anyone who has a valid certificate, // which isn't useful at all diff --git a/pom.xml b/pom.xml index ef60291c3ec7..3beccbdd327a 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ THE SOFTWARE. - 2.327 + 2.328 -SNAPSHOT - - + + diff --git a/src/spotbugs/spotbugs-excludes.xml b/src/spotbugs/spotbugs-excludes.xml index 0d4eb6c636fd..63c6295337f6 100644 --- a/src/spotbugs/spotbugs-excludes.xml +++ b/src/spotbugs/spotbugs-excludes.xml @@ -150,13 +150,6 @@ - - - - - - - @@ -352,14 +345,6 @@ - - - - - - - - @@ -394,26 +379,6 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/war/pom.xml b/war/pom.xml index d6cb8dddc820..0e5079b178fa 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -63,7 +63,7 @@ THE SOFTWARE. org.jenkins-ci executable-war - 2.2 + 2.3 provided