import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.net.URL;import java.nio.ByteBuffer;import java.nio.channels.Channels;import java.nio.channels.ClosedByInterruptException;import java.nio.channels.ReadableByteChannel;import java.nio.channels.WritableByteChannel;import java.util.Date;import org.apache.log4j.Logger;import org.quartz.InterruptableJob;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.JobKey;import org.quartz.UnableToInterruptJobException;public class MyJob implements InterruptableJob { private static Logger LOG = Logger.getLogger(MyJob.class); private volatile boolean isJobInterrupted = false; private JobKey jobKey = null; private volatile Thread thisThread; public MyJob() { } public void execute(JobExecutionContext context) throws JobExecutionException { thisThread = Thread.currentThread();// LOG.info("Thread name of the current job: " + thisThread.getName()); System.out.println("Thread name of the current job: " + thisThread.getName()); jobKey = context.getJobDetail().getKey();// LOG.info("Job " + jobKey + " executing at " + new Date()); System.out.println("Job " + jobKey + " executing at " + new Date()); try { String fileUrl = "http://d2zwv9pap9ylyd.cloudfront.net/terracotta-3.6.1.tar.gz"; // 59 MB String localFile = "d:/terracotta-3.6.1.tar.gz"; download(fileUrl, localFile); } catch (ClosedByInterruptException e) { LOG.info("Caught ClosedByInterruptException... exiting job."); e.printStackTrace(); } catch (IOException e) { LOG.info("Caught IOException... exiting job.", e); e.printStackTrace(); } finally { if (isJobInterrupted) { LOG.info("Job " + jobKey + " did not complete"); System.out.println("Job " + jobKey + " did not complete"); } else { LOG.info("Job " + jobKey + " completed at " + new Date()); System.out.println("Job " + jobKey + " completed at " + new Date()); } } } // this method is called by the scheduler public void interrupt() throws UnableToInterruptJobException { LOG.info("Job " + jobKey + " -- INTERRUPTING --"); System.out.println("Job " + jobKey + " -- INTERRUPTING --"); isJobInterrupted = true; if (thisThread != null) { // this called cause the ClosedByInterruptException to happen thisThread.interrupt(); } } private void download(String address, String localFileName) throws ClosedByInterruptException, IOException { URL url = new URL(address); ReadableByteChannel src = Channels.newChannel(url.openStream()); WritableByteChannel dest = new FileOutputStream(new File(localFileName)).getChannel(); try { System.out.println("Downloading " + address + " to " + new File(localFileName).getCanonicalPath()); int size = fastChannelCopy(src, dest); System.out.println("Download completed! " + (size / 1024 / 1024) + " MB"); } finally { src.close(); dest.close(); } } // Code copied from http://thomaswabner.wordpress.com/2007/10/09/fast-stream-copy-using-javanio-channels/ private static int fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException { final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); int count = 0; int total = 0; while ((count = src.read(buffer)) != -1) { total += count; // prepare the buffer to be drained buffer.flip(); // write to the channel, may block dest.write(buffer); // If partial transfer, shift remainder down // If buffer is empty, same as doing clear() buffer.compact(); } // EOF will leave buffer in fill state buffer.flip(); // make sure the buffer is fully drained. while (buffer.hasRemaining()) { dest.write(buffer); } return total; }}