【问题标题】:How to jar only the package folder and the class under it .如何只 jar 包文件夹及其下的类。
【发布时间】:2014-03-20 16:54:11
【问题描述】:

我通过查看网络上的示例创建了一个实用程序类来构建 jar 文件。 当我给出源文件夹和输出 jar 名称时,该类会创建 jar 文件。问题是当我展开 jar 时,我看到了带有 .class 文件的绝对路径,而不仅仅是包含源文件夹。如何只包含源文件夹的内容

例如,在 /tmp/example/package 中,我有 com/example/java/HellWorld.class。

当我将源代码作为 /tmp/example/package 时,jar 包含 /tmp/example/package/com/example/java/HellWorld.class 而不仅仅是 com/example/java/HellWorld.class

这是我的代码

public final class JarUtil {

private static Logger logger = LoggerFactory.getLogger(JarUtil.class);

private JarUtil() {

}

/**
 * @param dirToBeJared
 * @param outputJarFileName
 * @throws FileNotFoundException
 * @throws IOException
 */
public static void createJar(String dirToBeJared, String outputJarFileName) {

    logger.info("into create jar dirToBeJared: " + ", outputJarFileName" + outputJarFileName);

    Manifest manifest = new Manifest();
    manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    JarOutputStream target = null;

    try {

        target = new JarOutputStream(new FileOutputStream(outputJarFileName), manifest);

    } catch (FileNotFoundException e) {
        logger.error("error during create jar:" + e);
    } catch (IOException e) {
        logger.error("error during create jar:" + e);
    }

    try {

        add(new File(dirToBeJared), target);

    } catch (IOException e) {
        logger.error("error during create jar:" + e);
    }

    try {
        target.close();
    } catch (IOException e) {
        logger.error("error during create jar:" + e);
    }
}

private static void add(File source, JarOutputStream target) throws IOException {
    BufferedInputStream in = null;
    try {
        if (source.isDirectory()) {
            String name = source.getPath().replace("\\", "/");
            if (!name.isEmpty()) {
                if (!name.endsWith("/")) {
                    name += "/";
                }

              //  JarEntry entry = new JarEntry("com/athena");
                JarEntry entry = new JarEntry(name);
                entry.setTime(source.lastModified());
                target.putNextEntry(entry);
                target.closeEntry();
            }
            for (File nestedFile : source.listFiles()) {
                add(nestedFile, target);
            }    
            return;
        }

        JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
        entry.setTime(source.lastModified());
        target.putNextEntry(entry);

        try {
            in = new BufferedInputStream(new FileInputStream(source));
        } catch (FileNotFoundException e) {
            logger.error("error during the creating the jar: " + e);
        }

        byte[] buffer = new byte[1024];
        while (true) {
            int count = in.read(buffer);
            if (count == -1) {
                break;
            }    
            target.write(buffer, 0, count);
        }
        target.closeEntry();
    } finally {
        if (in != null) {
            in.close();
        }    
    }
}

public static void main(String[] args) {

    JarUtil.createJar("/tmp/examples/package","HelloWorld.jar");

}

}

【问题讨论】:

  • 你为什么要重新发明轮子?
  • 你需要查看 maven、ant 或 graddle(或...)
  • 我必须以编程方式构建 jar。无论如何,我得到了我想要的我提到的stackoverflow.com/questions/9287527/…

标签: java jar


【解决方案1】:

jar 已经具有您想要实现的功能。只需下载 jdk 并使用它:)

tmp/example/package中显示文件

$ find tmp/example/package/ -type f
tmp/example/package/com/example/java/Hello.class
tmp/example/package/com/example/java/HellWorld.class

用另一个目录中的所有文件创建 jar:

$ jar -cf new1.jar -C tmp/example/package/ .

结果是

$ jar -tf new1.jar 
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/java/
com/example/java/Hello.class
com/example/java/HellWorld.class

使用单个类创建 jar:

$ jar -cf new2.jar -C tmp/example/package com/example/java/HellWorld.class

结果是

$ jar -tf new2.jar 
META-INF/
META-INF/MANIFEST.MF
com/example/java/HellWorld.class

【讨论】:

  • 感谢您的回复。我想以编程方式执行此操作。我应该在我的帖子中提到这一点。
  • 如果您想从 java 中执行此操作,最简单的解决方案似乎是调用 Runtime.getRuntime().exec("jar ...")
【解决方案2】:

另一种解决方案。在类 JarUtil 中添加新的静态字段,或将其作为新参数传递给add 方法

Path startDir = Paths.get("/tmp/example/package").toAbsolutePath();

在方法add:

target.putNextEntry(new ZipEntry(
     startDir.relativize(source.toPath.toAbsolutePath()).
     toString()));

必须从 java 7 开始工作。

【讨论】:

    猜你喜欢
    • 2017-09-29
    • 2014-12-08
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    相关资源
    最近更新 更多