代码之家  ›  专栏  ›  技术社区  ›  Pierre

具有Depedences的可执行JAR

  •  1
  • Pierre  · 技术社区  · 15 年前

    我正在尝试从命令行构建一个可执行JAR(我不想使用Ant或OneJAR)。以下是我的file.jar的内容:

    jar tvf file.jar
         0 Mon Sep 20 17:16:12 CEST 2010 lib/
     45396 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.logging_1.0.4.v201005080501.jar
    321330 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar
     55003 Mon Sep 20 17:16:12 CEST 2010 lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar
         0 Mon Sep 20 19:15:00 CEST 2010 META-INF/
       265 Mon Sep 20 19:12:44 CEST 2010 META-INF/MANIFEST.MF
    530609 Mon Sep 20 17:16:12 CEST 2010 ped.jar
    

    META-INF/manifest.mf的内容:

    Manifest-Version: 1.0
    Class-Path: ped.jar lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar lib/org.apache.commons.logging_1.0.4.v201005080501.jar
    Main-Class: fr.inserm.umr915.bomcat.ped.PedigreeDrawer
    

    ped.jar do包含主类

    jar tvf ped.jar | grep PedigreeDrawer.class
     39541 Mon Sep 20 17:16:10 CEST 2010 fr/inserm/umr915/bomcat/ped/PedigreeDrawer.class
    

    但是当我试图执行file.jar时,我得到了一个错误:

    java -jar file.jar
    Exception in thread "main" java.lang.NoClassDefFoundError: fr/inserm/umr915/bomcat/ped/PedigreeDrawer
    Caused by: java.lang.ClassNotFoundException: fr.inserm.umr915.bomcat.ped.PedigreeDrawer
            at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    

    所以,我错过了一些东西。我不能通过只包含依赖项来打包可执行JAR吗?

    谢谢你的帮助

    彼埃尔

    5 回复  |  直到 15 年前
        1
  •  1
  •   Peter Tillemans    15 年前

    如前所述 Class-Path: 属性是相对于JAR文件的LoAction的,而不是在JAR文件中。这可能是爪哇打算运行applet的时代遗留下来的。

    您需要使用类似MavenUberjar的工具在一个jar中将所有需要的类组合在一起,以创建一个独立的可执行jar。

    当然,如果您绝对想避免使用工具,您也可以将所有jar解压到一个目录中,添加META-INF和清单,然后再次对所有jar进行压缩。

        2
  •  1
  •   secmask    15 年前

    是什么 罐子 ?
    您可以尝试如下设置类路径:

    Class-Path: lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar lib/org.apache.commons.httpclient_3.1.0.v201005080502.jar lib/org.apache.commons.logging_1.0.4.v201005080501.jar
    

    像这样运行JAR文件:

    java -jar ped.jar
    
        3
  •  1
  •   James Van Huis    15 年前

    如果没有特殊包装(如Onejar等),则不能将罐子放在罐子内。

    如果您真的不想使用Onejar(或其他类似的工具),您将需要在您的可分发文件中包含多个jar文件。

        4
  •  1
  •   tangens    15 年前

    文件中的“类路径”值 manifest.mf 指定类路径,就像启动应用程序时不使用 -jar 但与 -classpath lib/... 参数。路径是在本地解释的,而不是在JAR文件中。

    另一种选择是使用 one-jar 或者使用一个特殊的类加载器来查找外部JAR文件中包含的JAR文件。

    JCL 您可以直接从嵌入式jar加载类,如下所示:

      JarClassLoader jcl=new JarClassLoader();
      jcl.add("myjar.jar"); // Add some class source
    
      jcl.getSystemLoader().setOrder(1); // Look in system class loader first
      jcl.getLocalLoader().setOrder(2); // if not found look in local class loader
      jcl.getParentLoader().setOrder(3); // if not found look in parent class loader
      jcl.getThreadLoader().setOrder(4); // if not found look in thread context class loader
      jcl.getCurrentLoader().setOrder(5); // if not found look in current class loader
    
      // A custom class loader that extends org.xeustechnologies.jcl.ProxyClassLoader
      MyLoader loader=new MyLoader();
      loader.setOrder(6);
    
      jcl.addLoader(loader); //Add custom loader
    

    但是你必须把JCL添加到你的类路径中…或者在你的罐子里添加一个分解的JCL。

        5
  •  0
  •   Jayan    15 年前

    Onejar是用来解决这类问题的。您可以编写一个自定义类加载器来达到同样的效果。