diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 9c79924e7b32eaa837ef99afe6efffc6e78f6f92..3ef1a3ab06acea13be02ac7fc68d387a73314bf6 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -101,6 +101,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Future; +import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; import org.xml.sax.Attributes; @@ -729,11 +730,19 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas if(!fileName.endsWith(".jpi") && !fileName.endsWith(".hpi")){ throw new Failure(hudson.model.Messages.Hudson_NotAPlugin(fileName)); } - final String baseName = FilenameUtils.getBaseName(fileName); - new File(rootDir, baseName + ".hpi").delete(); // don't keep confusing legacy *.hpi - fileItem.write(new File(rootDir, baseName + ".jpi")); // rename all new plugins to *.jpi + + // first copy into a temporary file name + File t = File.createTempFile("uploaded", "jp_",rootDir); + fileItem.write(t); // rename all new plugins to *.jpi fileItem.delete(); + final String baseName = identifyPluginShortName(t); + + // and move the temp file into a proper name + new File(rootDir, baseName + ".hpi").delete(); // don't keep confusing legacy *.hpi + new File(rootDir, baseName + ".jpi").delete(); // rename can fail if the file already exists + t.renameTo(new File(rootDir, baseName + ".jpi")); + PluginWrapper existing = getPlugin(baseName); if (existing!=null && existing.isBundled){ existing.doPin(); @@ -749,6 +758,21 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas } } + protected String identifyPluginShortName(File t) { + try { + JarFile j = new JarFile(t); + try { + String name = j.getManifest().getMainAttributes().getValue("Short-Name"); + if (name!=null) return name; + } finally { + j.close(); + } + } catch (IOException e) { + LOGGER.log(WARNING, "Failed to identify the short name from "+t,e); + } + return FilenameUtils.getBaseName(t.getName()); // fall back to the base name of what's uploaded + } + public Descriptor getProxyDescriptor() { return Jenkins.getInstance().getDescriptor(ProxyConfiguration.class); }