From ca6d47c5c23a2b6e2c9721bbdf7f663a6006ca8b Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sat, 15 Sep 2018 15:32:22 +0300 Subject: [PATCH 01/47] [JENKINS-53593] Fix class loader error specific to OS. --- .../main/java/hudson/util/ProcessTree.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java index 843653f72d..6b2eec2f6b 100644 --- a/core/src/main/java/hudson/util/ProcessTree.java +++ b/core/src/main/java/hudson/util/ProcessTree.java @@ -43,7 +43,16 @@ import jenkins.security.SlaveToMasterCallable; import org.jvnet.winp.WinProcess; import org.jvnet.winp.WinpException; -import java.io.*; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileFilter; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -64,7 +73,6 @@ import javax.annotation.CheckForNull; import static com.sun.jna.Pointer.NULL; import jenkins.util.SystemProperties; import static hudson.util.jna.GNUCLibrary.LIBC; -import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINER; import static java.util.logging.Level.FINEST; import javax.annotation.Nonnull; @@ -175,8 +183,8 @@ public abstract class ProcessTree implements Iterable, IProcessTree, // let's do with what we have. killers = Collections.emptyList(); } - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to obtain killers",e); + } catch (IOException | Error e) { + LOGGER.log(Level.WARNING, "Failed to obtain killers", e); killers = Collections.emptyList(); } return killers; @@ -232,10 +240,11 @@ public abstract class ProcessTree implements Iterable, IProcessTree, void killByKiller() throws InterruptedException { for (ProcessKiller killer : getKillers()) try { - if (killer.kill(this)) + if (killer.kill(this)) { break; - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to kill pid="+getPid(),e); + } + } catch (IOException | Error e) { + LOGGER.log(Level.WARNING, "Failed to kill pid=" + getPid(), e); } } From a3cc7780aa2d6d36bdbabf663bd4b26f1172ecf3 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Fri, 21 Sep 2018 14:54:25 -0700 Subject: [PATCH 02/47] JDK11 support: refactor code to avoid underscore variable names --- .../main/java/hudson/ClassicPluginStrategy.java | 2 +- core/src/main/java/hudson/FilePath.java | 4 ++-- core/src/main/java/hudson/PluginManager.java | 2 +- .../cli/handlers/GenericItemOptionHandler.java | 2 +- core/src/main/java/hudson/model/Fingerprint.java | 4 ++-- core/src/main/java/hudson/model/ListView.java | 4 ++-- .../src/main/java/hudson/model/UpdateCenter.java | 2 +- .../java/hudson/model/queue/Executables.java | 2 +- .../java/hudson/os/solaris/ZFSInstaller.java | 2 +- .../security/HudsonPrivateSecurityRealm.java | 8 ++++---- .../src/main/java/hudson/tasks/BuildTrigger.java | 2 +- core/src/main/java/hudson/util/ProcessTree.java | 12 ++++++------ core/src/main/java/jenkins/model/Jenkins.java | 2 +- .../restarter/JnlpSlaveRestarterInstaller.java | 2 +- .../jenkins/triggers/ReverseBuildTrigger.java | 4 ++-- test/src/test/java/hudson/PluginManagerTest.java | 6 +++--- .../test/java/hudson/cli/ComputerStateTest.java | 2 +- .../test/java/hudson/model/FingerprintTest.java | 16 ++++++++-------- .../src/test/java/hudson/model/ListViewTest.java | 2 +- test/src/test/java/hudson/search/SearchTest.java | 2 +- .../jenkins/security/ApiTokenPropertyTest.java | 2 +- 21 files changed, 42 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 6503d4b639..2fdfd6427e 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -788,7 +788,7 @@ public class ClassicPluginStrategy implements PluginStrategy { if(p!=null) try { return p.classLoader.loadClass(name); - } catch (ClassNotFoundException _) { + } catch (ClassNotFoundException ex) { // try next } } diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 00d453f794..f3091386e4 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -2309,7 +2309,7 @@ public final class FilePath implements Serializable { // legacy agent.jar. Handle this gracefully try { LOGGER.log(Level.WARNING,"Looks like an old agent.jar. Please update "+ Which.jarFile(Channel.class)+" to the new version",e); - } catch (IOException _) { + } catch (IOException ex) { // really ignore this time } } @@ -2427,7 +2427,7 @@ public final class FilePath implements Serializable { // report both errors e.addSuppressed(x); throw e; - } catch (TimeoutException _) { + } catch (TimeoutException ex) { // remote is hanging throw e; } diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index be83e07456..fdf7b8d07e 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -1493,7 +1493,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas } updateCenter.persistInstallStatus(); if(!failures) { - try (ACLContext _ = ACL.as(currentAuth)) { + try (ACLContext acl = ACL.as(currentAuth)) { InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING); } } diff --git a/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java b/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java index 6cd1d86eba..0648f057a0 100644 --- a/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java @@ -62,7 +62,7 @@ public abstract class GenericItemOptionHandler extends OptionHan T s = j.getItemByFullName(src, type()); if (s == null) { final Authentication who = Jenkins.getAuthentication(); - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { Item actual = j.getItemByFullName(src); if (actual == null) { LOGGER.log(Level.FINE, "really no item exists named {0}", src); diff --git a/core/src/main/java/hudson/model/Fingerprint.java b/core/src/main/java/hudson/model/Fingerprint.java index 31dd8d87c5..e947908576 100644 --- a/core/src/main/java/hudson/model/Fingerprint.java +++ b/core/src/main/java/hudson/model/Fingerprint.java @@ -822,7 +822,7 @@ public class Fingerprint implements ModelObject, Saveable { public static final class ProjectRenameListener extends ItemListener { @Override public void onLocationChanged(final Item item, final String oldName, final String newName) { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { locationChanged(item, oldName, newName); } } @@ -1438,7 +1438,7 @@ public class Fingerprint implements ModelObject, Saveable { // Probably it failed due to the missing Item.DISCOVER // We try to retrieve the job using SYSTEM user and to check permissions manually. final Authentication userAuth = Jenkins.getAuthentication(); - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { final Item itemBySystemUser = jenkins.getItemByFullName(fullName); if (itemBySystemUser == null) { return false; diff --git a/core/src/main/java/hudson/model/ListView.java b/core/src/main/java/hudson/model/ListView.java index 002646e10d..9d84eb32ce 100644 --- a/core/src/main/java/hudson/model/ListView.java +++ b/core/src/main/java/hudson/model/ListView.java @@ -518,7 +518,7 @@ public class ListView extends View implements DirectlyModifiableView { public static final class Listener extends ItemListener { @Override public void onLocationChanged(final Item item, final String oldFullName, final String newFullName) { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { locationChanged(oldFullName, newFullName); } } @@ -563,7 +563,7 @@ public class ListView extends View implements DirectlyModifiableView { @Override public void onDeleted(final Item item) { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { deleted(item); } } diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index d457bd4ba2..faf0673d29 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -1401,7 +1401,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas status = new Running(); try { // safeRestart records the current authentication for the log, so set it to the managing user - try (ACLContext _ = ACL.as(User.get(authentication, false, Collections.emptyMap()))) { + try (ACLContext acl = ACL.as(User.get(authentication, false, Collections.emptyMap()))) { Jenkins.getInstance().safeRestart(); } } catch (RestartNotSupportedException exception) { diff --git a/core/src/main/java/hudson/model/queue/Executables.java b/core/src/main/java/hudson/model/queue/Executables.java index 2dbcca3f21..acb0e1fdfc 100644 --- a/core/src/main/java/hudson/model/queue/Executables.java +++ b/core/src/main/java/hudson/model/queue/Executables.java @@ -46,7 +46,7 @@ public class Executables { throws Error, RuntimeException { try { return e.getParent(); - } catch (AbstractMethodError _) { + } catch (AbstractMethodError ex) { try { Method m = e.getClass().getMethod("getParent"); m.setAccessible(true); diff --git a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java index 29532545fa..d14b2dd748 100644 --- a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java +++ b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java @@ -219,7 +219,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable // revert the file system creation try { hudson.destory(); - } catch (Exception _) { + } catch (Exception ex) { // but ignore the error and let the original error thrown } throw e; diff --git a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java index cf6c94e085..e08337aac4 100644 --- a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java +++ b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java @@ -739,11 +739,11 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea /*package*/ static final PasswordEncoder CLASSIC = new PasswordEncoder() { private final PasswordEncoder passwordEncoder = new ShaPasswordEncoder(256); - public String encodePassword(String rawPass, Object _) throws DataAccessException { + public String encodePassword(String rawPass, Object obj) throws DataAccessException { return hash(rawPass); } - public boolean isPasswordValid(String encPass, String rawPass, Object _) throws DataAccessException { + public boolean isPasswordValid(String encPass, String rawPass, Object obj) throws DataAccessException { // pull out the sale from the encoded password int i = encPass.indexOf(':'); if(i<0) return false; @@ -779,11 +779,11 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea * {@link PasswordEncoder} that uses jBCrypt. */ private static final PasswordEncoder JBCRYPT_ENCODER = new PasswordEncoder() { - public String encodePassword(String rawPass, Object _) throws DataAccessException { + public String encodePassword(String rawPass, Object obj) throws DataAccessException { return BCrypt.hashpw(rawPass,BCrypt.gensalt()); } - public boolean isPasswordValid(String encPass, String rawPass, Object _) throws DataAccessException { + public boolean isPasswordValid(String encPass, String rawPass, Object obj) throws DataAccessException { return BCrypt.checkpw(rawPass,encPass); } }; diff --git a/core/src/main/java/hudson/tasks/BuildTrigger.java b/core/src/main/java/hudson/tasks/BuildTrigger.java index 00615dbc79..78f8ef13f8 100644 --- a/core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/core/src/main/java/hudson/tasks/BuildTrigger.java @@ -431,7 +431,7 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer { public static class ItemListenerImpl extends ItemListener { @Override public void onLocationChanged(final Item item, final String oldFullName, final String newFullName) { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { locationChanged(item, oldFullName, newFullName); } } diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java index 843653f72d..5283054fca 100644 --- a/core/src/main/java/hudson/util/ProcessTree.java +++ b/core/src/main/java/hudson/util/ProcessTree.java @@ -1253,18 +1253,18 @@ public abstract class ProcessTree implements Iterable, IProcessTree, kinfo_proc_ppid_offset = kinfo_proc_ppid_offset_32; } try { - IntByReference _ = new IntByReference(sizeOfInt); + IntByReference ref = new IntByReference(sizeOfInt); IntByReference size = new IntByReference(sizeOfInt); Memory m; int nRetry = 0; while(true) { // find out how much memory we need to do this - if(LIBC.sysctl(MIB_PROC_ALL,3, NULL, size, NULL, _)!=0) + if(LIBC.sysctl(MIB_PROC_ALL,3, NULL, size, NULL, ref)!=0) throw new IOException("Failed to obtain memory requirement: "+LIBC.strerror(Native.getLastError())); // now try the real call m = new Memory(size.getValue()); - if(LIBC.sysctl(MIB_PROC_ALL,3, m, size, NULL, _)!=0) { + if(LIBC.sysctl(MIB_PROC_ALL,3, m, size, NULL, ref)!=0) { if(Native.getLastError()==ENOMEM && nRetry++<16) continue; // retry throw new IOException("Failed to call kern.proc.all: "+LIBC.strerror(Native.getLastError())); @@ -1324,14 +1324,14 @@ public abstract class ProcessTree implements Iterable, IProcessTree, arguments = new ArrayList(); envVars = new EnvVars(); - IntByReference _ = new IntByReference(); + IntByReference intByRef = new IntByReference(); IntByReference argmaxRef = new IntByReference(0); IntByReference size = new IntByReference(sizeOfInt); // for some reason, I was never able to get sysctlbyname work. // if(LIBC.sysctlbyname("kern.argmax", argmaxRef.getPointer(), size, NULL, _)!=0) - if(LIBC.sysctl(new int[]{CTL_KERN,KERN_ARGMAX},2, argmaxRef.getPointer(), size, NULL, _)!=0) + if(LIBC.sysctl(new int[]{CTL_KERN,KERN_ARGMAX},2, argmaxRef.getPointer(), size, NULL, intByRef)!=0) throw new IOException("Failed to get kern.argmax: "+LIBC.strerror(Native.getLastError())); int argmax = argmaxRef.getValue(); @@ -1369,7 +1369,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree, } StringArrayMemory m = new StringArrayMemory(argmax); size.setValue(argmax); - if(LIBC.sysctl(new int[]{CTL_KERN,KERN_PROCARGS2,pid},3, m, size, NULL, _)!=0) + if(LIBC.sysctl(new int[]{CTL_KERN,KERN_PROCARGS2,pid},3, m, size, NULL, intByRef)!=0) throw new IOException("Failed to obtain ken.procargs2: "+LIBC.strerror(Native.getLastError())); diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index f1ba7be1dd..e4880248e3 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -5030,7 +5030,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve if (idx > 0) { return new VersionNumber(versionString.substring(0,idx)); } - } catch (NumberFormatException _) { + } catch (NumberFormatException ex) { // fall through } diff --git a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java index e47cc39925..222998caaf 100644 --- a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java +++ b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java @@ -77,7 +77,7 @@ public class JnlpSlaveRestarterInstaller extends ComputerListener implements Ser try { Engine.class.getMethod("addListener", EngineListener.class); - } catch (NoSuchMethodException _) { + } catch (NoSuchMethodException ex) { return null; // running with older version of remoting that doesn't support adding listener } diff --git a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java index 3058274ceb..c601cebc26 100644 --- a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java +++ b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java @@ -251,7 +251,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc } private Map> calculateCache() { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { final Map> result = new WeakHashMap<>(); for (Job downstream : Jenkins.getInstance().allItems(Job.class)) { ReverseBuildTrigger trigger = @@ -312,7 +312,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc public static class ItemListenerImpl extends ItemListener { @Override public void onLocationChanged(Item item, final String oldFullName, final String newFullName) { - try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + try (ACLContext acl = ACL.as(ACL.SYSTEM)) { for (Job p : Jenkins.getInstance().allItems(Job.class)) { ReverseBuildTrigger t = ParameterizedJobMixIn.getTrigger(p, ReverseBuildTrigger.class); if (t != null) { diff --git a/test/src/test/java/hudson/PluginManagerTest.java b/test/src/test/java/hudson/PluginManagerTest.java index 61c09bea42..180689e295 100644 --- a/test/src/test/java/hudson/PluginManagerTest.java +++ b/test/src/test/java/hudson/PluginManagerTest.java @@ -293,7 +293,7 @@ public class PluginManagerTest { try { callDependerValue(); fail(); - } catch (ClassNotFoundException _) { + } catch (ClassNotFoundException ex) { } // No extensions exist. @@ -331,7 +331,7 @@ public class PluginManagerTest { try { r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint"); fail(); - } catch( ClassNotFoundException _ ){ + } catch( ClassNotFoundException ex ){ } // Load dependee. @@ -380,7 +380,7 @@ public class PluginManagerTest { try { r.jenkins.getExtensionList("org.jenkinsci.plugins.dependencytest.dependee.DependeeExtensionPoint"); fail(); - } catch( ClassNotFoundException _ ){ + } catch( ClassNotFoundException ex ){ } } diff --git a/test/src/test/java/hudson/cli/ComputerStateTest.java b/test/src/test/java/hudson/cli/ComputerStateTest.java index 6933b12544..87845cea8e 100644 --- a/test/src/test/java/hudson/cli/ComputerStateTest.java +++ b/test/src/test/java/hudson/cli/ComputerStateTest.java @@ -168,6 +168,6 @@ public class ComputerStateTest { try { page.getAnchorByText(text); fail(text + " link should not exist"); - } catch (ElementNotFoundException _) { /*expected*/ } + } catch (ElementNotFoundException ex) { /*expected*/ } } } diff --git a/test/src/test/java/hudson/model/FingerprintTest.java b/test/src/test/java/hudson/model/FingerprintTest.java index ff5214063f..a8a9befece 100644 --- a/test/src/test/java/hudson/model/FingerprintTest.java +++ b/test/src/test/java/hudson/model/FingerprintTest.java @@ -160,7 +160,7 @@ public class FingerprintTest { setJobPermissionsOnce(project1, "user1", Item.READ, Item.DISCOVER); setJobPermissionsOnce(project2, "user2", Item.READ, Item.DISCOVER); - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { Fingerprint.BuildPtr original = fp.getOriginal(); assertThat("user1 should be able to see the origin", fp.getOriginal(), notNullValue()); assertEquals("user1 should be able to see the origin's project name", project1.getName(), original.getName()); @@ -169,13 +169,13 @@ public class FingerprintTest { assertEquals("Only project1 should be visible to user1", project1.getFullName(), fp._getUsages().get(0).name); } - try (ACLContext _ = ACL.as(user2)) { + try (ACLContext acl = ACL.as(user2)) { assertThat("user2 should be unable to see the origin", fp.getOriginal(), nullValue()); assertEquals("Only one usage should be visible to user2", 1, fp._getUsages().size()); assertEquals("Only project2 should be visible to user2", project2.getFullName(), fp._getUsages().get(0).name); } - try (ACLContext _ = ACL.as(user3)) { + try (ACLContext acl = ACL.as(user3)) { Fingerprint.BuildPtr original = fp.getOriginal(); assertThat("user3 should be unable to see the origin", fp.getOriginal(), nullValue()); assertEquals("All usages should be invisible for user3", 0, fp._getUsages().size()); @@ -193,7 +193,7 @@ public class FingerprintTest { User user1 = User.get("user1"); setupProjectMatrixAuthStrategy(Jenkins.READ, Item.DISCOVER); - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { Fingerprint.BuildPtr original = fingerprint.getOriginal(); assertThat("user1 should able to see the origin", fingerprint.getOriginal(), notNullValue()); assertEquals("user1 sees the wrong original name with Item.DISCOVER", project.getFullName(), original.getName()); @@ -216,7 +216,7 @@ public class FingerprintTest { folder.setPermissions("user1", Item.READ); // Ensure we can read the original from user account - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { assertTrue("Test framework issue: User1 should be able to read the folder", folder.hasPermission(Item.READ)); Fingerprint.BuildPtr original = fingerprint.getOriginal(); @@ -241,7 +241,7 @@ public class FingerprintTest { setupProjectMatrixAuthStrategy(Jenkins.READ, Item.DISCOVER); // Ensure we can read the original from user account - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { assertFalse("Test framework issue: User1 should be unable to read the folder", folder.hasPermission(Item.READ)); assertThat("user1 should be unable to see the origin", fingerprint.getOriginal(), nullValue()); assertEquals("No jobs should be visible to user1", 0, fingerprint._getUsages().size()); @@ -266,7 +266,7 @@ public class FingerprintTest { setupProjectMatrixAuthStrategy(Jenkins.READ, Item.READ, Item.DISCOVER); project.delete(); - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { assertThat("user1 should be unable to see the origin", fp.getOriginal(), nullValue()); assertEquals("No jobs should be visible to user1", 0, fp._getUsages().size()); } @@ -284,7 +284,7 @@ public class FingerprintTest { setupProjectMatrixAuthStrategy(Jenkins.ADMINISTER); project.delete(); - try (ACLContext _ = ACL.as(user1)) { + try (ACLContext acl = ACL.as(user1)) { Fingerprint.BuildPtr original = fingerprint.getOriginal(); assertThat("user1 should able to see the origin", fingerprint.getOriginal(), notNullValue()); assertThat("Job has been deleted, so Job reference should return null", fingerprint.getOriginal().getJob(), nullValue()); diff --git a/test/src/test/java/hudson/model/ListViewTest.java b/test/src/test/java/hudson/model/ListViewTest.java index 680a592060..04cdc116d9 100644 --- a/test/src/test/java/hudson/model/ListViewTest.java +++ b/test/src/test/java/hudson/model/ListViewTest.java @@ -234,7 +234,7 @@ public class ListViewTest { ListView v = new ListView("v", j.jenkins); v.add(p); j.jenkins.addView(v); - try (ACLContext _ = ACL.as(User.get("alice"))) { + try (ACLContext acl = ACL.as(User.get("alice"))) { p.renameTo("p2"); } assertEquals(Collections.singletonList(p), v.getItems()); diff --git a/test/src/test/java/hudson/search/SearchTest.java b/test/src/test/java/hudson/search/SearchTest.java index 98d74ad2c1..e2fcd37a48 100644 --- a/test/src/test/java/hudson/search/SearchTest.java +++ b/test/src/test/java/hudson/search/SearchTest.java @@ -440,7 +440,7 @@ public class SearchTest { mas.grant(Jenkins.READ).onRoot().toEveryone(); j.jenkins.setAuthorizationStrategy(mas); - try(ACLContext _ = ACL.as(User.get("alice"))) { + try(ACLContext acl = ACL.as(User.get("alice"))) { List results = new ArrayList<>(); j.jenkins.getSearchIndex().find("config", results); j.jenkins.getSearchIndex().find("manage", results); diff --git a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java index 47e750f62c..e9a4f16b24 100644 --- a/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java +++ b/test/src/test/java/jenkins/security/ApiTokenPropertyTest.java @@ -69,7 +69,7 @@ public class ApiTokenPropertyTest { final String token = t.getApiToken(); // Make sure that user is able to get the token via the interface - try (ACLContext _ = ACL.as(u)) { + try (ACLContext acl = ACL.as(u)) { assertEquals("User is unable to get its own token", token, t.getApiToken()); } From 7509cde3432cfea68bb99d6e4b0b0e0cba8b3cd4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 25 Sep 2018 03:37:32 +0300 Subject: [PATCH 03/47] Exclude UI screw --- core/src/main/java/hudson/model/View.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index cc75811fa1..de1dc343e8 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -192,6 +192,7 @@ public abstract class View extends AbstractModelObject implements AccessControll /** * Gets all the items in this collection in a read-only view. */ + @Nonnull @Exported(name="jobs") public abstract Collection getItems(); From 037a1c06a08f485360088595f410063dd869f3c5 Mon Sep 17 00:00:00 2001 From: lqli Date: Tue, 25 Sep 2018 16:31:08 +0800 Subject: [PATCH 04/47] warp successive words in help --- war/src/main/webapp/css/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/war/src/main/webapp/css/style.css b/war/src/main/webapp/css/style.css index d698e65359..ebc646374d 100644 --- a/war/src/main/webapp/css/style.css +++ b/war/src/main/webapp/css/style.css @@ -777,6 +777,7 @@ LABEL.attach-previous { background-color: #f0f0f0; padding: 1em; margin-bottom: 1em; + word-break: break-word; } .help .from-plugin { From 297e4e3d85fa53496209f2acecf16d7a67616668 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Thu, 27 Sep 2018 00:31:15 +0200 Subject: [PATCH 05/47] [JENKINS-53793] - Suppress DMI_COLLECTION_OF_URLS in ClassicPluginStrategy It starts failing FindBugs runs against Java 11. The implementation is not efficient, but it should not be a serious issue in this case --- core/src/main/java/hudson/ClassicPluginStrategy.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 6503d4b639..73a781f125 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -31,6 +31,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.InvalidPathException; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import jenkins.util.AntWithFindResourceClassLoader; import jenkins.util.SystemProperties; import com.google.common.collect.Lists; @@ -798,6 +799,8 @@ public class ClassicPluginStrategy implements PluginStrategy { } @Override + @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", + justification = "Should not produce network overheads since the URL is local. JENKINS-53793 is a follow-up") protected Enumeration findResources(String name) throws IOException { HashSet result = new HashSet(); From 8598492f193cab9633c6d32e13a9d463bc207007 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Thu, 27 Sep 2018 01:23:28 +0200 Subject: [PATCH 06/47] =?UTF-8?q?Ignored=20Exceptions:=20use=20=E2=80=98ig?= =?UTF-8?q?nored=E2=80=99=20to=20supress=20IntellijIDEA=20warnings=20as=20?= =?UTF-8?q?suggested=20by=20@daniel-beck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/main/java/hudson/ClassicPluginStrategy.java | 9 +++++---- core/src/main/java/hudson/FilePath.java | 6 +++--- core/src/main/java/hudson/model/queue/Executables.java | 2 +- core/src/main/java/hudson/os/solaris/ZFSInstaller.java | 2 +- core/src/main/java/jenkins/model/Jenkins.java | 2 +- .../slaves/restarter/JnlpSlaveRestarterInstaller.java | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 2fdfd6427e..af0521fab8 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -778,19 +778,20 @@ public class ClassicPluginStrategy implements PluginStrategy { Class c = ClassLoaderReflectionToolkit._findLoadedClass(pw.classLoader, name); if (c!=null) return c; return ClassLoaderReflectionToolkit._findClass(pw.classLoader, name); - } catch (ClassNotFoundException e) { + } catch (ClassNotFoundException ignored) { //not found. try next } } } else { for (Dependency dep : dependencies) { PluginWrapper p = pluginManager.getPlugin(dep.shortName); - if(p!=null) + if(p!=null) { try { return p.classLoader.loadClass(name); - } catch (ClassNotFoundException ex) { - // try next + } catch (ClassNotFoundException ignored) { + // OK, try next } + } } } diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index f3091386e4..e9504a71c6 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -2309,7 +2309,7 @@ public final class FilePath implements Serializable { // legacy agent.jar. Handle this gracefully try { LOGGER.log(Level.WARNING,"Looks like an old agent.jar. Please update "+ Which.jarFile(Channel.class)+" to the new version",e); - } catch (IOException ex) { + } catch (IOException ignored) { // really ignore this time } } @@ -2427,8 +2427,8 @@ public final class FilePath implements Serializable { // report both errors e.addSuppressed(x); throw e; - } catch (TimeoutException ex) { - // remote is hanging + } catch (TimeoutException ignored) { + // remote is hanging, just throw the original exception throw e; } } diff --git a/core/src/main/java/hudson/model/queue/Executables.java b/core/src/main/java/hudson/model/queue/Executables.java index acb0e1fdfc..426c12df96 100644 --- a/core/src/main/java/hudson/model/queue/Executables.java +++ b/core/src/main/java/hudson/model/queue/Executables.java @@ -46,7 +46,7 @@ public class Executables { throws Error, RuntimeException { try { return e.getParent(); - } catch (AbstractMethodError ex) { + } catch (AbstractMethodError ignored) { // will fallback to a private implementation try { Method m = e.getClass().getMethod("getParent"); m.setAccessible(true); diff --git a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java index d14b2dd748..f22a0b7879 100644 --- a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java +++ b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java @@ -219,7 +219,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable // revert the file system creation try { hudson.destory(); - } catch (Exception ex) { + } catch (Exception ignored) { // but ignore the error and let the original error thrown } throw e; diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index e4880248e3..ba8e826317 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -5030,7 +5030,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve if (idx > 0) { return new VersionNumber(versionString.substring(0,idx)); } - } catch (NumberFormatException ex) { + } catch (NumberFormatException ignored) { // fall through } diff --git a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java index 222998caaf..3a8b9f6b42 100644 --- a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java +++ b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java @@ -77,7 +77,7 @@ public class JnlpSlaveRestarterInstaller extends ComputerListener implements Ser try { Engine.class.getMethod("addListener", EngineListener.class); - } catch (NoSuchMethodException ex) { + } catch (NoSuchMethodException ignored) { return null; // running with older version of remoting that doesn't support adding listener } From d714a622eafebe983618df0facf3745eab549230 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Thu, 27 Sep 2018 01:13:32 +0200 Subject: [PATCH 07/47] [JENKINS-53693] - Ignore java.xml components in core tests. It is require to make the tests passing on Java 11, but apparently it also speeds up tests on Java 8. --- core/src/test/java/hudson/FunctionsTest.java | 3 +++ core/src/test/java/hudson/cli/ListJobsCommandTest.java | 2 ++ .../test/java/hudson/cli/handlers/ViewOptionHandlerTest.java | 2 ++ core/src/test/java/hudson/model/JobTest.java | 2 ++ core/src/test/java/hudson/model/ListViewTest.java | 2 ++ core/src/test/java/hudson/model/ParametersActionTest.java | 3 +++ core/src/test/java/hudson/slaves/ChannelPingerTest.java | 2 ++ .../java/hudson/slaves/DelegatingComputerLauncherTest.java | 2 ++ core/src/test/java/hudson/util/RunListTest.java | 2 ++ .../java/jenkins/model/CoreEnvironmentContributorTest.java | 2 ++ core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java | 2 ++ core/src/test/java/jenkins/model/NewViewLinkTest.java | 2 ++ .../test/java/jenkins/security/apitoken/ApiTokenStatsTest.java | 2 ++ 13 files changed, 28 insertions(+) diff --git a/core/src/test/java/hudson/FunctionsTest.java b/core/src/test/java/hudson/FunctionsTest.java index a12179dcf7..41cfa02779 100644 --- a/core/src/test/java/hudson/FunctionsTest.java +++ b/core/src/test/java/hudson/FunctionsTest.java @@ -53,10 +53,13 @@ import org.kohsuke.stapler.StaplerRequest; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; + +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class FunctionsTest { @Test public void testGetActionUrl_absoluteUriWithAuthority(){ diff --git a/core/src/test/java/hudson/cli/ListJobsCommandTest.java b/core/src/test/java/hudson/cli/ListJobsCommandTest.java index c42eab40ec..fa1af80efe 100644 --- a/core/src/test/java/hudson/cli/ListJobsCommandTest.java +++ b/core/src/test/java/hudson/cli/ListJobsCommandTest.java @@ -32,12 +32,14 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(Jenkins.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) @SuppressStaticInitializationFor("hudson.cli.CLICommand") public class ListJobsCommandTest { diff --git a/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java b/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java index 38639ea21d..eeda846d79 100644 --- a/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java +++ b/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java @@ -46,11 +46,13 @@ import org.kohsuke.args4j.spi.Setter; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @PrepareForTest(Jenkins.class) @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class ViewOptionHandlerTest { @Mock private Setter setter; diff --git a/core/src/test/java/hudson/model/JobTest.java b/core/src/test/java/hudson/model/JobTest.java index c65793d521..22679f2826 100644 --- a/core/src/test/java/hudson/model/JobTest.java +++ b/core/src/test/java/hudson/model/JobTest.java @@ -11,6 +11,7 @@ import org.jvnet.hudson.test.Issue; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.MockRepository; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -20,6 +21,7 @@ import hudson.util.ReflectionUtils; @RunWith(PowerMockRunner.class) @PrepareForTest({ Node.class, Platform.class }) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class JobTest { @Test diff --git a/core/src/test/java/hudson/model/ListViewTest.java b/core/src/test/java/hudson/model/ListViewTest.java index aa9ed29a02..aa77c1ddfe 100644 --- a/core/src/test/java/hudson/model/ListViewTest.java +++ b/core/src/test/java/hudson/model/ListViewTest.java @@ -17,10 +17,12 @@ import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class ListViewTest { private interface ItemGroupOfNonTopLevelItem extends TopLevelItem, ItemGroup {} diff --git a/core/src/test/java/hudson/model/ParametersActionTest.java b/core/src/test/java/hudson/model/ParametersActionTest.java index 6f7321ed19..670d820e71 100644 --- a/core/src/test/java/hudson/model/ParametersActionTest.java +++ b/core/src/test/java/hudson/model/ParametersActionTest.java @@ -13,9 +13,12 @@ import static org.junit.Assert.assertNotSame; import org.junit.runner.RunWith; import org.jvnet.hudson.test.Issue; import static org.powermock.api.mockito.PowerMockito.mock; + +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class ParametersActionTest { private ParametersAction baseParamsAB; diff --git a/core/src/test/java/hudson/slaves/ChannelPingerTest.java b/core/src/test/java/hudson/slaves/ChannelPingerTest.java index 666f6afaac..0e4941d00b 100644 --- a/core/src/test/java/hudson/slaves/ChannelPingerTest.java +++ b/core/src/test/java/hudson/slaves/ChannelPingerTest.java @@ -12,6 +12,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import hudson.remoting.Channel; @@ -21,6 +22,7 @@ import java.util.HashMap; @RunWith(PowerMockRunner.class) @PrepareForTest({ ChannelPinger.class }) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class ChannelPingerTest { @Mock private Channel mockChannel; diff --git a/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java index 5d47c1a2af..f70b552ac1 100644 --- a/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java +++ b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java @@ -6,6 +6,7 @@ import jenkins.model.Jenkins; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -21,6 +22,7 @@ import static org.powermock.api.mockito.PowerMockito.when; * @author peppelan */ @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class DelegatingComputerLauncherTest { public static class DummyOne extends DelegatingComputerLauncher { diff --git a/core/src/test/java/hudson/util/RunListTest.java b/core/src/test/java/hudson/util/RunListTest.java index 2ced98d439..19202b38d6 100644 --- a/core/src/test/java/hudson/util/RunListTest.java +++ b/core/src/test/java/hudson/util/RunListTest.java @@ -33,6 +33,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.jvnet.hudson.test.Issue; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -40,6 +41,7 @@ import org.powermock.modules.junit4.PowerMockRunner; * @author Ignacio Albors */ @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class RunListTest { // RunList for byTimestamp tests diff --git a/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java b/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java index df203a5627..44177e0442 100644 --- a/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java +++ b/core/src/test/java/jenkins/model/CoreEnvironmentContributorTest.java @@ -18,10 +18,12 @@ import org.jvnet.hudson.test.Issue; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class CoreEnvironmentContributorTest { CoreEnvironmentContributor instance; diff --git a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java index a2b5f3afd2..4d071dd644 100644 --- a/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java +++ b/core/src/test/java/jenkins/model/JenkinsGetRootUrlTest.java @@ -41,11 +41,13 @@ import static org.mockito.Matchers.anyString; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest({JenkinsLocationConfiguration.class, Stapler.class}) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class JenkinsGetRootUrlTest { private Jenkins jenkins; diff --git a/core/src/test/java/jenkins/model/NewViewLinkTest.java b/core/src/test/java/jenkins/model/NewViewLinkTest.java index febd23a618..905970d522 100644 --- a/core/src/test/java/jenkins/model/NewViewLinkTest.java +++ b/core/src/test/java/jenkins/model/NewViewLinkTest.java @@ -15,11 +15,13 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest({NewViewLink.class, Jenkins.class}) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class NewViewLinkTest { @Mock diff --git a/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java b/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java index 6649702190..d3a76bd88c 100644 --- a/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java +++ b/core/src/test/java/jenkins/security/apitoken/ApiTokenStatsTest.java @@ -34,6 +34,7 @@ import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.internal.matchers.LessOrEqual; import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PowerMockIgnore; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -62,6 +63,7 @@ import static org.junit.Assert.assertThat; @RunWith(PowerMockRunner.class) @PrepareForTest(ApiTokenPropertyConfiguration.class) +@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*"}) public class ApiTokenStatsTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); From 45c837daa920e85f84f288a7337016a853054add Mon Sep 17 00:00:00 2001 From: Jeff Pearce Date: Thu, 27 Sep 2018 09:47:40 -0700 Subject: [PATCH 08/47] [JENKINS-53721] - Add getter/setter to EnvVars so the envinject plugin can set Platform safely (#3639) [JENKINS-53721] - Add getter/setter to EnvVars so the envinject plugin can set Platform safely --- core/src/main/java/hudson/EnvVars.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/hudson/EnvVars.java b/core/src/main/java/hudson/EnvVars.java index a4d581802e..cd553f3aba 100644 --- a/core/src/main/java/hudson/EnvVars.java +++ b/core/src/main/java/hudson/EnvVars.java @@ -44,6 +44,7 @@ import java.util.TreeSet; import java.util.UUID; import java.util.logging.Logger; import javax.annotation.Nonnull; +import javax.annotation.CheckForNull; /** * Environment variables. @@ -84,7 +85,24 @@ public class EnvVars extends TreeMap { * So this property remembers that information. */ private Platform platform; + + /** + * Gets the platform for which these env vars targeted. + * @since TODO + * @return The platform. + */ + public @CheckForNull Platform getPlatform() { + return platform; + } + /** + * Sets the platform for which these env vars target. + * @since TODO + * @param platform the platform to set. + */ + public void setPlatform(@Nonnull Platform platform) { + this.platform = platform; + } public EnvVars() { super(CaseInsensitiveComparator.INSTANCE); } @@ -425,7 +443,7 @@ public class EnvVars extends TreeMap { * *

* If you access this field from agents, then this is the environment - * variable of the agent agent. + * variable of the agent. */ public static final Map masterEnvVars = initMaster(); From 3caef8ec3278f0554f23098beaf25be6adf19679 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Thu, 27 Sep 2018 20:12:15 +0200 Subject: [PATCH 09/47] [JENKINS-46523] - Make UnixReflection class compatible with Java 11, remove pre-Java 8 reflection (#3650) * [JENKINS-46523] - Make UnixReflection class compatble with Java 9+, remover pre-Java-8 code Ideally this logic should be replaced by Multi-Release JAR * [JENKINS-46523] - FindBugs annotations complicate the code here * [JENKINS-53799 ] - Explicitly reference the JIRA ticket in the error message --- .../main/java/hudson/util/ProcessTree.java | 100 +++++++++++------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java index 0aa51c4699..574fdf55b4 100644 --- a/core/src/main/java/hudson/util/ProcessTree.java +++ b/core/src/main/java/hudson/util/ProcessTree.java @@ -56,6 +56,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.SortedMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -64,7 +65,6 @@ import javax.annotation.CheckForNull; import static com.sun.jna.Pointer.NULL; import jenkins.util.SystemProperties; import static hudson.util.jna.GNUCLibrary.LIBC; -import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINER; import static java.util.logging.Level.FINEST; import javax.annotation.Nonnull; @@ -684,13 +684,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree, @Override public OSProcess get(Process proc) { - try { - return get((Integer) UnixReflection.PID_FIELD.get(proc)); - } catch (IllegalAccessException e) { // impossible - IllegalAccessError x = new IllegalAccessError(); - x.initCause(e); - throw x; - } + return get(UnixReflection.pid(proc)); } public void killAll(Map modelEnvVars) throws InterruptedException { @@ -818,60 +812,94 @@ public abstract class ProcessTree implements Iterable, IProcessTree, public abstract List getArguments(); } + //TODO: can be replaced by multi-release JAR /** * Reflection used in the Unix support. */ private static final class UnixReflection { /** * Field to access the PID of the process. + * Required for Java 8 and older JVMs. */ - private static final Field PID_FIELD; + private static final Field JAVA8_PID_FIELD; + + /** + * Field to access the PID of the process. + * Required for Java 9 and above until this is replaced by multi-release JAR. + */ + private static final Method JAVA9_PID_METHOD; /** * Method to destroy a process, given pid. * * Looking at the JavaSE source code, this is using SIGTERM (15) */ - private static final Method DESTROY_PROCESS; + private static final Method JAVA8_DESTROY_PROCESS; + private static final Method JAVA_9_PROCESSHANDLE_OF; + private static final Method JAVA_9_PROCESSHANDLE_DESTROY; static { try { - Class clazz = Class.forName("java.lang.UNIXProcess"); - PID_FIELD = clazz.getDeclaredField("pid"); - PID_FIELD.setAccessible(true); - - if (isPreJava8()) { - DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess",int.class); + if (isPostJava8()) { // Java 9+ + Class clazz = Process.class; + JAVA9_PID_METHOD = clazz.getMethod("pid"); + JAVA8_PID_FIELD = null; + Class processHandleClazz = Class.forName("java.lang.ProcessHandle"); + JAVA_9_PROCESSHANDLE_OF = processHandleClazz.getMethod("of", long.class); + JAVA_9_PROCESSHANDLE_DESTROY = processHandleClazz.getMethod("destroy"); + JAVA8_DESTROY_PROCESS = null; } else { - DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess",int.class, boolean.class); + Class clazz = Class.forName("java.lang.UNIXProcess"); + JAVA8_PID_FIELD = clazz.getDeclaredField("pid"); + JAVA8_PID_FIELD.setAccessible(true); + JAVA9_PID_METHOD = null; + + JAVA8_DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess", int.class, boolean.class); + JAVA8_DESTROY_PROCESS.setAccessible(true); + JAVA_9_PROCESSHANDLE_OF = null; + JAVA_9_PROCESSHANDLE_DESTROY = null; } - DESTROY_PROCESS.setAccessible(true); - } catch (ClassNotFoundException e) { - LinkageError x = new LinkageError(); - x.initCause(e); - throw x; - } catch (NoSuchFieldException e) { - LinkageError x = new LinkageError(); - x.initCause(e); - throw x; - } catch (NoSuchMethodException e) { - LinkageError x = new LinkageError(); - x.initCause(e); + } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) { + LinkageError x = new LinkageError("Cannot initialize reflection for Unix Processes", e); throw x; } } - public static void destroy(int pid) throws IllegalAccessException, InvocationTargetException { - if (isPreJava8()) { - DESTROY_PROCESS.invoke(null, pid); + public static void destroy(int pid) throws IllegalAccessException, + InvocationTargetException { + if (JAVA8_DESTROY_PROCESS != null) { + JAVA8_DESTROY_PROCESS.invoke(null, pid, false); } else { - DESTROY_PROCESS.invoke(null, pid, false); + final Optional handle = (Optional)JAVA_9_PROCESSHANDLE_OF.invoke(null, pid); + if (handle.isPresent()) { + JAVA_9_PROCESSHANDLE_DESTROY.invoke(handle.get()); + } } } - private static boolean isPreJava8() { - int javaVersionAsAnInteger = Integer.parseInt(System.getProperty("java.version").replaceAll("\\.", "").replaceAll("_", "").substring(0, 2)); - return javaVersionAsAnInteger < 18; + //TODO: We ideally need to update ProcessTree APIs to Support Long (JENKINS-53799). + public static int pid(@Nonnull Process proc) { + try { + if (JAVA8_PID_FIELD != null) { + return JAVA8_PID_FIELD.getInt(proc); + } else { + long pid = (long)JAVA9_PID_METHOD.invoke(proc); + if (pid > Integer.MAX_VALUE) { + throw new IllegalAccessError("Java 9+ support error (JENKINS-53799). PID is out of Jenkins API bounds: " + pid); + } + return (int)pid; + } + } catch (IllegalAccessException | InvocationTargetException e) { // impossible + IllegalAccessError x = new IllegalAccessError(); + x.initCause(e); + throw x; + } + } + + // Java 9 uses new version format + private static boolean isPostJava8() { + String javaVersion = System.getProperty("java.version"); + return !javaVersion.startsWith("1."); } } From 1f31f421770847787f7928f52bc83cf825bba373 Mon Sep 17 00:00:00 2001 From: Steve Arch Date: Thu, 27 Sep 2018 19:15:48 +0100 Subject: [PATCH 10/47] [JENKINS-53353] - Do not cache results of View.getActions() (#3608) * JENKINS-53353 Do not cache results of View.getActions() Plugins that may affect the view, eg via TransientViewActionFactory that get installed _after_ a `view` has been initally viewed will not be able to add anything to the view if the results of getActions() are cached. * JENKINS-53353 Removed unnecessary synchronization * JENKINS-53353 Whitespace * JENKINS-53353 Restored (and deprecated) updateTransientActions to maintain backwards compatibility. --- core/src/main/java/hudson/model/View.java | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java index de1dc343e8..fcab16b90b 100644 --- a/core/src/main/java/hudson/model/View.java +++ b/core/src/main/java/hudson/model/View.java @@ -116,7 +116,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static jenkins.scm.RunWithSCM.*; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -172,8 +171,6 @@ public abstract class View extends AbstractModelObject implements AccessControll */ protected boolean filterQueue; - protected transient List transientActions; - /** * List of {@link ViewProperty}s configured for this view. * @since 1.406 @@ -550,21 +547,20 @@ public abstract class View extends AbstractModelObject implements AccessControll * @see Jenkins#getActions() */ public List getActions() { - List result = new ArrayList(); - result.addAll(getOwner().getViewActions()); - synchronized (this) { - if (transientActions == null) { - updateTransientActions(); - } - result.addAll(transientActions); - } - return result; + List result = new ArrayList<>(); + result.addAll(getOwner().getViewActions()); + result.addAll(TransientViewActionFactory.createAllFor(this)); + return result; } - - public synchronized void updateTransientActions() { - transientActions = TransientViewActionFactory.createAllFor(this); - } - + + /** + * No-op. Included to maintain backwards compatibility. + * @deprecated This method does nothing and should not be used + */ + @Restricted(DoNotUse.class) + @Deprecated + public void updateTransientActions() {} + public Object getDynamic(String token) { for (Action a : getActions()) { String url = a.getUrlName(); @@ -994,7 +990,6 @@ public abstract class View extends AbstractModelObject implements AccessControll rename(req.getParameter("name")); getProperties().rebuild(req, req.getSubmittedForm(), getApplicablePropertyDescriptors()); - updateTransientActions(); save(); From eed7f5ee06b2014faa15f35daeacb7c1c17b41d6 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Fri, 28 Sep 2018 09:45:12 +0200 Subject: [PATCH 11/47] Remove SECURITY-218 class import from TcpSlaveAgentListener test. YAGNI. --- test/src/test/java/hudson/TcpSlaveAgentListenerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/src/test/java/hudson/TcpSlaveAgentListenerTest.java b/test/src/test/java/hudson/TcpSlaveAgentListenerTest.java index 25bf75d9d4..fe29570086 100644 --- a/test/src/test/java/hudson/TcpSlaveAgentListenerTest.java +++ b/test/src/test/java/hudson/TcpSlaveAgentListenerTest.java @@ -20,7 +20,6 @@ import javax.annotation.Nullable; import jenkins.model.Jenkins; import jenkins.model.identity.InstanceIdentityProvider; -import jenkins.security.security218.ysoserial.ExecBlockingSecurityManager.ExecException; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; From 179d59767958a8d40e15c7eed4db82b9ef7b88db Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Fri, 28 Sep 2018 13:59:14 +0200 Subject: [PATCH 12/47] introduce hudson.Util#fixNull(value, defaultValue) Signed-off-by: Nicolas De Loof --- core/src/main/java/hudson/Util.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index d3aa18870d..0a13082b4b 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -1195,8 +1195,14 @@ public class Util { */ @Nonnull public static String fixNull(@CheckForNull String s) { - if(s==null) return ""; - else return s; + return fixNull(s, ""); + } + + /** + * Convert null to defaultValue. + */ + public static T fixNull(@CheckForNull T s, T defaultValue) { + return s != null ? s : defaultValue; } /** @@ -1221,22 +1227,22 @@ public class Util { @Nonnull public static List fixNull(@CheckForNull List l) { - return l!=null ? l : Collections.emptyList(); + return fixNull(l, Collections.emptyList()); } @Nonnull public static Set fixNull(@CheckForNull Set l) { - return l!=null ? l : Collections.emptySet(); + return fixNull(l, Collections.emptySet()); } @Nonnull public static Collection fixNull(@CheckForNull Collection l) { - return l!=null ? l : Collections.emptySet(); + return fixNull(l, Collections.emptySet()); } @Nonnull public static Iterable fixNull(@CheckForNull Iterable l) { - return l!=null ? l : Collections.emptySet(); + return fixNull(l, Collections.emptySet()); } /** From 143c1c5d2835554780e0aa9baa3bc517bb121561 Mon Sep 17 00:00:00 2001 From: Jeff Thompson Date: Fri, 28 Sep 2018 10:17:20 -0600 Subject: [PATCH 13/47] Upgrade to latest version of Remoting. Primarily this eliminates a potential deadlock in managing the ProtocolStack. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 170c042c5a..1ad533b586 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ THE SOFTWARE. 3.0.0 - 3.26 + 3.27 3.4 From 2d7b2b6e24b9df04f72d80906bddd941107469d1 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Fri, 28 Sep 2018 20:46:29 +0200 Subject: [PATCH 14/47] [JENKINS-51903] - Allow specifying multiple Java versions in Jenkinsfile Backports Jenkinsfile from the java11-support branch --- Jenkinsfile | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b3285a5c64..f6eb3e2c0c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -17,11 +17,14 @@ properties([buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: // see https://github.com/jenkins-infra/documentation/blob/master/ci.adoc for information on what node types are available def buildTypes = ['Linux', 'Windows'] +def jdks = [8] def builds = [:] for(i = 0; i < buildTypes.size(); i++) { +for(j = 0; j < jdks.size(); j++) { def buildType = buildTypes[i] - builds[buildType] = { + def jdk = jdks[j] + builds["${buildType}-jdk${jdk}"] = { node(buildType.toLowerCase()) { timestamps { // First stage is actually checking out the source. Since we're using Multibranch @@ -39,10 +42,11 @@ for(i = 0; i < buildTypes.size(); i++) { // See below for what this method does - we're passing an arbitrary environment // variable to it so that JAVA_OPTS and MAVEN_OPTS are set correctly. withMavenEnv(["JAVA_OPTS=-Xmx1536m -Xms512m", - "MAVEN_OPTS=-Xmx1536m -Xms512m"]) { + "MAVEN_OPTS=-Xmx1536m -Xms512m"], jdk) { // Actually run Maven! // -Dmaven.repo.local=… tells Maven to create a subdir in the temporary directory for the local Maven repository def mvnCmd = "mvn -Pdebug -U -Dset.changelist help:evaluate -Dexpression=changelist -Doutput=$changelistF clean install ${runTests ? '-Dmaven.test.failure.ignore' : '-DskipTests'} -V -B -Dmaven.repo.local=$m2repo -s settings-azure.xml -e" + if(isUnix()) { sh mvnCmd sh 'test `git status --short | tee /dev/stderr | wc --bytes` -eq 0' @@ -71,8 +75,9 @@ for(i = 0; i < buildTypes.size(); i++) { } } } -} +}} +// TODO: ATH flow now supports Java 8 only, it needs to be reworked (INFRA-1690) builds.ath = { node("docker&&highmem") { // Just to be safe @@ -82,7 +87,7 @@ builds.ath = { dir("sources") { checkout scm withMavenEnv(["JAVA_OPTS=-Xmx1536m -Xms512m", - "MAVEN_OPTS=-Xmx1536m -Xms512m"]) { + "MAVEN_OPTS=-Xmx1536m -Xms512m"], 8) { sh "mvn --batch-mode --show-version -DskipTests -am -pl war package -Dmaven.repo.local=${pwd tmp: true}/m2repo -s settings-azure.xml" } dir("war/target") { @@ -103,13 +108,13 @@ infra.maybePublishIncrementals() // This method sets up the Maven and JDK tools, puts them in the environment along // with whatever other arbitrary environment variables we passed in, and runs the // body we passed in within that environment. -void withMavenEnv(List envVars = [], def body) { +void withMavenEnv(List envVars = [], def javaVersion, def body) { // The names here are currently hardcoded for my test environment. This needs // to be made more flexible. // Using the "tool" Workflow call automatically installs those tools on the // node. String mvntool = tool name: "mvn", type: 'hudson.tasks.Maven$MavenInstallation' - String jdktool = tool name: "jdk8", type: 'hudson.model.JDK' + String jdktool = tool name: "jdk${javaVersion}", type: 'hudson.model.JDK' // Set JAVA_HOME, MAVEN_HOME and special PATH variables for the tools we're // using. From 18027c5b0c4ab9f0dc1fe180282742c0144e672a Mon Sep 17 00:00:00 2001 From: Devin Nusbaum Date: Mon, 18 Jun 2018 09:56:08 -0400 Subject: [PATCH 15/47] [JENKINS-46725] - Update jnr-posix to 3.0.45 to prevent Illegal Reflective acces warnings --- core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pom.xml b/core/pom.xml index 258e26f64f..3452fd0542 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -109,7 +109,7 @@ THE SOFTWARE. com.github.jnr jnr-posix - 3.0.41 + 3.0.45 org.kohsuke From f9cefcb0d4e30e3dd927fd1fa15f7cea83efd2e5 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Fri, 28 Sep 2018 21:12:14 +0200 Subject: [PATCH 16/47] [JENKINS-52024] - Update Metainf services from 1.4 to 1.8 in the master branch --- core/pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/pom.xml b/core/pom.xml index 258e26f64f..4e8ed6d9f7 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -570,8 +570,7 @@ THE SOFTWARE. org.kohsuke.metainf-services metainf-services - 1.4 - provided + 1.8 true From ce68c48704bde42e1b31bb1e8e39c117b65d45ae Mon Sep 17 00:00:00 2001 From: Sam Van Oort Date: Fri, 22 Jun 2018 11:13:50 -0400 Subject: [PATCH 17/47] [JENKINS-52024] - Hard dependency on lib-annotation-indexer to override stale version provided by transitive deps --- cli/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cli/pom.xml b/cli/pom.xml index 69c53a20a4..73b4faab3e 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -33,6 +33,11 @@ org.kohsuke access-modifier-annotation + + org.jenkins-ci + annotation-indexer + 1.12 + commons-codec commons-codec From 7bc431f09d05c0a6c0da9798fd773a02a7fce277 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 28 Sep 2018 16:35:38 -0400 Subject: [PATCH 18/47] The context type parameter on ConsoleAnnotatorFactory did not work. --- .../main/java/hudson/console/AnnotatedLargeText.java | 6 +++--- .../console/ConsoleAnnotationOutputStream.java | 9 ++++++--- .../main/java/hudson/console/ConsoleAnnotator.java | 12 ++++++++---- .../java/hudson/console/ConsoleAnnotatorFactory.java | 9 +++++---- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index edfab781f2..6acbdeff6e 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -113,7 +113,7 @@ public class AnnotatedLargeText extends LargeText { rsp.setContentType(isHtml() ? "text/html;charset=UTF-8" : "text/plain;charset=UTF-8"); } - private ConsoleAnnotator createAnnotator(StaplerRequest req) throws IOException { + private ConsoleAnnotator createAnnotator(StaplerRequest req) throws IOException { try { String base64 = req!=null ? req.getHeader("X-ConsoleAnnotator") : null; if (base64!=null) { @@ -135,7 +135,7 @@ public class AnnotatedLargeText extends LargeText { throw new IOException(e); } // start from scratch - return ConsoleAnnotator.initial(context==null ? null : context.getClass()); + return ConsoleAnnotator.initial(context); } @Override @@ -164,7 +164,7 @@ public class AnnotatedLargeText extends LargeText { } public long writeHtmlTo(long start, Writer w) throws IOException { - ConsoleAnnotationOutputStream caw = new ConsoleAnnotationOutputStream( + ConsoleAnnotationOutputStream caw = new ConsoleAnnotationOutputStream<>( w, createAnnotator(Stapler.getCurrentRequest()), context, charset); long r = super.writeLogTo(start,caw); diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java b/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java index 919e3af011..f3a22c875c 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationOutputStream.java @@ -72,7 +72,7 @@ public class ConsoleAnnotationOutputStream extends LineTransformationOutputSt this.lineOut = new WriterOutputStream(line,charset); } - public ConsoleAnnotator getConsoleAnnotator() { + public ConsoleAnnotator getConsoleAnnotator() { return ann; } @@ -80,6 +80,8 @@ public class ConsoleAnnotationOutputStream extends LineTransformationOutputSt * Called after we read the whole line of plain text, which is stored in {@link #buf}. * This method performs annotations and send the result to {@link #out}. */ + @SuppressWarnings({"unchecked", "rawtypes"}) // appears to be unsound + @Override protected void eol(byte[] in, int sz) throws IOException { line.reset(); final StringBuffer strBuf = line.getStringBuffer(); @@ -109,9 +111,10 @@ public class ConsoleAnnotationOutputStream extends LineTransformationOutputSt final ConsoleNote a = ConsoleNote.readFrom(new DataInputStream(b)); if (a!=null) { if (annotators==null) - annotators = new ArrayList>(); + annotators = new ArrayList<>(); annotators.add(new ConsoleAnnotator() { - public ConsoleAnnotator annotate(T context, MarkupText text) { + @Override + public ConsoleAnnotator annotate(T context, MarkupText text) { return a.annotate(context,text,charPos); } }); diff --git a/core/src/main/java/hudson/console/ConsoleAnnotator.java b/core/src/main/java/hudson/console/ConsoleAnnotator.java index 475badceb6..9701eb302f 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotator.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotator.java @@ -82,22 +82,25 @@ public abstract class ConsoleAnnotator implements Serializable { * To indicate that you are not interested in the following lines, return {@code null}. */ @CheckForNull - public abstract ConsoleAnnotator annotate(@Nonnull T context, @Nonnull MarkupText text ); + public abstract ConsoleAnnotator annotate(@Nonnull T context, @Nonnull MarkupText text ); /** * Cast operation that restricts T. */ + @SuppressWarnings("unchecked") public static ConsoleAnnotator cast(ConsoleAnnotator a) { return (ConsoleAnnotator)a; } + @SuppressWarnings({"unchecked", "rawtypes"}) // unclear to jglick what is going on here private static final class ConsoleAnnotatorAggregator extends ConsoleAnnotator { List> list; ConsoleAnnotatorAggregator(Collection list) { - this.list = new ArrayList>(list); + this.list = new ArrayList<>(list); } + @Override public ConsoleAnnotator annotate(T context, MarkupText text) { ListIterator> itr = list.listIterator(); while (itr.hasNext()) { @@ -126,7 +129,7 @@ public abstract class ConsoleAnnotator implements Serializable { case 1: return cast(all.iterator().next()); // just one } - return new ConsoleAnnotatorAggregator(all); + return new ConsoleAnnotatorAggregator<>(all); } /** @@ -140,8 +143,9 @@ public abstract class ConsoleAnnotator implements Serializable { /** * List all the console annotators that can work for the specified context type. */ + @SuppressWarnings({"unchecked", "rawtypes"}) // reflective public static List> _for(T context) { - List> r = new ArrayList>(); + List> r = new ArrayList<>(); for (ConsoleAnnotatorFactory f : ConsoleAnnotatorFactory.all()) { if (f.type().isInstance(context)) { ConsoleAnnotator ca = f.newInstance(context); diff --git a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java index f9feac4a95..409ee59c67 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotatorFactory.java @@ -80,13 +80,13 @@ public abstract class ConsoleAnnotatorFactory implements ExtensionPoint { * @return * null if this factory is not going to participate in the annotation of this console. */ - public abstract ConsoleAnnotator newInstance(T context); + public abstract ConsoleAnnotator newInstance(T context); /** * For which context type does this annotator work? */ - public Class type() { - Type type = Types.getBaseClass(getClass(), ConsoleAnnotator.class); + public Class type() { + Type type = Types.getBaseClass(getClass(), ConsoleAnnotatorFactory.class); if (type instanceof ParameterizedType) return Types.erasure(Types.getTypeArgument(type,0)); else @@ -105,7 +105,7 @@ public abstract class ConsoleAnnotatorFactory implements ExtensionPoint { } private URL getResource(String fileName) { - Class c = getClass(); + Class c = getClass(); return c.getClassLoader().getResource(c.getName().replace('.','/').replace('$','/')+ fileName); } @@ -125,6 +125,7 @@ public abstract class ConsoleAnnotatorFactory implements ExtensionPoint { /** * All the registered instances. */ + @SuppressWarnings("rawtypes") public static ExtensionList all() { return ExtensionList.lookup(ConsoleAnnotatorFactory.class); } From 52755f5e55f64fe55f3fdeb6b3b9ee562797052d Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sat, 29 Sep 2018 18:47:28 +0200 Subject: [PATCH 19/47] [JENKINS-52024] - Move annotation indexer to dependencyManagement as suggested by @jglick --- cli/pom.xml | 1 - core/pom.xml | 1 - pom.xml | 6 ++++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index 73b4faab3e..e65b174223 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -36,7 +36,6 @@ org.jenkins-ci annotation-indexer - 1.12 commons-codec diff --git a/core/pom.xml b/core/pom.xml index 4e8ed6d9f7..703a5ebe47 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -207,7 +207,6 @@ THE SOFTWARE. org.jenkins-ci annotation-indexer - 1.12 org.jenkins-ci diff --git a/pom.xml b/pom.xml index 170c042c5a..7378476037 100644 --- a/pom.xml +++ b/pom.xml @@ -266,6 +266,12 @@ THE SOFTWARE. commons-codec 1.9 + + + org.jenkins-ci + annotation-indexer + 1.12 + From beadc5946f4415b28cb6d7a3a9cfb8a2782ab316 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sun, 30 Sep 2018 12:37:53 +0200 Subject: [PATCH 20/47] Util#fixNull: Address Javadoc comments and add annotations --- core/src/main/java/hudson/Util.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 0a13082b4b..00a88df95e 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -1199,9 +1199,11 @@ public class Util { } /** - * Convert null to defaultValue. + * Convert {@code null} to a default value. + * @since TODO */ - public static T fixNull(@CheckForNull T s, T defaultValue) { + @Nonnull + public static T fixNull(@CheckForNull T s, @Nonnull T defaultValue) { return s != null ? s : defaultValue; } From 1a93f90adaa6250da86d3c3e1b4c96376d5f53a0 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 30 Sep 2018 17:35:53 -0700 Subject: [PATCH 21/47] [maven-release-plugin] prepare release jenkins-2.144 --- cli/pom.xml | 2 +- core/pom.xml | 2 +- pom.xml | 4 ++-- test/pom.xml | 2 +- war/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index 69c53a20a4..eba6136226 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.144 cli diff --git a/core/pom.xml b/core/pom.xml index 3452fd0542..e61fc9b155 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.144 jenkins-core diff --git a/pom.xml b/pom.xml index 1ad533b586..081b738b82 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.144 pom Jenkins main module @@ -59,7 +59,7 @@ THE SOFTWARE. scm:git:git://github.com/jenkinsci/jenkins.git scm:git:ssh://git@github.com/jenkinsci/jenkins.git https://github.com/jenkinsci/jenkins - ${scmTag} + jenkins-2.144 diff --git a/test/pom.xml b/test/pom.xml index 4f9dae71fa..500e4100ba 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.144 jenkins-test diff --git a/war/pom.xml b/war/pom.xml index a2a1e2502a..9ea7853ae3 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.144 jenkins-war From 008c4350849bd323f0b4adde03dbe7b5b58ed1e8 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 30 Sep 2018 17:36:06 -0700 Subject: [PATCH 22/47] [maven-release-plugin] prepare for next development iteration --- cli/pom.xml | 2 +- core/pom.xml | 2 +- pom.xml | 6 +++--- test/pom.xml | 2 +- war/pom.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index eba6136226..69c53a20a4 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.144 + ${revision}${changelist} cli diff --git a/core/pom.xml b/core/pom.xml index e61fc9b155..3452fd0542 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.144 + ${revision}${changelist} jenkins-core diff --git a/pom.xml b/pom.xml index 081b738b82..5cb9753a13 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.144 + ${revision}${changelist} pom Jenkins main module @@ -59,7 +59,7 @@ THE SOFTWARE. scm:git:git://github.com/jenkinsci/jenkins.git scm:git:ssh://git@github.com/jenkinsci/jenkins.git https://github.com/jenkinsci/jenkins - jenkins-2.144 + ${scmTag} @@ -75,7 +75,7 @@ THE SOFTWARE. - 2.144 + 2.145 -SNAPSHOT light-test true + + + smoke-test + + jenkins.model.StartupTest,jenkins.model.JenkinsTest,jenkins.install.*,jenkins.security.CustomClassFilterTest,hudson.AboutJenkinsTest,hudson.ClassicPluginStrategyTest,hudson.LauncherTest,hudson.slaves.JNLPLauncherTest,hudson.model.RunTest,hudson.model.UserTest,hudson.model.FreeStyleProjectTest,hudson.model.HudsonTest,hudson.model.ComputerTest,hudson.CLI.BuildCommandTest#sync,*.smokes + + all-tests From 4debff7e3adaa3932073f0eba1313d659fdcff4f Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sat, 6 Oct 2018 15:01:00 +0200 Subject: [PATCH 41/47] Update documentation to reflect the current test profiles --- BUILDING.TXT | 11 ----------- CONTRIBUTING.md | 6 ++++++ 2 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 BUILDING.TXT diff --git a/BUILDING.TXT b/BUILDING.TXT deleted file mode 100644 index bde5cadf35..0000000000 --- a/BUILDING.TXT +++ /dev/null @@ -1,11 +0,0 @@ -If you want simply to have the jenkins.war as fast as possible (without test -execution), run: - - mvn clean install -pl war -am -DskipTests - -The WAR file will be in war/target/jenkins.war (you can play with it) - -For more information on building Jenkins, visit -https://wiki.jenkins-ci.org/display/JENKINS/Building+Jenkins - -Have Fun !! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d419bd03a9..ab12568a0a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,6 +46,12 @@ Functional tests (`test` module) take a while even on server-grade machines. Most of the tests will be launched by the continuous integration instance, so there is no strict need to run full test suites before proposing a pull request. +There are 3 profiles for tests: + +* `light-test` - only unit tests, no functional tests +* `smoke-test` - run unit tests + a number of functional tests +* `all-tests` - Runs all tests, with re-run (default) + In addition to the included tests, you can also find extra integration and UI tests in the [Acceptance Test Harness (ATH)](https://github.com/jenkinsci/acceptance-test-harness) repository. If you propose complex UI changes, you should create new ATH tests for them. From e998a7808ff7bf2523382fac8a28c2c1912b63a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Fern=C3=A1ndez?= <31063239+fcojfernandez@users.noreply.github.com> Date: Sat, 6 Oct 2018 16:05:38 +0200 Subject: [PATCH 42/47] [JENKINS-53792] Env vars to configure CLI -auth option (#3653) * [JENKINS-53792] Add env vars for auth option * [JENKINS-53792] Fix encoding after first commit * [JENKINS-53792] Better readability * [JENKINS-53792] Refactor and use the ApiToken * [JENKINS-53792] Fix encoding --- cli/pom.xml | 4 + cli/src/main/java/hudson/cli/CLI.java | 16 ++ .../hudson/cli/client/Messages.properties | 4 +- .../hudson/cli/client/Messages_es.properties | 28 +- core/pom.xml | 1 - pom.xml | 6 + .../test/java/hudson/cli/CLIEnvVarTest.java | 242 ++++++++++++++++++ 7 files changed, 292 insertions(+), 9 deletions(-) create mode 100644 test/src/test/java/hudson/cli/CLIEnvVarTest.java diff --git a/cli/pom.xml b/cli/pom.xml index e65b174223..670e416a26 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -81,6 +81,10 @@ annotations provided + + commons-lang + commons-lang + diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index 5da726be0e..52c6785d58 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -77,6 +77,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import static java.util.logging.Level.*; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; /** * CLI entry point to Jenkins. @@ -452,6 +453,10 @@ public class CLI implements AutoCloseable { String user = null; String auth = null; + + String userIdEnv = System.getenv("JENKINS_USER_ID"); + String tokenEnv = System.getenv("JENKINS_API_TOKEN"); + boolean strictHostKey = false; while(!args.isEmpty()) { @@ -563,6 +568,17 @@ public class CLI implements AutoCloseable { return -1; } + if (auth == null) { + // -auth option not set + if (StringUtils.isNotBlank(userIdEnv) && StringUtils.isNotBlank(tokenEnv)) { + auth = StringUtils.defaultString(userIdEnv).concat(":").concat(StringUtils.defaultString(tokenEnv)); + } else if (StringUtils.isNotBlank(userIdEnv) || StringUtils.isNotBlank(tokenEnv)) { + printUsage(Messages.CLI_BadAuth()); + return -1; + } // Otherwise, none credentials were set + + } + if (!url.endsWith("/")) { url += '/'; } diff --git a/cli/src/main/resources/hudson/cli/client/Messages.properties b/cli/src/main/resources/hudson/cli/client/Messages.properties index 921fe67a21..44fa79c6fd 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages.properties @@ -13,10 +13,12 @@ CLI.Usage=Jenkins CLI\n\ -strictHostKey : request strict host key checking (for use with -ssh)\n\ -logger FINE : enable detailed logging from the client\n\ -auth [ USER:SECRET | @FILE ] : specify username and either password or API token (or load from them both from a file);\n\ - for use with -http, or -remoting but only when the JNLP agent port is disabled\n\ + for use with -http, or -remoting but only when the JNLP agent port is disabled.\n\ + Not necessary if JENKINS_USER_ID and JENKINS_API_TOKEN env vars are set\n\ \n\ The available commands depend on the server. Run the 'help' command to\n\ see the list. CLI.NoURL=Neither -s nor the JENKINS_URL env var is specified. CLI.VersionMismatch=Version mismatch. This CLI cannot work with this Jenkins server. CLI.NoSuchFileExists=No such file exists: {0} +CLI.BadAuth=The JENKINS_USER_ID and JENKINS_API_TOKEN env vars should be both set or left empty. diff --git a/cli/src/main/resources/hudson/cli/client/Messages_es.properties b/cli/src/main/resources/hudson/cli/client/Messages_es.properties index f9979a5619..b8ff42b3c2 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_es.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_es.properties @@ -1,10 +1,24 @@ CLI.Usage=Jenkins CLI\n\ - Usar: java -jar jenkins-cli.jar [-s URL] command [opts...] args...\n\ - Options:\n\ - \ -s URL : dirección web (por defecto se usa la variable JENKINS_URL)\n\ + Uso: java -jar jenkins-cli.jar [-s URL] command [opts...] args...\n\ + Opciones:\n\ + -s URL : direcci\u00f3n web (por defecto se usa la variable JENKINS_URL)\n\ + -http : usa un protocolo plano sobre HTTP(S) (es el uso por defecto; excluyente con -ssh y -remoting)\n\ + -ssh : usa el protocolo SSH (requiere -user; el puerto SSH debe estar abierto en el servidor y el usuario debe tener registrada su clave publica)\n\ + -remoting : usa el protocolo deprecado de Remoting (siempre que est\u00e9 habilitado en el servidor; s\u00f3lo para compatibilidad con comandos heredados o legacy)\n\ + -i KEY : clave privada SSH usada para autenticaci\u00f3n (usado con -ssh o -remoting)\n\ + -p HOST:PORT : host y puerto para el uso de proxy HTTPS. Ver https://jenkins.io/redirect/cli-https-proxy-tunnel\n\ + -noCertificateCheck : elude por completo la verificaci\u00f3n del certificado HTTPS. Usar con precauci\u00f3n\n\ + -noKeyAuth : intenta no cargar la clave privada de autenticaci\u00f3n SSH. Presenta conflicto con -i\n\ + -user : especifica el usuario (se usa con -ssh)\n\ + -strictHostKey : solicita la comprobaci\u00f3n estricta de la clave del host (se usa con -ssh)\n\ + -logger FINE : habilita logs detallados en el cliente\n\ + -auth [ USER:SECRET | @FILE ] : especifica el usuario y contrase\u00f1a o API token (o los carga de un fichero);\n\ + se usa con -http o -remoting pero s\u00f3lo si el puerto del agente JNLP est\u00e1 deshabilitado.\n\ + No es necesario si las variables de entorno JENKINS_USER_ID y JENKINS_API_TOKEN se encuentran configuradas.\n\ \n\ - La lista completa de comandos disponibles depende del servidor. Ejecuta\n\ - el comando ''help'' para ver la lista. -CLI.NoURL=No se ha especificado el parámetro -s ni la variable JENKINS_URL -CLI.VersionMismatch=La versión no coincide. Esta consola "CLI" no se puede usar en este Jenkins + La lista de comandos disponibles depende del servidor. Ejecuta\n\ + el comando ''help'' para ver la lista completa. +CLI.NoURL=No se ha especificado el par\u00e1metro -s ni la variable JENKINS_URL +CLI.VersionMismatch=La versi\u00f3n no coincide. Esta consola "CLI" no se puede usar en este Jenkins CLI.NoSuchFileExists=El fichero {0} no existe. +CLI.BadAuth=Ambas variables de entorno JENKINS_USER_ID y JENKINS_API_TOKEN deber\u00edan estar configuradas o mantenerse vac\u00edas. diff --git a/core/pom.xml b/core/pom.xml index f57e8453e8..a940e93423 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -279,7 +279,6 @@ THE SOFTWARE. commons-lang commons-lang - 2.6 commons-digester diff --git a/pom.xml b/pom.xml index c809736be4..e5f3dc51df 100644 --- a/pom.xml +++ b/pom.xml @@ -148,6 +148,12 @@ THE SOFTWARE. 2.4 + + commons-lang + commons-lang + 2.6 + + org.mockito mockito-core diff --git a/test/src/test/java/hudson/cli/CLIEnvVarTest.java b/test/src/test/java/hudson/cli/CLIEnvVarTest.java new file mode 100644 index 0000000000..0a5b18a928 --- /dev/null +++ b/test/src/test/java/hudson/cli/CLIEnvVarTest.java @@ -0,0 +1,242 @@ +package hudson.cli; + +import hudson.EnvVars; +import hudson.Launcher; +import hudson.model.User; +import hudson.util.StreamTaskListener; +import jenkins.model.Jenkins; +import jenkins.security.ApiTokenProperty; +import jenkins.security.apitoken.ApiTokenTestHelper; +import org.apache.commons.io.FileUtils; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.MockAuthorizationStrategy; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThat; + +public class CLIEnvVarTest { + + @Rule + public JenkinsRule r = new JenkinsRule(); + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + private File home; + private File jar; + + @Before + public void grabCliJar() throws IOException { + home = tmp.newFolder(); + jar = tmp.newFile("jenkins-cli.jar"); + FileUtils.copyURLToFile(r.jenkins.getJnlpJars("jenkins-cli.jar").getURL(), jar); + } + + @Test + public void testSOptionWithoutJENKINS_URL() throws Exception { + assertEquals(0, launch("java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + } + + @Test + public void testWithoutSOptionAndWithoutJENKINS_URL() throws Exception { + assertNotEquals(0, launch("java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "who-am-i") + ); + } + + @Test + public void testJENKINS_URLWithoutSOption() throws Exception { + // Valid URL + Map envars = new HashMap<>(); + envars.put("JENKINS_URL", r.getURL().toString()); + assertEquals(0, launch(envars, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "who-am-i") + ); + + // Invalid URL + envars = new HashMap<>(); + envars.put("JENKINS_URL", "http://invalid-url"); + assertNotEquals(0, launch(envars, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "who-am-i") + ); + + } + + @Test + public void testSOptionOverridesJENKINS_URL() throws Exception { + Map envars = new HashMap<>(); + envars.put("JENKINS_URL", "http://invalid-url"); + assertEquals(0, launch(envars, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + } + + @Test + public void testAuthOptionWithoutEnvVars() throws Exception { + String token = getToken(); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + assertEquals(0, launch(Collections.emptyMap(), baos, null, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "-auth", String.format("%s:%s", "admin", token), + "who-am-i") + ); + assertThat(baos.toString(), containsString("Authenticated as: admin")); + } + } + + @Test + public void testWithoutEnvVarsAndWithoutAuthOption() throws Exception { + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().to("admin")); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + assertEquals(0, launch(Collections.emptyMap(), baos, null, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + assertThat(baos.toString(), containsString("Authenticated as: anonymous")); + } + } + + @Test + public void testEnvVarsWithoutAuthOption() throws Exception { + String token = getToken(); + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + Map envars = new HashMap<>(); + envars.put("JENKINS_USER_ID", "admin"); + envars.put("JENKINS_API_TOKEN", token); + assertEquals(0, launch(envars, baos, null, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + assertThat(baos.toString(), containsString("Authenticated as: admin")); + } + } + + @Test + public void testOnlyOneEnvVar() throws Exception { + String token = getToken(); + + // only JENKINS_USER_ID + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + Map envars = new HashMap<>(); + envars.put("JENKINS_USER_ID", "admin"); + assertNotEquals(0, launch(envars, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + } + + // only JENKINS_API_TOKEN + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + Map envars = new HashMap<>(); + envars.put("JENKINS_API_TOKEN", token); + assertNotEquals(0, launch(envars, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "who-am-i") + ); + } + } + + @Test + public void testAuthOptionOverridesEnvVars() throws Exception { + String token = getToken(); + + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + Map envars = new HashMap<>(); + envars.put("JENKINS_USER_ID", "other-user"); + envars.put("JENKINS_API_TOKEN", "other-user"); + assertEquals(0, launch(envars, baos, null, + "java", + "-Duser.home=" + home, + "-jar", jar.getAbsolutePath(), + "-s", r.getURL().toString(), + "-auth", String.format("%s:%s", "admin", token), + "who-am-i") + ); + assertThat(baos.toString(), containsString("Authenticated as: admin")); + } + } + + private String getToken() { + ApiTokenTestHelper.enableLegacyBehavior(); + + r.jenkins.setSecurityRealm(r.createDummySecurityRealm()); + r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy().grant(Jenkins.ADMINISTER).everywhere().to("admin")); + + return User.get("admin").getProperty(ApiTokenProperty.class).getApiToken(); + } + + private int launch(String... cmdArgs) throws Exception { + return launch(Collections.emptyMap(), cmdArgs); + } + + private int launch(Map envars, String... cmdArgs) throws Exception { + return launch(envars, null, null, cmdArgs); + } + + private int launch(Map envars, OutputStream out, OutputStream err, String... cmdArgs) throws Exception { + if (out == null) { + out = System.out; + } + + if (err == null) { + err = System.err; + } + + return new Launcher.LocalLauncher(StreamTaskListener.fromStderr()) + .decorateByEnv(new EnvVars(envars)) + .launch() + .cmds(cmdArgs) + .stdout(out) + .stderr(err) + .join(); + } +} From d411213546138cbd29eb2fc5e2425a2ff79558a9 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sat, 6 Oct 2018 16:27:32 +0200 Subject: [PATCH 43/47] Update parent POM to 1.49 to pick-up updates for JDK11 build flow --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c809736be4..73df75e98e 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.48 + 1.49 From 56c6571d7342e25c521e0b83f268b16bf48ded12 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sun, 7 Oct 2018 19:19:36 +0200 Subject: [PATCH 44/47] [JENKINS-53792] - Update CLI help to advertise usage of credential files (#3684) * [JENKINS-53792] - Update CLI help to advertise usage of credential files * [JENKINS-53792] - Use redirect as suggested by @daniel-beck --- cli/src/main/resources/hudson/cli/client/Messages.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/src/main/resources/hudson/cli/client/Messages.properties b/cli/src/main/resources/hudson/cli/client/Messages.properties index 44fa79c6fd..1dd17040cc 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages.properties @@ -14,7 +14,8 @@ CLI.Usage=Jenkins CLI\n\ -logger FINE : enable detailed logging from the client\n\ -auth [ USER:SECRET | @FILE ] : specify username and either password or API token (or load from them both from a file);\n\ for use with -http, or -remoting but only when the JNLP agent port is disabled.\n\ - Not necessary if JENKINS_USER_ID and JENKINS_API_TOKEN env vars are set\n\ + Passing crendentials by a file is recommended.\n\ + See https://jenkins.io/redirect/cli-http-connection-mode for more info and options.\n\ \n\ The available commands depend on the server. Run the 'help' command to\n\ see the list. From 4b32eac1129d03169af8a14deb4cccb00af8cc99 Mon Sep 17 00:00:00 2001 From: Zhao Xiaojie Date: Mon, 8 Oct 2018 04:04:33 +0800 Subject: [PATCH 45/47] Add i18n support for "icon size" control hyperlinks (#3681) * Add i18n support * Add original localize file. --- .../main/resources/lib/hudson/iconSize.jelly | 6 ++--- .../resources/lib/hudson/iconSize.properties | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 core/src/main/resources/lib/hudson/iconSize.properties diff --git a/core/src/main/resources/lib/hudson/iconSize.jelly b/core/src/main/resources/lib/hudson/iconSize.jelly index 5f5ec7f4b3..4dd5fbeff1 100644 --- a/core/src/main/resources/lib/hudson/iconSize.jelly +++ b/core/src/main/resources/lib/hudson/iconSize.jelly @@ -41,9 +41,9 @@ THE SOFTWARE. ${%Icon}: - - - + + + diff --git a/core/src/main/resources/lib/hudson/iconSize.properties b/core/src/main/resources/lib/hudson/iconSize.properties new file mode 100644 index 0000000000..d4292959f9 --- /dev/null +++ b/core/src/main/resources/lib/hudson/iconSize.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright (c) 2018, linuxsuren +# +# 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. + +Icon=Icon +S=S +M=M +L=L From 97a853112d60905988959ea80f95f7b555f1aa02 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 7 Oct 2018 19:17:41 -0700 Subject: [PATCH 46/47] [maven-release-plugin] prepare release jenkins-2.145 --- cli/pom.xml | 2 +- core/pom.xml | 2 +- pom.xml | 4 ++-- test/pom.xml | 2 +- war/pom.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index 670e416a26..fdf4b3077a 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.145 cli diff --git a/core/pom.xml b/core/pom.xml index a940e93423..15223d867a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.145 jenkins-core diff --git a/pom.xml b/pom.xml index 2253973dc3..2432ef3303 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.145 pom Jenkins main module @@ -59,7 +59,7 @@ THE SOFTWARE. scm:git:git://github.com/jenkinsci/jenkins.git scm:git:ssh://git@github.com/jenkinsci/jenkins.git https://github.com/jenkinsci/jenkins - ${scmTag} + jenkins-2.145 diff --git a/test/pom.xml b/test/pom.xml index 7f08f9b914..7d63f37627 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.145 jenkins-test diff --git a/war/pom.xml b/war/pom.xml index a2a1e2502a..bd331970b4 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -28,7 +28,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - ${revision}${changelist} + 2.145 jenkins-war From edd303e91747380043723c1b4c7dc843b91afa51 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 7 Oct 2018 19:17:54 -0700 Subject: [PATCH 47/47] [maven-release-plugin] prepare for next development iteration --- cli/pom.xml | 2 +- core/pom.xml | 2 +- pom.xml | 6 +++--- test/pom.xml | 2 +- war/pom.xml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/pom.xml b/cli/pom.xml index fdf4b3077a..670e416a26 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main jenkins-parent - 2.145 + ${revision}${changelist} cli diff --git a/core/pom.xml b/core/pom.xml index 15223d867a..a940e93423 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.145 + ${revision}${changelist} jenkins-core diff --git a/pom.xml b/pom.xml index 2432ef3303..5207f1d1e4 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-parent - 2.145 + ${revision}${changelist} pom Jenkins main module @@ -59,7 +59,7 @@ THE SOFTWARE. scm:git:git://github.com/jenkinsci/jenkins.git scm:git:ssh://git@github.com/jenkinsci/jenkins.git https://github.com/jenkinsci/jenkins - jenkins-2.145 + ${scmTag} @@ -75,7 +75,7 @@ THE SOFTWARE. - 2.145 + 2.146 -SNAPSHOT