import java.io.*; import java.net.*; import java.util.*; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; /** * Ant Task for downloading the latest JRE or JDK from Oracle. */ public class Downloader extends Task { static final String COOKIE = "oraclelicense=accept-securebackup-cookie"; private int version; // Java 8 private int update; // Update 131 private int build; // Build 11 // https://gist.github.com/P7h/9741922 // http://stackoverflow.com/q/10268583 private String hash; // d54c1d3a095b4ff2b6607d096fa80163 private boolean jdk; // false if JRE private String flavor; private String path; // target path public Downloader() { } public void setVersion(int version) { this.version = version; } public void setUpdate(int update) { this.update = update; } public void setBuild(int build) { this.build = build; } public void setHash(String hash) { this.hash = hash; } public void setJDK(boolean jdk) { this.jdk = jdk; } public void setFlavor(String flavor) { this.flavor = flavor; } public void setPath(String path) { this.path = path; } public void execute() throws BuildException { if (version == 0) { throw new BuildException("Version (i.e. 7 or 8) must be set"); } if (build == 0) { throw new BuildException("Build number must be set"); } if (flavor == null) { throw new BuildException("You've gotta choose a flavor (macosx-x64.dmg, windows-x64.exe...)"); } if (update >= 121 && hash == null) { throw new BuildException("Starting with 8u121, a hash is required, see https://gist.github.com/P7h/9741922"); } //download(path, jdk, platform, bits, version, update, build); try { download(); } catch (IOException e) { throw new BuildException(e); } } void download() throws IOException { String filename = (jdk ? "jdk" : "jre") + (update == 0 ? String.format("-%d-%s", version, flavor) : String.format("-%du%d-%s", version, update, flavor)); if (path == null) { path = filename; } String url = "http://download.oracle.com/otn-pub/java/jdk/" + (update == 0 ? String.format("%d-b%02d/", version, build) : String.format("%du%d-b%02d/", version, update, build)); // URL format changed starting with 8u121 if (update >= 121) { url += hash + "/"; } // Finally, add the filename to the end url += filename; HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestProperty("Cookie", COOKIE); //printHeaders(conn); //conn.connect(); while (conn.getResponseCode() == 302) { Map<String, List<String>> headers = conn.getHeaderFields(); List<String> location = headers.get("Location"); if (location.size() == 1) { url = location.get(0); System.out.println("Redirecting to " + url); } else { throw new BuildException("Got " + location.size() + " locations."); } List<String> cookies = headers.get("Set-Cookie"); conn = (HttpURLConnection) new URL(url).openConnection(); if (cookies != null) { for (String cookie : cookies) { conn.setRequestProperty("Cookie", cookie); } } conn.setRequestProperty("Cookie", COOKIE); conn.connect(); } if (conn.getResponseCode() == 200) { InputStream input = conn.getInputStream(); BufferedInputStream bis = new BufferedInputStream(input); File outputFile = new File(path); //folder, filename); System.out.format("Downloading %s from %s%n", outputFile.getAbsolutePath(), url); // Write to a temp file so that we don't have an incomplete download // masquerading as a good archive. File tempFile = File.createTempFile("download", "", outputFile.getParentFile()); BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(tempFile)); int c = bis.read(); while (c != -1) { output.write(c); c = bis.read(); } bis.close(); output.flush(); output.close(); if (outputFile.exists()) { if (!outputFile.delete()) { throw new BuildException("Could not delete old download: " + outputFile.getAbsolutePath()); } } if (!tempFile.renameTo(outputFile)) { throw new BuildException(String.format("Could not rename %s to %s", tempFile.getAbsolutePath(), outputFile.getAbsolutePath())); } } else { printHeaders(conn); System.exit(1); } } static void printHeaders(URLConnection conn) { Map<String, List<String>> headers = conn.getHeaderFields(); Set<Map.Entry<String, List<String>>> entrySet = headers.entrySet(); for (Map.Entry<String, List<String>> entry : entrySet) { String headerName = entry.getKey(); System.out.println("Header Name:" + headerName); List<String> headerValues = entry.getValue(); for (String value : headerValues) { System.out.print("Header value:" + value); } System.out.println(); System.out.println(); } } }