hive-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ser...@apache.org
Subject [21/61] [abbrv] hive git commit: HIVE-15053: Beeline#addlocaldriver - reduce classpath scanning (Zoltan Haindrich, reviewed by Ashutosh Chauhan)
Date Tue, 10 Oct 2017 00:51:55 GMT
HIVE-15053: Beeline#addlocaldriver - reduce classpath scanning (Zoltan Haindrich, reviewed
by Ashutosh Chauhan)

Signed-off-by: Zoltan Haindrich <kirk@rxd.hu>


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/4cc0771d
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/4cc0771d
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/4cc0771d

Branch: refs/heads/hive-14535
Commit: 4cc0771d180299c917bf2adc60493fba8c9c9efd
Parents: 71004d2
Author: Zoltan Haindrich <kirk@rxd.hu>
Authored: Fri Oct 6 11:11:28 2017 +0200
Committer: Zoltan Haindrich <kirk@rxd.hu>
Committed: Fri Oct 6 11:11:28 2017 +0200

----------------------------------------------------------------------
 .../java/org/apache/hive/beeline/BeeLine.java   | 110 +-------
 .../apache/hive/beeline/ClassNameCompleter.java | 254 -------------------
 .../hive/beeline/TestBeelineArgParsing.java     |  13 +-
 .../hive/beeline/TestClassNameCompleter.java    |  76 ------
 .../apache/hive/common/util/HiveTestUtils.java  |  37 ++-
 5 files changed, 47 insertions(+), 443 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/4cc0771d/beeline/src/java/org/apache/hive/beeline/BeeLine.java
----------------------------------------------------------------------
diff --git a/beeline/src/java/org/apache/hive/beeline/BeeLine.java b/beeline/src/java/org/apache/hive/beeline/BeeLine.java
index f2c346d..649edc0 100644
--- a/beeline/src/java/org/apache/hive/beeline/BeeLine.java
+++ b/beeline/src/java/org/apache/hive/beeline/BeeLine.java
@@ -67,6 +67,7 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.Properties;
 import java.util.ResourceBundle;
+import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.StringTokenizer;
@@ -2111,122 +2112,21 @@ public class BeeLine implements Closeable {
     return scanDrivers(false);
   }
 
-
   Driver[] scanDrivers(boolean knownOnly) throws IOException {
     long start = System.currentTimeMillis();
 
-    Set<String> classNames = new HashSet<String>();
-
-    if (!knownOnly) {
-      classNames.addAll(Arrays.asList(
-          ClassNameCompleter.getClassNames()));
-    }
-
-    classNames.addAll(KNOWN_DRIVERS);
-
-    Set driverClasses = new HashSet();
+    ServiceLoader<Driver> sqlDrivers = ServiceLoader.load(Driver.class);
 
-    for (Iterator<String> i = classNames.iterator(); i.hasNext();) {
-      String className = i.next().toString();
+    Set<Driver> driverClasses = new HashSet<>();
 
-      if (className.toLowerCase().indexOf("driver") == -1) {
-        continue;
-      }
-
-      try {
-        Class c = Class.forName(className, false,
-            Thread.currentThread().getContextClassLoader());
-        if (!Driver.class.isAssignableFrom(c)) {
-          continue;
-        }
-
-        if (Modifier.isAbstract(c.getModifiers())) {
-          continue;
-        }
-
-        // now instantiate and initialize it
-        driverClasses.add(c.newInstance());
-      } catch (Throwable t) {
-      }
+    for (Driver driver : sqlDrivers) {
+        driverClasses.add(driver);
     }
     info("scan complete in "
         + (System.currentTimeMillis() - start) + "ms");
     return (Driver[]) driverClasses.toArray(new Driver[0]);
   }
 
-
-  private Driver[] scanDriversOLD(String line) {
-    long start = System.currentTimeMillis();
-
-    Set<String> paths = new HashSet<String>();
-    Set driverClasses = new HashSet();
-
-    for (StringTokenizer tok = new StringTokenizer(
-        System.getProperty("java.ext.dirs"),
-        System.getProperty("path.separator")); tok.hasMoreTokens();) {
-      File[] files = new File(tok.nextToken()).listFiles();
-      for (int i = 0; files != null && i < files.length; i++) {
-        paths.add(files[i].getAbsolutePath());
-      }
-    }
-
-    for (StringTokenizer tok = new StringTokenizer(
-        System.getProperty("java.class.path"),
-        System.getProperty("path.separator")); tok.hasMoreTokens();) {
-      paths.add(new File(tok.nextToken()).getAbsolutePath());
-    }
-
-    for (Iterator<String> i = paths.iterator(); i.hasNext();) {
-      File f = new File(i.next());
-      output(getColorBuffer().pad(loc("scanning", f.getAbsolutePath()), 60),
-          false);
-
-      try (ZipFile zf = new ZipFile(f)) {
-        int total = zf.size();
-        int index = 0;
-
-        for (Enumeration zfEnum = zf.entries(); zfEnum.hasMoreElements();) {
-          ZipEntry entry = (ZipEntry) zfEnum.nextElement();
-          String name = entry.getName();
-          progress(index++, total);
-
-          if (name.endsWith(".class")) {
-            name = name.replace('/', '.');
-            name = name.substring(0, name.length() - 6);
-
-            try {
-              // check for the string "driver" in the class
-              // to see if we should load it. Not perfect, but
-              // it is far too slow otherwise.
-              if (name.toLowerCase().indexOf("driver") != -1) {
-                Class c = Class.forName(name, false,
-                    getClass().getClassLoader());
-                if (Driver.class.isAssignableFrom(c)
-                    && !(Modifier.isAbstract(
-                        c.getModifiers()))) {
-                  try {
-                    // load and initialize
-                    Class.forName(name);
-                  } catch (Exception e) {
-                  }
-                  driverClasses.add(c.newInstance());
-                }
-              }
-            } catch (Throwable t) {
-            }
-          }
-        }
-        progress(total, total);
-      } catch (Exception e) {
-      }
-    }
-
-    info("scan complete in "
-        + (System.currentTimeMillis() - start) + "ms");
-    return (Driver[]) driverClasses.toArray(new Driver[0]);
-  }
-
-
   // /////////////////////////////////////
   // ResultSet output formatting classes
   // /////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/hive/blob/4cc0771d/beeline/src/java/org/apache/hive/beeline/ClassNameCompleter.java
----------------------------------------------------------------------
diff --git a/beeline/src/java/org/apache/hive/beeline/ClassNameCompleter.java b/beeline/src/java/org/apache/hive/beeline/ClassNameCompleter.java
deleted file mode 100644
index 65ac576..0000000
--- a/beeline/src/java/org/apache/hive/beeline/ClassNameCompleter.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- * Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with
- * the distribution.
- *
- * Neither the name of JLine nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.hive.beeline;
-
-import jline.console.completer.StringsCompleter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.net.URLConnection;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.Enumeration;
-import java.util.TreeSet;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipEntry;
-
-/**
- * the completer is original provided in JLine 0.9.94 and is being removed in 2.12. Add the
- * previous implement for usage of the beeline.
- */
-public class ClassNameCompleter extends StringsCompleter {
-
-  private static final Logger LOG = LoggerFactory.getLogger(ClassNameCompleter.class.getName());
-  public final static String clazzFileNameExtension = ".class";
-  public final static String jarFileNameExtension = ".jar";
-
-  public ClassNameCompleter(String... candidates) {
-    super(candidates);
-  }
-
-  public static String[] getClassNames() throws IOException {
-    Set urls = new HashSet();
-
-    for (ClassLoader loader = Thread.currentThread().getContextClassLoader(); loader != null;
-         loader = loader.getParent()) {
-      if (!(loader instanceof URLClassLoader)) {
-        continue;
-      }
-
-      urls.addAll(Arrays.asList(((URLClassLoader) loader).getURLs()));
-    }
-
-    // Now add the URL that holds java.lang.String. This is because
-    // some JVMs do not report the core classes jar in the list of
-    // class loaders.
-    Class[] systemClasses = new Class[]{String.class, javax.swing.JFrame.class};
-
-    for (int i = 0; i < systemClasses.length; i++) {
-      URL classURL = systemClasses[i]
-              .getResource("/" + systemClasses[i].getName().replace('.', '/') + clazzFileNameExtension);
-
-      if (classURL != null) {
-        URLConnection uc = classURL.openConnection();
-
-        if (uc instanceof JarURLConnection) {
-          urls.add(((JarURLConnection) uc).getJarFileURL());
-        }
-      }
-    }
-
-    Set classes = new HashSet();
-
-    for (Iterator i = urls.iterator(); i.hasNext(); ) {
-      URL url = (URL) i.next();
-      try {
-        File file = new File(url.getFile());
-
-        if (file.isDirectory()) {
-          Set files = getClassFiles(file.getAbsolutePath(), new HashSet(), file, new int[]
{ 200 });
-          classes.addAll(files);
-
-          continue;
-        }
-
-        if (!isJarFile(file)) {
-          continue;
-        }
-
-        JarFile jf = new JarFile(file);
-
-        for (Enumeration e = jf.entries(); e.hasMoreElements();) {
-          JarEntry entry = (JarEntry) e.nextElement();
-
-          if (entry == null) {
-            continue;
-          }
-
-          String name = entry.getName();
-
-          if (isClazzFile(name)) {
-            /* only use class file */
-            classes.add(name);
-          } else if (isJarFile(name)) {
-            classes.addAll(getClassNamesFromJar(name));
-          } else {
-            continue;
-          }
-        }
-      } catch (IOException e) {
-        throw new IOException(String.format("Error reading classpath entry: %s", url), e);
-      }
-    }
-
-    // now filter classes by changing "/" to "." and trimming the
-    // trailing ".class"
-    Set classNames = new TreeSet();
-
-    for (Iterator i = classes.iterator(); i.hasNext(); ) {
-      String name = (String) i.next();
-      classNames.add(name.replace('/', '.').substring(0, name.length() - 6));
-    }
-
-    return (String[]) classNames.toArray(new String[classNames.size()]);
-  }
-
-  private static Set getClassFiles(String root, Set holder, File directory, int[] maxDirectories)
{
-    // we have passed the maximum number of directories to scan
-    if (maxDirectories[0]-- < 0) {
-      return holder;
-    }
-
-    File[] files = directory.listFiles();
-
-    for (int i = 0; (files != null) && (i < files.length); i++) {
-      String name = files[i].getAbsolutePath();
-
-      if (!(name.startsWith(root))) {
-        continue;
-      } else if (files[i].isDirectory()) {
-        getClassFiles(root, holder, files[i], maxDirectories);
-      } else if (files[i].getName().endsWith(clazzFileNameExtension)) {
-        holder.add(files[i].getAbsolutePath().
-                substring(root.length() + 1));
-      }
-    }
-
-    return holder;
-  }
-
-  /**
-   * Get clazz names from a jar file path
-   * @param path specifies the jar file's path
-   * @return
-   */
-  private static List<String> getClassNamesFromJar(String path) {
-    List<String> classNames = new ArrayList<String>();
-    ZipInputStream zip = null;
-    try {
-      zip = new ZipInputStream(new FileInputStream(path));
-      ZipEntry entry = zip.getNextEntry();
-      while (entry != null) {
-        if (!entry.isDirectory() && entry.getName().endsWith(clazzFileNameExtension))
{
-          StringBuilder className = new StringBuilder();
-          for (String part : entry.getName().split("/")) {
-            if (className.length() != 0) {
-              className.append(".");
-            }
-            className.append(part);
-            if (part.endsWith(clazzFileNameExtension)) {
-              className.setLength(className.length() - clazzFileNameExtension.length());
-            }
-          }
-          classNames.add(className.toString());
-        }
-        entry = zip.getNextEntry();
-      }
-    } catch (IOException e) {
-      LOG.error("Fail to parse the class name from the Jar file due to the exception:" +
e);
-    } finally {
-      if (zip != null) {
-        try {
-          zip.close();
-        } catch (IOException e) {
-          LOG.error("Fail to close the file due to the exception:" + e);
-        }
-      }
-    }
-
-    return classNames;
-  }
-
-  private static boolean isJarFile(File file) {
-    return (file != null && file.isFile() && isJarFile(file.getName()));
-  }
-
-  private static boolean isJarFile(String fileName) {
-    return fileName.endsWith(jarFileNameExtension);
-  }
-
-  private static boolean isClazzFile(String clazzName) {
-    return clazzName.endsWith(clazzFileNameExtension);
-  }
-}

http://git-wip-us.apache.org/repos/asf/hive/blob/4cc0771d/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
----------------------------------------------------------------------
diff --git a/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java b/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
index 2884cc8..379dcfd 100644
--- a/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
+++ b/beeline/src/test/org/apache/hive/beeline/TestBeelineArgParsing.java
@@ -22,7 +22,12 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertTrue;
+
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
@@ -92,10 +97,13 @@ public class TestBeelineArgParsing {
     }
   }
 
-  @Parameters public static Collection<Object[]> data() throws IOException, InterruptedException
{
+  @Parameters(name="{1}")
+  public static Collection<Object[]> data() throws IOException, InterruptedException
{
     // generate the dummy driver by using txt file
     String u = HiveTestUtils.getFileFromClasspath("DummyDriver.txt");
-    File jarFile = HiveTestUtils.genLocalJarForTest(u, dummyDriverClazzName);
+    Map<File, String> extraContent=new HashMap<>();
+    extraContent.put(new File("META-INF/services/java.sql.Driver"), dummyDriverClazzName);
+    File jarFile = HiveTestUtils.genLocalJarForTest(u, dummyDriverClazzName, extraContent);
     String pathToDummyDriver = jarFile.getAbsolutePath();
     return Arrays.asList(new Object[][] {
         { "jdbc:postgresql://host:5432/testdb", "org.postgresql.Driver",
@@ -284,6 +292,7 @@ public class TestBeelineArgParsing {
     TestBeeline bl = new TestBeeline();
 
     LOG.info("Add " + driverJarFileName + " for the driver class " + driverClazzName);
+    assertTrue("expected to exists: "+driverJarFileName,new File(driverJarFileName).exists());
     bl.addLocalJar(driverJarFileName);
     if (!defaultSupported) {
       Assert.assertNull(bl.findLocalDriver(connectionString));

http://git-wip-us.apache.org/repos/asf/hive/blob/4cc0771d/beeline/src/test/org/apache/hive/beeline/TestClassNameCompleter.java
----------------------------------------------------------------------
diff --git a/beeline/src/test/org/apache/hive/beeline/TestClassNameCompleter.java b/beeline/src/test/org/apache/hive/beeline/TestClassNameCompleter.java
deleted file mode 100644
index 1999937..0000000
--- a/beeline/src/test/org/apache/hive/beeline/TestClassNameCompleter.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.hive.beeline;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import static org.junit.Assert.*;
-
-public class TestClassNameCompleter {
-
-  @ClassRule
-  public static TemporaryFolder tmpFolder = new TemporaryFolder();
-
-  @Test
-  public void addingAndEmptyJarFile() throws IOException {
-
-    String fileName = "empty.file.jar";
-    File p = tmpFolder.newFile(fileName);
-
-    URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
-    try {
-      URLClassLoader newClassLoader = new URLClassLoader(new URL[] { p.toURL() }, classLoader);
-
-      Thread.currentThread().setContextClassLoader(newClassLoader);
-      ClassNameCompleter.getClassNames();
-      fail("an exception was expected!");
-    } catch (IOException e) {
-      assertTrue("Exception message should contain the filename!",
-          e.getMessage().indexOf(fileName) >= 0);
-    } finally {
-      Thread.currentThread().setContextClassLoader(classLoader);
-    }
-
-  }
-
-  @Test
-  public void addingEmptyFile() throws IOException {
-
-    String fileName = "empty.file";
-    File p = tmpFolder.newFile(fileName);
-
-    URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
-    try {
-      URLClassLoader newClassLoader = new URLClassLoader(new URL[] { p.toURL() }, classLoader);
-
-      Thread.currentThread().setContextClassLoader(newClassLoader);
-      ClassNameCompleter.getClassNames();
-    } finally {
-      Thread.currentThread().setContextClassLoader(classLoader);
-    }
-
-  }
-}

http://git-wip-us.apache.org/repos/asf/hive/blob/4cc0771d/common/src/java/org/apache/hive/common/util/HiveTestUtils.java
----------------------------------------------------------------------
diff --git a/common/src/java/org/apache/hive/common/util/HiveTestUtils.java b/common/src/java/org/apache/hive/common/util/HiveTestUtils.java
index 88b9f81..abb31cf 100644
--- a/common/src/java/org/apache/hive/common/util/HiveTestUtils.java
+++ b/common/src/java/org/apache/hive/common/util/HiveTestUtils.java
@@ -20,17 +20,25 @@ package org.apache.hive.common.util;
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
-import com.google.common.io.Files;
-
+import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.hive.common.classification.InterfaceAudience;
 import org.apache.hadoop.hive.common.classification.InterfaceStability;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.io.Files;
+
 @InterfaceAudience.Private
 @InterfaceStability.Unstable
 public class HiveTestUtils {
@@ -70,16 +78,33 @@ public class HiveTestUtils {
 
   public static File genLocalJarForTest(String pathToClazzFile, String clazzName)
       throws IOException, InterruptedException {
+    return genLocalJarForTest(pathToClazzFile, clazzName, new HashMap<File, String>());
+  }
+
+  public static File genLocalJarForTest(String pathToClazzFile, String clazzName, Map<File,String>extraContent)
+      throws IOException, InterruptedException {
     String u = pathToClazzFile;
     File dir = new File(u);
     File parentDir = dir.getParentFile();
     File f = new File(parentDir, clazzName + JAVA_FILE_EXT);
     Files.copy(dir, f);
     executeCmd(new String[] { "javac", clazzName + JAVA_FILE_EXT }, parentDir);
-    executeCmd(new String[] { "jar", "cf", clazzName + JAR_FILE_EXT, clazzName + CLAZZ_FILE_EXT
},
-        parentDir);
     f.delete();
-    new File(parentDir, clazzName + CLAZZ_FILE_EXT).delete();
-    return new File(parentDir, clazzName + JAR_FILE_EXT);
+
+    File outputJar=new File(parentDir, clazzName + JAR_FILE_EXT);
+    ZipOutputStream zos=new ZipOutputStream(new FileOutputStream(outputJar));
+    String contentClassName = clazzName + CLAZZ_FILE_EXT;
+    zos.putNextEntry(new ZipEntry(contentClassName));
+    IOUtils.copy(new FileInputStream(new File(parentDir,contentClassName)), zos);
+    zos.closeEntry();
+
+    for (Entry<File, String> entry : extraContent.entrySet()) {
+      zos.putNextEntry(new ZipEntry(entry.getKey().toString()));
+      zos.write(entry.getValue().getBytes());
+      zos.closeEntry();
+    }
+    zos.close();
+    new File(parentDir, contentClassName).delete();
+    return outputJar;
   }
 }


Mime
View raw message