diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index bd5ea5d7da9ad98565032db1810df24060daf79e..4f021a4de3f572426d0b3505353ce22eba7ad80c 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -27,6 +27,7 @@ import hudson.Util; import hudson.model.Queue.*; import hudson.FilePath; import hudson.model.queue.SubTask; +import hudson.model.queue.Tasks; import hudson.model.queue.WorkUnit; import hudson.util.TimeUnit2; import hudson.util.InterceptingProxy; @@ -351,7 +352,7 @@ public class Executor extends Thread implements ModelObject { public void doStop( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { Queue.Executable e = executable; if(e!=null) { - e.getParent().getOwnerTask().checkAbortPermission(); + Tasks.getOwnerTaskOf(e.getParent()).checkAbortPermission(); interrupt(); } rsp.forwardToPreviousPage(req); @@ -362,7 +363,7 @@ public class Executor extends Thread implements ModelObject { */ public boolean hasStopPermission() { Queue.Executable e = executable; - return e!=null && e.getParent().getOwnerTask().hasAbortPermission(); + return e!=null && Tasks.getOwnerTaskOf(e.getParent()).hasAbortPermission(); } public Computer getOwner() { diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index 5d10a52725688c07616a709f61a993fc2315ac14..63670c0cd2a166ce863d4299810b5707bd4ebb9f 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -42,6 +42,7 @@ import hudson.model.queue.MappingWorksheet; import hudson.model.queue.MappingWorksheet.Mapping; import hudson.model.queue.QueueSorter; import hudson.model.queue.QueueTaskDispatcher; +import hudson.model.queue.Tasks; import hudson.model.queue.WorkUnit; import hudson.model.Node.Mode; import hudson.model.listeners.SaveableListener; @@ -1057,12 +1058,18 @@ public class Queue extends ResourceController implements Saveable { /** * Obtains the {@link SubTask}s that constitute this task. * + *

* The collection returned by this method must also contain the primary {@link SubTask} * represented by this {@link Task} object itself as the first element. * The returned value is read-only. * + *

* At least size 1. * + *

+ * Since this is a newly added method, the invocation may results in {@link AbstractMethodError}. + * Use {@link Tasks#getSubTasksOf(Task)} that avoids this. + * * @since 1.FATTASK */ Collection getSubTasks(); diff --git a/core/src/main/java/hudson/model/queue/MappingWorksheet.java b/core/src/main/java/hudson/model/queue/MappingWorksheet.java index 98ac130e3d7969fa57ba6b103aa98187e497d24b..b6d89a7555df5382c9f6c42a5fcfb71a8aeea056 100644 --- a/core/src/main/java/hudson/model/queue/MappingWorksheet.java +++ b/core/src/main/java/hudson/model/queue/MappingWorksheet.java @@ -294,8 +294,8 @@ public class MappingWorksheet { // group execution units into chunks. use of LinkedHashMap ensures that the main work comes at the top Map> m = new LinkedHashMap>(); - for (SubTask meu : task.getSubTasks()) { - Object c = meu.getSameNodeConstraint(); + for (SubTask meu : Tasks.getSubTasksOf(task)) { + Object c = Tasks.getSameNodeConstraintOf(meu); if (c==null) c = new Object(); List l = m.get(c); diff --git a/core/src/main/java/hudson/model/queue/Tasks.java b/core/src/main/java/hudson/model/queue/Tasks.java new file mode 100644 index 0000000000000000000000000000000000000000..631fae7ad0509c7f07f0a15244961c2cedea83de --- /dev/null +++ b/core/src/main/java/hudson/model/queue/Tasks.java @@ -0,0 +1,86 @@ +/* + * The MIT License + * + * Copyright (c) 2010, InfraDNA, Inc. + * + * 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.model.queue; + +import hudson.model.Queue.Task; + +import java.util.Collection; +import java.util.Collections; + +/** + * Convenience methods around {@link Task} and {@link SubTask}. + * + * @author Kohsuke Kawaguchi + * @since 1.FATTASK + */ +public class Tasks { + + /** + * A pointless function to work around what appears to be a HotSpot problem. See HUDSON-5756 and bug 6933067 + * on BugParade for more details. + */ + private static Collection _getSubTasksOf(Task task) { + return task.getSubTasks(); + } + + public static Collection getSubTasksOf(Task task) { + try { + return _getSubTasksOf(task); + } catch (AbstractMethodError e) { + return Collections.singleton(task); + } + } + + /** + * A pointless function to work around what appears to be a HotSpot problem. See HUDSON-5756 and bug 6933067 + * on BugParade for more details. + */ + private static Object _getSameNodeConstraintOf(SubTask t) { + return t.getSameNodeConstraint(); + } + + public static Object getSameNodeConstraintOf(SubTask t) { + try { + return _getSameNodeConstraintOf(t); + } catch (AbstractMethodError e) { + return null; + } + } + + /** + * A pointless function to work around what appears to be a HotSpot problem. See HUDSON-5756 and bug 6933067 + * on BugParade for more details. + */ + public static Task _getOwnerTaskOf(SubTask t) { + return t.getOwnerTask(); + } + + public static Task getOwnerTaskOf(SubTask t) { + try { + return t.getOwnerTask(); + } catch (AbstractMethodError e) { + return (Task)t; + } + } +} diff --git a/core/src/main/java/hudson/model/queue/WorkUnitContext.java b/core/src/main/java/hudson/model/queue/WorkUnitContext.java index 5b78140f0583fe380752a0cf4970a2af5623f1c7..f1091d6dc088e0016b2fdceed2353317bff1937f 100644 --- a/core/src/main/java/hudson/model/queue/WorkUnitContext.java +++ b/core/src/main/java/hudson/model/queue/WorkUnitContext.java @@ -70,7 +70,7 @@ public final class WorkUnitContext { this.actions = item.getActions(); // +1 for the main task - int workUnitSize = task.getSubTasks().size(); + int workUnitSize = Tasks.getSubTasksOf(task).size(); startLatch = new Latch(workUnitSize) { @Override protected void onCriteriaMet() { diff --git a/readme.txt b/readme.txt index 840658f8b61336970792dce412ada0c6b0217c1b..187cdf651cbf44196886f87327dc3968443174fb 100644 --- a/readme.txt +++ b/readme.txt @@ -1,8 +1,2 @@ -TODO: - - handle AbstractMethodError on methods newly added. - - Document the new abstraction - - - executor rendering. we'd like to sort executors so that WideJobProperty can merge its rendering with parents.