运行 outer jar 并且这应该执行 inner jar

Run outer jar and this should execute inner jar

我在 'outer.jar' 文件中有一个主要的 class。在这个 jar 中,classes/lib 文件夹中还有另一个名为 'inner.jar' 的 jar。当我使用命令 java -jar outer.jar?

运行 外罐时,如何制作内罐 运行

我的主要 class 是 运行 另一个名为 'inner.jar' 的 jar 并使用输出。现在我的应用程序也被打包为一个名为 'outer.jar' 的 jar,当我 运行 这个 'outer.jar' 时,主 class 无法 运行 [=30] =]

外罐主要class代码:

public class OuterJarMain{
    public static void main(String[] args) {

            String path = OuterJarMain.class.getProtectionDomain().getCodeSource().getLocation().getPath();
            ProcessBuilder pb = new ProcessBuilder("java", "-jar", path.substring(1)+"lib/inner.jar", "1");
            try {
                Process p = pb.start();

            } catch (IOException e) {
                e.printStackTrace();
            }

当主要 class 从 IDE 执行时,代码工作正常,因为 inner.jar 在 target/classes/lib 文件夹中可用。但是当我从命令行 运行 outer.jar 时,路径显示为 /C:/....../outer.jar!/.../classes!/ 并且 inner.jar 未执行

由于jar里面的文件是存档的,不能像普通文件一样访问它们。

你可以做的是将 jar 中的条目复制到一个文件夹中,如 this post 中所示,然后使用 java -jar 执行 jar,之后如果你不需要jar 你可以调用 File.deleteOnExit()

编辑: 我修改了 post 中的代码,示例如下所示。 方法returns 导出的内部 jar 的绝对位置。

public static String exportInnerJar(){
    String jarDir = ""; 
    try {
        //Get the parent directory of the outer jar.
        jarDir = URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(),"UTF-8");
    } catch (UnsupportedEncodingException e) {
        System.err.println("Fail to find the outer jar location");
        e.printStackTrace();
    }
    //The location of the inner jar
    //The example means the innar jar is at outer.jar/example/inner.jar where "example" is a folder under the root of the outer jar.
    InputStream is = ClassName.class.getResourceAsStream("/example/inner.jar");

    //The location to be exported to, you can change this to wherever you want
    File exportInnerJar = new File(jarDir).toPath().resolve("inner.jar").toFile();

    //Create the file
    exportInnerJar.createNewFile();

    //Use FileOutputStream to write to file
    FileOutputStream fos = new FileOutputStream(exportInnerJar);

    //setup a buffer
    int readBytes;
    byte[] buffer = new byte[4096];

    //export
    while ((readBytes = is.read(buffer)) > 0) {
        fos.write(buffer, 0, readBytes);
    }

    // close streams
    is.close();
    fos.close();

    return exportInnerJar.getAbsolutePath();
}