2010-08-03 70 views
4
  • 在此post中,使用-jar选项会忽略所有的-cp和$ CLASSPATH。
  • 在此post中,使用-cp选项也会忽略$ CLASSPATH。

他们有什么好的理由吗?

回答

7

每当您将应用程序分发到不同的环境中运行时,就可以避免类路径中发生冲突。在大多数情况下,您希望应用程序独立于平台特定的配置。如果$CLASSPATH包含对具有(不知道或意识到)相同的包和类名的类的引用,它将在包含在应用程序的类路径中的类之前的类加载中优先。这可能会导致意外的应用程序行为或潜在的安全漏洞。

4

jar应该是一个独立的程序,包含自包含的库。如果你想包括其他类路径,你可能需要做一些像

java -cp jar1:jar2:$CLASSPATH some.class.with.main 

BalusC回答其他问题。

0

用我的话来说,没有足够的理由来解释这种明显的“荒谬”。从one of the bugs in the Sun bug database开始,只能推断开发人员没有考虑到可以通过CLASSPATH环境变量或通过-cp选项指定类路径的事实。发现问题时,发布或多或少是公开的,其效果是修复会导致向后兼容性问题。

+1

您正试图重写历史记录。对这个错误报告的更全面的解读是:1)这是一个故意设计的决定,有很好的理由,2)回顾起来,理由仍然有效。改变'-jar'语义的事实会破坏很多事情,这只是另一个不会改变的原因......不是主要原因。主要原因是Sun/Oracle认为当前的行为是正确的。 (FWIW,我同意) – 2010-08-03 23:19:45

+0

嗯,我不是。规范是不完整的,因为它从来没有解决通过环境继承的用户类路径,所以它从来没有故意好。回想起来,这可能听起来不错,但正如分析中的一个评论所指出的那样,修复是微不足道的。 – 2010-08-03 23:23:50

+0

我不知道*你从哪里得到的。该规范明确指出/使用“-jar”时忽略$ CLASSPATH。该错误报告甚至引用了在线文档中的说明,以便说明这一点。 – 2010-08-04 00:00:12

1

有几个原因,环境变量CLASSPATH是(也应该)忽略:

  1. 全局类路径为所有项目是没有意义的。它对于所有项目来说都不一样,而且你不希望为所有项目重新应用一个庞大的项目。
  2. 你不能指望它被设置,所以根据它是一个坏主意。移动时,在一台机器上运行的代码突然不起作用。你如何沟通必要的环境设置?最好不要使用它们。
  3. Java EE应用程序服务器都有自己的约定(例如,WEB-INF/lib中的所有JAR和WEB-INF/classes中的所有.class文件都自动位于Web应用程序的CLASSPATH中)。
  4. Java EE应用程序服务器都忽略全局CLASSPATH。他们不相信它。
  5. Java IDE都有自己的约定来设置项目CLASSPATH。学习它们。
  6. 所有Java IDE都忽略全局CLASSPATH。他们不相信它。

我没有使用任何机器上的全局CLASSPATH。这不是必需的。我建议学习CLASSPATH的工作方式,并停止依赖环境变量。

+0

我运行了一个应用程序,该应用程序拥有自己的类路径,在jar中进行了硬编码。它调用我的另一个jython应用程序。我想为jython提供额外的类。为什么选择我的jython类的位置的主要Java应用程序是不好的?其次,我不明白如何证明CLASSPATH是完全废话可以解释,当没有使用-cp选项时,它是可以的。 – Val 2013-10-12 16:36:33

1

如果您确实想要使用“-jar”启动应用程序并通过用户的$ CLASSPATH环境变量获取类,则应该可以通过让应用程序创建自己的类加载器来完成此操作。 (你甚至可以让你的应用程序在“-jar”参数后寻找“-cp”参数)。可执行JAR文件的主要目的是将应用程序与用户碰巧启动应用程序的环境的变幻莫测分开。

如果你想用你的应用程序类路径做黑客事情,更简单的方法是创建一个包装脚本,然后根据需要组装有效的类路径,然后用“-cp”选项启动应用程序。你甚至可以从各种JAR文件的清单中拉出“类路径”,并将其合并到一起...

1

正确与否,我长期为-jar-cp标志。这将是明显而直接的,不会成为安全风险或打破目前的行为。

使用像java.util.ServiceLoader这样的API,希望从类路径添加/删除服务是完全合理的。您不应该因为在清单中使用Main-Class而失去该功能。