繁体   English   中英

$CLASSPATH 和 -cp 与 Java

[英]$CLASSPATH and -cp with Java

  • 在这篇文章中,使用 -jar 选项会忽略所有 -cp 和 $CLASSPATH。
  • 在这篇文章中,使用 -cp 选项也会忽略 $CLASSPATH。

他们有什么好的理由吗?

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

jar 应该是具有自包含库的独立程序。 如果要包含其他类路径,则可能需要执行以下操作

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

BalusC 回答了另一个问题。

在这两种情况下,限制的原因是为了避免1意外或肆意/考虑不周地覆盖有效类路径。

如果您真的希望应用程序可以使用“-jar”启动并通过用户的 $CLASSPATH 环境变量获取类,您应该能够通过让应用程序创建自己的类加载器或使用自定义启动器来实现。 (您甚至可以让您的应用程序在“-jar”参数之后查找“-cp”参数。)

同样,您可以修改第一种情况下的行为。

但是,我认为这样做是个坏主意。 可执行 JAR 文件的要点是将应用程序与用户碰巧启动应用程序的环境的变幻莫测隔离开来。

如果你想用你的应用程序类路径做一些hacky的事情,一个更简单的方法是创建一个包装脚本来组装有效的类路径,然后用“-cp”选项启动应用程序。 您甚至可以从各种 JAR 文件的清单中提取“类路径”并将其合并...


1 - 显然,它不会完全阻止某人更改类路径。 但是停止这将是一个坏主意,如果我们假设用户可以获得本地管理员权限等,那么在技术上可能是不可能的。

环境变量 CLASSPATH 被(并且应该)忽略的原因有几个:

  1. 所有项目的全局 CLASSPATH 完全没有意义。 它不可能对所有项目都相同,并且您不希望将一个庞大的项目重新应用于所有项目。
  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 的工作原理并停止依赖环境变量。

正确与否,我渴望一个-jar-cp标志。 这将足够明显和直接,不会构成安全风险或破坏当前行为。

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

用我的话来说,没有足够理智的理由来解释这种明显的“荒谬”。 Sun 错误数据库中的错误之一,只能推断开发人员没有考虑到可以通过 CLASSPATH 环境变量或 -cp 选项指定类路径的事实。 当问题被发现时,该版本或多或少是公开的,其结果是修复会导致向后兼容性问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM