$CLASSPATH 和 -cp 与 Java

发布于 2024-09-12 21:56:14 字数 331 浏览 7 评论 0原文

  • 在此 帖子 中,使用 -jar 选项忽略所有 -cp 和 $CLASSPATH。
  • 在此帖子中,使用 -cp 选项也会忽略 $CLASSPATH。

他们有什么充分的理由吗?

  • In this post, using -jar option ignores all the -cp and $CLASSPATH.
  • In this post, using -cp option also ignores the $CLASSPATH.

Is there any good reason for them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

九命猫 2024-09-19 21:56:14

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

It's to avoid clashes in the classpath whenever you distribute your application to run on different environments. In most of the cases you'd like your application to be independent from the platform specific configuration. If the $CLASSPATH contains references to classes with (either unawarely or awarely) the same package and classname, it would get precedence in classloading before the classes which you included in your application's classpath. This may lead to unexpected application behaviour or potential security holes.

花伊自在美 2024-09-19 21:56:14

jar 应该是一个具有独立库的独立程序。如果您想包含其他类路径,您可能需要执行类似

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

BalusC 回答其他问题的操作。

jar is supposed to be a standalone program with self-contained libraries. If you want to include other classpaths, you may need to do something like

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

BalusC answered the other question.

海的爱人是光 2024-09-19 21:56:14

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

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

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

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

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


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

In both cases, the reason for the restrictions it to avoid1 accidental or wanton / ill-considered overriding of the effective classpath.

If you really want an application to be launchable using "-jar" and to also pick up classes via the user's $CLASSPATH environment variable, you should be able to do this by having the application create its own classloader, or using a custom launcher. (You could even make your application look for a "-cp" argument after the "-jar" argument.)

Likewise, you could modify the behavior in the first case.

However, I think it would be bad idea to do that. The main point of executable JAR files is to isolate the application from the vagaries of the environment in which the user happens to launch the application.

If you want to do hacky things with your application classpath, a simpler approach is to create a wrapper script that assembles the effective classpath however you want to, then launches the application with a "-cp" option. You could even pull the "Class-path" out of various JAR files' manifests and incorporate that ...


1 - Clearly, it doesn't stop someone changing the classpath entirely. But stopping that would be a bad idea, and probably isn't technically possible if we assume that the user can get local admin privilege, etcetera.

反目相谮 2024-09-19 21:56:14

环境变量 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 的工作原理并停止依赖环境变量。

There are several reasons why the environment variable CLASSPATH is (and should be) ignored:

  1. A global CLASSPATH for all projects makes no sense at all. It can't be the same for all projects, and you don't want one massive one that's reapplied to all projects.
  2. You can't count on it being set, so depending on it is a bad idea. Code that works on one machine suddenly doesn't work when it's moved. How do you communicate the necessary environment settings? Better not to use them.
  3. Java EE app servers all have their own conventions (e.g., all JARs in WEB-INF/lib and all .class files in WEB-INF/classes are automatically in the CLASSPATH for a web app).
  4. Java EE app servers all ignore global CLASSPATH. They don't count on it.
  5. Java IDEs all have their own conventions for setting a project CLASSPATH. Learn them.
  6. All Java IDEs ignore global CLASSPATH. They don't count on it.

I don't have a global CLASSPATH on any machine that I use. It's not necessary. I'd recommend learning how CLASSPATH works and stop relying on environment variables.

破晓 2024-09-19 21:56:14

无论正确与否,我都渴望一个 -jar-cp 标志。这将是显而易见和直接的,不会构成安全风险或破坏当前的行为。

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

Correct or not, I long for a -jar-cp flag. That would be obvious and direct enough to not be a security risk or break current behavior.

With APIs like java.util.ServiceLoader, it is entirely reasonable to wish to add/remove services from the classpath. You shouldn't have to loose that functionality because you used Main-Class in your manifest.

装迷糊 2024-09-19 21:56:14

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

There is no sane enough reason to explain this apparent "absurdity", in my words. From one of the bugs in the Sun bug database, one can only infer that a developer did not account for the fact that the classpath could be specified via the CLASSPATH environment variable, or via the -cp option. By the time the issue was found, the release was more or less public, with the effect that the fix would cause backward compatibility issues.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文