/** Extract a resource from jar, mark it for deletion upon exit, and return its location. */ private static File extractFromJar( String resource, String fileName, String suffix, File directory) throws IOException { URL res = Main.class.getResource(resource); if (res == null) throw new IOException("Unable to find the resource: " + resource); // put this jar in a file system so that we can load jars from there File tmp; try { tmp = File.createTempFile(fileName, suffix, directory); } catch (IOException e) { String tmpdir = (directory == null) ? System.getProperty("java.io.tmpdir") : directory.getAbsolutePath(); IOException x = new IOException("Jenkins has failed to create a temporary file in " + tmpdir); x.initCause(e); throw x; } InputStream is = res.openStream(); try { OutputStream os = new FileOutputStream(tmp); try { copyStream(is, os); } finally { os.close(); } } finally { is.close(); } tmp.deleteOnExit(); return tmp; }
/** Figures out the URL of <tt>jenkins.war</tt>. */ public static File whoAmI(File directory) throws IOException, URISyntaxException { // JNLP returns the URL where the jar was originally placed (like http://jenkins-ci.org/...) // not the local cached file. So we need a rather round about approach to get to // the local file name. // There is no portable way to find where the locally cached copy // of jenkins.war/jar is; JDK 6 is too smart. (See JENKINS-2326.) try { URL classFile = Main.class.getClassLoader().getResource("Main.class"); JarFile jf = ((JarURLConnection) classFile.openConnection()).getJarFile(); Field f = ZipFile.class.getDeclaredField("name"); f.setAccessible(true); return new File((String) f.get(jf)); } catch (Exception x) { System.err.println("ZipFile.name trick did not work, using fallback: " + x); } File myself = File.createTempFile("jenkins", ".jar", directory); myself.deleteOnExit(); InputStream is = Main.class.getProtectionDomain().getCodeSource().getLocation().openStream(); try { OutputStream os = new FileOutputStream(myself); try { copyStream(is, os); } finally { os.close(); } } finally { is.close(); } return myself; }