【问题标题】:Java, create runnable jar file including ONLY used dependencies.Java,创建可运行的 jar 文件,包括仅使用的依赖项。
【发布时间】:2014-10-18 03:15:25
【问题描述】:

这个问题以前有人问过,但还没有满意的答案!

我在一个充满其他不相关类的项目中有一个 Java Main.java 类。我想将该 Main.java 导出到一个可执行的 jar 文件中,其中仅包含它实际使用的依赖项。

这可能吗,如果可以,怎么办?

Eclipse(create runnable jar)和 Intellij(create artifact)都将包含在包含 Main.java 类的模块中定义的所有依赖项。

【问题讨论】:

  • 如果您使用的是动态实例化,我认为如果不先解决停机问题,就不可能确定依赖树。
  • 为什么在 Java 构建路径中有您不使用的依赖项?到目前为止,您得到了哪些答案?
  • 只需将所需的依赖项添加到构建路径即可。要么在 mainfest 中手动指定它们
  • @nitind 因为它非常方便。我不需要创建一个新项目并为我创建的每个静态 void main 引入各种依赖项,对吗?这样做会很疯狂。

标签: java eclipse intellij-idea


【解决方案1】:

您应该真正使用依赖管理系统,而不是 Eclipse 和 IDEA 中默认提供的那些。许多 Java 开发人员(包括我)使用Maven。如果您在 Eclipse 中工作,它包括 m2eclipse

您不希望在一个项目中拥有所有依赖项,因为它会变得非常臃肿。但是,如果您有一个使用 <dependencyManagement> 标记的 Maven 父级 pom,您可以轻松地引用此父级 pom,然后轻松地仅引用该子项目中所需的依赖项。这使实际上是独立的一切都分开,并提供了一种简单的组织机制——人们使用 Maven 的原因。

How to use <dependencyManagement> in Maven

Maven 还有一些插件可以为你管理你的 jar 创建,例如maven-assembly-plugin 允许您在 jar 中完全按照您想要的方式构建依赖项等等。


您必须以某种方式自己执行此操作。您希望任何 IDE/依赖管理系统对以下代码做什么:

Test.java

public class Test {
     public static void main(String... args) {
         System.exit(0);
         new Foo(null);
     }
}

Foo.java

import com.google.common.base.Preconditions;

public class Foo {
    public Foo(String s) {
        Preconditions.checkNotNull(s);
    }
}

这里不需要 Guava 依赖...但你只知道在 RUNTIME 中。如果包含所有类的所有 import 语句,则包含所有依赖项。如果不这样做,那么您需要进行运行时分析。您的问题类似于Turing halting problem

【讨论】:

  • 是的,还不够好。我将提取 jar 并手动删除所有依赖项。 (不敢相信 Java 没有比这更进一步)
  • @SecretService 这比让配置文件做你想做的更好吗?
  • 你说:“你不想在一个项目中拥有所有的依赖......”这正是我想要的。我没有兴趣为我创建的每个静态 void main 创建一个 maven 模块。我只想提取我使用的类。
  • @SecretService 您的代码如何知道您使用了哪些类? Maven 使这项任务变得更容易和更快,但不是完全自动化的,因为这几乎是不可能的。
  • 这是一个愚蠢的例子,因为无论需要导入什么类都应该被拉入,否则它不会编译。我不是在谈论运行时分析,而是纯粹的静态分析,可以在编译时检测到的东西。
猜你喜欢
  • 2012-06-20
  • 1970-01-01
  • 2012-02-02
  • 2011-04-12
  • 1970-01-01
  • 2014-09-06
  • 2019-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多