简体   繁体   中英

$CLASSPATH and -cp with Java

  • 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?

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.

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.

In both cases, the reason for the restrictions it to avoid 1 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.

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 (eg, 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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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