Java 以编程方式将一个jar文件复制到另一个jar文件中

Java 以编程方式将一个jar文件复制到另一个jar文件中,java,jar,Java,Jar,我想用下面的代码在文件夹中复制一个jar文件 public static void copyJarFile(JarFile jarFile, File destDir) throws IOException { String fileName = jarFile.getName(); String fileNameLastPart = fileName.substring(fileName.lastIndexOf(File.separator));

我想用下面的代码在文件夹中复制一个jar文件

   public static void copyJarFile(JarFile jarFile, File destDir) throws IOException {
       String fileName = jarFile.getName();
       String fileNameLastPart = fileName.substring(fileName.lastIndexOf(File.separator));
       File destFile = new File(destDir, fileNameLastPart);

       JarOutputStream jos = new JarOutputStream(new FileOutputStream(destFile));
       Enumeration<JarEntry> entries = jarFile.entries();

       while (entries.hasMoreElements()) {
           JarEntry entry = entries.nextElement();
           InputStream is = jarFile.getInputStream(entry);

           //jos.putNextEntry(entry);
           //create a new entry to avoid ZipException: invalid entry compressed size
           jos.putNextEntry(new JarEntry(entry.getName()));
           byte[] buffer = new byte[4096];
           int bytesRead = 0;
           while ((bytesRead = is.read(buffer)) != -1) {
               jos.write(buffer, 0, bytesRead);
           }
           is.close();
           jos.flush();
           jos.closeEntry();
       }
       jos.close();
   }
publicstaticvoidcopyjarfile(JarFile-JarFile,File-destDir)抛出IOException{
字符串fileName=jarFile.getName();
字符串fileNameLastPart=fileName.substring(fileName.lastIndexOf(File.separator));
File destFile=新文件(destDir,fileNameLastPart);
JarOutputStream jos=new-JarOutputStream(new-FileOutputStream(destFile));
枚举条目=jarFile.entries();
while(entries.hasMoreElements()){
JarEntry=entries.nextElement();
InputStream=jarFile.getInputStream(条目);
//何塞·普特内森特里(条目);
//创建新条目以避免ZipException:无效条目压缩大小
jos.putNextEntry(新的JarEntry(entry.getName());
字节[]缓冲区=新字节[4096];
int字节读取=0;
而((bytesRead=is.read(buffer))!=-1){
jos.write(缓冲区,0,字节读取);
}
is.close();
jos.flush();
jos.closeEntry();
}
jos.close();
}

该程序运行良好。但是当目标不是目录而是jar文件时,该程序就不能工作。我想把一个jar文件复制到另一个jar文件中。如何以编程方式实现它?

Jar文件只是一个具有特定文件结构和.Jar扩展名的奇特命名zip文件。因此,如果您能够使用它将所有内容转储到一个文件夹中,并且该文件夹具有您正在查找的确切结构,那么您可以将该目录压缩为一个zip文件,然后将该zip文件重命名为
whatever.jar
,而不是当您说
我想将一个jar文件复制到另一个jar文件时,将其重命名为
whatever.zip

,你到底是什么意思

假设您的原始jar名为
a.jar
,您希望创建
b.jar
。您的意思是希望
a.jar
中的所有项目都像原来一样位于
b.jar
中吗?还是希望
b.jar
包含名为
a.jar
的条目,该条目是
a.jar
的完整副本

如果您只是希望
b.jar
包含
a.jar
中的所有项目,那么您当前的代码应该可以工作,尽管有更有效的方法可以做到这一点。如果这就是你的意思,我建议直接复制文件

如果您想将整个
a.jar
添加到
b.jar
中作为一个条目,而不是在
a.jar
中循环条目,您只需从
a.jar
创建一个
FileInputStream
并从中读取即可

InputStream is = new FileInputStream("a.jar");

jos.putNextEntry(new JarEntry("a.jar"));
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
    jos.write(buffer, 0, bytesRead);
}

为什么要麻烦地打开jar文件并分别复制每个条目,而不是复制文件本身?另外,您使用哪个版本的Java?我使用的是jdk1.7。好的,你能告诉我如何将整个jar文件复制到另一个jar文件中,而不是显式地复制每个条目吗?如果是,在某个子目录下?您的代码没有做到这一点,即使说“.jar扩展名”也是误导;所谓的“extesion”只是文件名的一部分,不管所有DEs都让您相信什么。我可以将zip文件称为“我是一个zip”或“我告诉你我是text.txt”。据我所知,如果你的类路径中有一个.zip,JVM不会将它添加到你的类路径中,但它会添加一个.jar。因此,是的,扩展是文件不可分割的一部分,因为如果没有扩展,它将永远不会被注意到(至少在我所知道的任何JVM或JEE容器实现中)!这将删除目标jar文件的所有以前的数据,并在其中插入一个新的jar文件。我还想保留该数据。也就是说,将源jar复制到目标jar的过程不应影响目标的先前文件。请再次帮助我,Java的内置Jar API不允许修改现有的Jar文件,这意味着您必须创建一个新的Jar文件,复制所有现有条目(就像您在原始帖子中所做的那样),然后在关闭
JarOutputStream
之前添加新的Jar(就像我的回答中那样)。好的。我正在创建一个名为Pooler的实用程序,它将以jar文件的形式添加客户端提供的新算法。我的应用程序名为Pooler.jar。根据你的回答,当在我的Pooler.jar项目中添加一个新算法时,我必须再次创建一个新的jar,并将所有以前的条目复制到新的jar中,然后再次将新算法复制到我的新jar文件中,并删除包含旧算法的jar的以前版本?好的,我应该创建一个单独的文件夹,该文件夹应位于我应该在Pooler.jar中复制客户端提供的jar文件。然而,根据您对应用程序的描述,我认为它不会做您认为会做的事情。在重新启动运行应用程序的JVM之前,类加载器将无法访问
Pooler.jar
中jar中的类。您可能希望对类加载器进行一些研究,并重新设计应用程序的这一方面。