如何只包装包文件夹和它下面的类。

时间:2014-03-19 05:59:14

标签: java jar

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

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

当我将source作为/ 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");

}

}

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

Path startDir = Paths.get("/tmp/example/package").toAbsolutePath();
方法add中的

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

自java 7以来必须正常工作。