diff --git a/changelog.html b/changelog.html
index b62d2499495def2906db363fb3abc6283f1ad445..062b8e4bde3a169d0e6439c4d20e93365a51ff98 100644
--- a/changelog.html
+++ b/changelog.html
@@ -65,6 +65,9 @@ Upcoming changes
Improved the tracking of queued jobs and their eventual builds in the REST API.
Added a new extension point to contribute custom plexus components into Maven for the maven project type.
+
+ Remoting classloader performance improvement upon reconnection to the same slave.
+ (issue 15120)
diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java
index 56b8ee59903a91ba8d2bf4d4f97e3e6e3fcf17da..28c1ad78e50f28bba4e80deb5cb82b50093daa05 100644
--- a/core/src/main/java/hudson/ClassicPluginStrategy.java
+++ b/core/src/main/java/hudson/ClassicPluginStrategy.java
@@ -23,7 +23,6 @@
*/
package hudson;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import hudson.Plugin.DummyImpl;
import hudson.PluginWrapper.Dependency;
@@ -36,11 +35,21 @@ import hudson.util.MaskingClassLoader;
import hudson.util.VersionNumber;
import jenkins.ClassLoaderReflectionToolkit;
import jenkins.ExtensionFilter;
+import org.apache.commons.io.output.NullOutputStream;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
+import org.apache.tools.ant.taskdefs.Zip;
import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.Resource;
+import org.apache.tools.ant.types.ZipFileSet;
+import org.apache.tools.ant.types.resources.MappedResourceCollection;
+import org.apache.tools.ant.util.GlobPatternMapper;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipExtraField;
+import org.apache.tools.zip.ZipOutputStream;
import java.io.Closeable;
import java.io.File;
@@ -57,7 +66,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.jar.Attributes;
@@ -413,11 +421,10 @@ public class ClassicPluginStrategy implements PluginStrategy {
* Explodes the plugin into a directory, if necessary.
*/
private static void explode(File archive, File destDir) throws IOException {
- if(!destDir.exists())
- destDir.mkdirs();
+ destDir.mkdirs();
// timestamp check
- File explodeTime = new File(destDir,".timestamp");
+ File explodeTime = new File(destDir,".timestamp2");
if(explodeTime.exists() && explodeTime.lastModified()==archive.lastModified())
return; // no need to expand
@@ -425,12 +432,9 @@ public class ClassicPluginStrategy implements PluginStrategy {
Util.deleteRecursive(destDir);
try {
- Expand e = new Expand();
- e.setProject(new Project());
- e.setTaskType("unzip");
- e.setSrc(archive);
- e.setDest(destDir);
- e.execute();
+ Project prj = new Project();
+ unzipExceptClasses(archive, destDir, prj);
+ createClassJarFromWebInfClasses(archive, destDir, prj);
} catch (BuildException x) {
throw new IOException2("Failed to expand " + archive,x);
}
@@ -442,6 +446,66 @@ public class ClassicPluginStrategy implements PluginStrategy {
}
}
+ /**
+ * Repackage classes directory into a jar file to make it remoting friendly.
+ * The remoting layer can cache jar files but not class files.
+ */
+ private static void createClassJarFromWebInfClasses(File archive, File destDir, Project prj) {
+ File classesJar = new File(destDir, "WEB-INF/lib/classes.jar");
+
+ ZipFileSet zfs = new ZipFileSet();
+ zfs.setProject(prj);
+ zfs.setSrc(archive);
+ zfs.setIncludes("WEB-INF/classes/");
+
+ MappedResourceCollection mapper = new MappedResourceCollection();
+ mapper.add(zfs);
+
+ GlobPatternMapper gm = new GlobPatternMapper();
+ gm.setFrom("WEB-INF/classes/*");
+ gm.setTo("*");
+ mapper.add(gm);
+
+ final long dirTime = archive.lastModified();
+ Zip z = new Zip() {
+ /**
+ * Forces the fixed timestamp for directories to make sure
+ * classes.jar always get a consistent checksum.
+ */
+ protected void zipDir(Resource dir, ZipOutputStream zOut, String vPath,
+ int mode, ZipExtraField[] extra)
+ throws IOException {
+
+ ZipOutputStream wrapped = new ZipOutputStream(new NullOutputStream()) {
+ @Override
+ public void putNextEntry(ZipEntry ze) throws IOException {
+ ze.setTime(dirTime+1999); // roundup
+ super.putNextEntry(ze);
+ }
+ };
+ super.zipDir(dir,wrapped,vPath,mode,extra);
+ }
+ };
+ z.setProject(prj);
+ z.setTaskType("zip");
+ classesJar.getParentFile().mkdirs();
+ z.setDestFile(classesJar);
+ z.add(mapper);
+ z.execute();
+ }
+
+ private static void unzipExceptClasses(File archive, File destDir, Project prj) {
+ Expand e = new Expand();
+ e.setProject(prj);
+ e.setTaskType("unzip");
+ e.setSrc(archive);
+ e.setDest(destDir);
+ PatternSet p = new PatternSet();
+ p.setExcludes("WEB-INF/classes/");
+ e.addPatternset(p);
+ e.execute();
+ }
+
/**
* Used to load classes from dependency plugins.
*/
diff --git a/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java b/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
index 50010b413075867e17f91c971a518c85e6584007..d39e3f603ba1d10e84989876dcbad9bd81199e66 100644
--- a/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
+++ b/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java
@@ -160,6 +160,9 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
throw new IOException2(e);
} catch (Exception e) {
throw new IOException2(e);
+ } finally {
+ if (DUMP_PERFORMANCE_COUNTERS)
+ Channel.current().dumpPerformanceCounters(listener.error("Remoting stats"));
}
}
@@ -571,4 +574,6 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(Maven3Builder.class.getName());
+
+ public static boolean DUMP_PERFORMANCE_COUNTERS = Boolean.getBoolean(Maven3Builder.class.getName()+".dumpPerformanceCounters");
}
diff --git a/pom.xml b/pom.xml
index 39b28080756b0b707c5f09b4c97ba97b9fb86aaa..b071d7747ef3eb25ead1551c6377a3400de64e6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -175,7 +175,7 @@ THE SOFTWARE.
org.jenkins-ci.main
remoting
- 2.23
+ 2.24