JarBuilder.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:7k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.streaming;
  19. import java.io.*;
  20. import java.util.*;
  21. import java.util.jar.*;
  22. import java.util.zip.ZipException;
  23. /**
  24.  * This class is the main class for generating job.jar
  25.  * for Hadoop Streaming jobs. It includes the files specified 
  26.  * with the -file option and includes them in the jar. Also,
  27.  * hadoop-streaming is a user level appplication, so all the classes
  28.  * with hadoop-streaming that are needed in the job are also included
  29.  * in the job.jar.
  30.  */
  31. public class JarBuilder {
  32.   public JarBuilder() {
  33.   }
  34.   public void setVerbose(boolean v) {
  35.     this.verbose = v;
  36.   }
  37.   public void merge(List srcNames, List srcUnjar, String dstJar) throws IOException {
  38.     String source = null;
  39.     JarOutputStream jarOut = null;
  40.     JarFile jarSource = null;
  41.     jarOut = new JarOutputStream(new FileOutputStream(dstJar));
  42.     boolean throwing = false;
  43.     try {
  44.       if (srcNames != null) {
  45.         Iterator iter = srcNames.iterator();
  46.         while (iter.hasNext()) {
  47.           source = (String) iter.next();
  48.           File fsource = new File(source);
  49.           String base = getBasePathInJarOut(source);
  50.           if (!fsource.exists()) {
  51.             throwing = true;
  52.             throw new FileNotFoundException(fsource.getAbsolutePath());
  53.           }
  54.           if (fsource.isDirectory()) {
  55.             addDirectory(jarOut, base, fsource, 0);
  56.           } else {
  57.             addFileStream(jarOut, base, fsource);
  58.           }
  59.         }
  60.       }
  61.       if (srcUnjar != null) {
  62.         Iterator iter = srcUnjar.iterator();
  63.         while (iter.hasNext()) {
  64.           source = (String) iter.next();
  65.           jarSource = new JarFile(source);
  66.           addJarEntries(jarOut, jarSource);
  67.           jarSource.close();
  68.         }
  69.       }
  70.     } finally {
  71.       try {
  72.         jarOut.close();
  73.       } catch (ZipException z) {
  74.         if (!throwing) {
  75.           throw new IOException(z.toString());
  76.         }
  77.       }
  78.     }
  79.   }
  80.   protected String fileExtension(String file) {
  81.     int leafPos = file.lastIndexOf('/');
  82.     if (leafPos == file.length() - 1) return "";
  83.     String leafName = file.substring(leafPos + 1);
  84.     int dotPos = leafName.lastIndexOf('.');
  85.     if (dotPos == -1) return "";
  86.     String ext = leafName.substring(dotPos + 1);
  87.     return ext;
  88.   }
  89.   /** @return empty or a jar base path. Must not start with '/' */
  90.   protected String getBasePathInJarOut(String sourceFile) {
  91.     // TaskRunner will unjar and append to classpath: .:classes/:lib/*    
  92.     String ext = fileExtension(sourceFile);
  93.     if (ext.equals("class")) {
  94.       return "classes/"; // or ""
  95.     } else if (ext.equals("jar") || ext.equals("zip")) {
  96.       return "lib/";
  97.     } else {
  98.       return "";
  99.     }
  100.   }
  101.   private void addJarEntries(JarOutputStream dst, JarFile src) throws IOException {
  102.     Enumeration entries = src.entries();
  103.     JarEntry entry = null;
  104.     while (entries.hasMoreElements()) {
  105.       entry = (JarEntry) entries.nextElement();
  106.       //if (entry.getName().startsWith("META-INF/")) continue; 
  107.       InputStream in = src.getInputStream(entry);
  108.       addNamedStream(dst, entry.getName(), in);
  109.     }
  110.   }
  111.   /** @param name path in jar for this jar element. Must not start with '/' */
  112.   void addNamedStream(JarOutputStream dst, String name, InputStream in) throws IOException {
  113.     if (verbose) {
  114.       System.err.println("JarBuilder.addNamedStream " + name);
  115.     }
  116.     try {
  117.       dst.putNextEntry(new JarEntry(name));
  118.       int bytesRead = 0;
  119.       while ((bytesRead = in.read(buffer, 0, BUFF_SIZE)) != -1) {
  120.         dst.write(buffer, 0, bytesRead);
  121.       }
  122.     } catch (ZipException ze) {
  123.       if (ze.getMessage().indexOf("duplicate entry") >= 0) {
  124.         if (verbose) {
  125.           System.err.println(ze + " Skip duplicate entry " + name);
  126.         }
  127.       } else {
  128.         throw ze;
  129.       }
  130.     } finally {
  131.       in.close();
  132.       dst.flush();
  133.       dst.closeEntry();
  134.     }
  135.   }
  136.   void addFileStream(JarOutputStream dst, String jarBaseName, File file) throws IOException {
  137.     FileInputStream in = new FileInputStream(file);
  138.     String name = jarBaseName + file.getName();
  139.     addNamedStream(dst, name, in);
  140.     in.close();
  141.   }
  142.   void addDirectory(JarOutputStream dst, String jarBaseName, File dir, int depth) throws IOException {
  143.     File[] contents = dir.listFiles();
  144.     if (contents != null) {
  145.       for (int i = 0; i < contents.length; i++) {
  146.         File f = contents[i];
  147.         String fBaseName = (depth == 0) ? "" : dir.getName();
  148.         if (jarBaseName.length() > 0) {
  149.           fBaseName = jarBaseName + "/" + fBaseName;
  150.         }
  151.         if (f.isDirectory()) {
  152.           addDirectory(dst, fBaseName, f, depth + 1);
  153.         } else {
  154.           addFileStream(dst, fBaseName + "/", f);
  155.         }
  156.       }
  157.     }
  158.   }
  159.   /** Test program */
  160.   public static void main(String args[]) {
  161.     // args = new String[] { "C:/Temp/merged.jar", "C:/jdk1.5.0/jre/lib/ext/dnsns.jar",  "/Temp/addtojar2.log", "C:/jdk1.5.0/jre/lib/ext/mtest.jar", "C:/Temp/base"};
  162.     if (args.length < 2) {
  163.       System.err.println("Usage: JarFiles merged.jar [src.jar | dir | file ]+");
  164.     } else {
  165.       JarBuilder jarFiles = new JarBuilder();
  166.       List names = new ArrayList();
  167.       List unjar = new ArrayList();
  168.       for (int i = 1; i < args.length; i++) {
  169.         String f = args[i];
  170.         String ext = jarFiles.fileExtension(f);
  171.         boolean expandAsJar = ext.equals("jar") || ext.equals("zip");
  172.         if (expandAsJar) {
  173.           unjar.add(f);
  174.         } else {
  175.           names.add(f);
  176.         }
  177.       }
  178.       try {
  179.         jarFiles.merge(names, unjar, args[0]);
  180.         Date lastMod = new Date(new File(args[0]).lastModified());
  181.         System.out.println("Merge done to " + args[0] + " " + lastMod);
  182.       } catch (Exception ge) {
  183.         ge.printStackTrace(System.err);
  184.       }
  185.     }
  186.   }
  187.   private static final int BUFF_SIZE = 32 * 1024;
  188.   private byte buffer[] = new byte[BUFF_SIZE];
  189.   protected boolean verbose = false;
  190. }