Java как в runtime узнать classpath

Обновлено: 02.07.2024

Теперь быстренько разберемся classpath, так как это достаточно важная тема для разработки на Java. Естественно я тут не смогу разобрать все тонкости и хитрости, но постараюсь представить самое необходимое чтобы было понимание этой темы. Для желающих разобраться глубже приведу линки для самостоятельного изучения. Ну и как всегда гугль в помощь.

Чтобы понимать что происходит под капотом у любой Java IDE когда она собирает проект и запускает его надо хоть немного попрактиковаться в использовании компилятора javac, среды исполнения java и понять classpath.

По существу classpath указывает компилятору или виртуальной машине где искать классы необходимые для сборки проекта или же его запуска. Немного об этом мы уже узнали тут. Теперь разберемся с этим получше.

Начнем с простого. Вернемся к нашему проекту Hello World (00004E_HelloWorld), там где мы разделили его на два файла Hello.java и Word.java.

Теперь попробуем создать исполняемый (jar) файл этого проекта из среды Eclipse. Так как скомпилированные, читай готовые к исполнению, файлы в Java имеют расширение class, а классов в реальных программах, могут быть сотни и тысячи, то их собирают в один или несколько jar архивов и таким образом запускают. То есть уже существует не россыпь файлов с расширением class, а один или несколько jar файлов.

И так! Понеслась! Воспользуемся Export для создания jar

CP0001

CP0003

После этого мы получим файл HelloWorld.jar готовый к исполнению на виртуальной машине java. Запустим его из командной строки:

CP0004

CP0005

CP0006

Почему строчка запуска выглядит именно так? Вспоминаем что именно класс Hello.java содержит у нас метод main.

CP0007

Класс Word.java такого метода не имеет.

CP0008

И так в нашей строчке

java -cp HelloWorld.jar Hello

мы указали что искать метод main надо в классе Hello (расширение .class опускается) по пути HelloWorld.jar. Jar и zip архивы рассматриваются виртуальной машиной как каталоги, поэтому их надо указывать по полному имени с расширением.

Теперь скомпилируем наши классы Hello.java и Word.java самостоятельно из командной строки без помощи Eclipse, чтобы еще глубже понять как все работает. Для чистоты эксперимента рекомендую удалить все файлы с расширением .class и .jar из каталога bin.

Для начал просто скомпилируем исходники в class файлы без упаковки их в jar, чтобы было понятнее.

Переходим в коневой каталог 00004E_HelloWorld и от туда даем команду компиляции

javac -encoding utf8 -d bin src\Hello.java src\Word.java

CP0009

Теперь у нас в каталоге bin два файла Hello.class и Word.class. Перейдем в него чтобы запустить программу.

CP0010

Все работает. Но файлики у нас там лежат россыпью классво .class

Теперь упакуем эти файлики .class в jar архив командой

jar cf HelloWorld.jar Hello.class Word.class

и попробуем запустить HelloWorld.jar

CP0012

И вылетела ошибочка. Почему так? Ведь у нас уже есть jar файл в который упакованы оба класса.

CP0013

Но все равно не работает. Это происходит потому, что внутри jar файла мы не указали какой файл у нас имеет метод main.

Запустить наш jar файл все таки можно указав дополнительно, какой класс содержит метод main.

java -cp HelloWorld.jar Hello

CP0014

Теперь все работает. Но согласитесь так запускать jar файл не удобно, так как всегда надо знать какой класс содержит метод main. Если вы смотрели внимательно, то видимо заметили внутри архива HelloWorld.jar папку META-INF. В ней содержится файл MANIFEST.MF

CP0015

Вот в нем и должна содержаться информация о классе содержащем метод main, но пока в нем ее нет.

CP0016

Исправим эту ошибочку. Удалим файлик HelloWorld.jar и создадим его заново, но уже с добавлением информации о классе содержащим метод main. Сделаем это следующей командой

jar cfe HelloWorld.jar Hello Hello.class Word.class

И запустим файл HelloWorld.jar уже как полагается без танцев с бубном.

CP0017

Как видим все работает нормально. Это произошло потому, что файл MANIFEST.MF уже содержит информацию о классе содержащем метод main.

CP0018

Ну вот теперь мы имеем хоть какое-то представление о том что происходит когда какая-либо IDE создает исполняемый jar файл, а так же получили представление о classpath. В следующей статье мы немного углубим его.

P.S. Так же стоит знать что по умолчанию для виртуальной машины java доступны все классы стандартной библиотеки java, а так же все классы в текущем каталоге от куда запускается главный класс содержащий метод main.

Ну и на последок ссылка где про classpath рассказано достаточно подробно. Правда я не знаю как долго она проживет.

C:> sdkTool -classpath classpath1 ; classpath2.

C:> set CLASSPATH= classpath1 ; classpath2.

  • For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file.
  • For .class files in an unnamed package, the class path ends with the directory that contains the .class files.
  • For .class files in a named package, the class path ends with the directory that contains the "root" package (the first package in the full package name).

Multiple path entries are separated by semi-colons. With the set command, it's important to omit spaces from around the equals sign (=).

The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, you must include "." in the new settings.

Classpath entries that are neither directories nor archives (.zip or .jar files) nor * are ignored.

Description

The class path tells JDK tools and applications where to find third-party and user-defined classes -- that is, classes that are not Java extensions or part of the Java platform. The class path needs to find any classes you've compiled with the javac compiler -- its default is the current directory to conveniently enable those classes to be found.

The JDK, the JVM and other JDK tools find classes by searching the Java platform (bootstrap) classes, any extension classes, and the class path, in that order. (For details on the search strategy, see How Classes Are Found.) Class libraries for most applications will want to take advantage of the extensions mechanism. You only need to set the class path when you want to load a class that's (a) not in the current directory or in any of its subdirectories, and (b) not in a location specified by the extensions mechanism.

If you are upgrading from an older version of the JDK, your startup settings may include CLASSPATH settings that are no longer needed. You should remove any settings that are not application-specific, such as classes.zip . Some third-party applications that use the Java Virtual Machine may modify your CLASSPATH environment variable to include the libaries they use. Such settings can remain.

You can change the class path by using the JDK tools' -classpath option when you invoke the JVM or other JDK tools or by using the CLASSPATH environment variable. Using the -classpath option is preferred over setting CLASSPATH environment variable because you can set it individually for each application without affecting other applications and without other applications modifying its value.

Classes can be stored either in directories (folders) or in archive files. The Java platform classes are stored in rt.jar . For more details on archives and information on how the class path works, see Understanding the class path and package names near the end of this document.

Important Note: Some older versions of the JDK sofware included a < jdk-dir >/classes entry in the default class path. That directory exists for use by the JDK software, and should not be used for application classes. Application classes should be placed in a directory outside of the JDK directory hierarcy. That way, installing a new JDK does not force you to reinstall application classes. For compatibility with older versions, applications that use the < jdk-dir >/classes directory as a class library will run in the current version, but there is no guarantee that they will run in future versions.

Using the JDK tools' -classpath option

The JDK tools java, jdb, javac, and javah have a -classpath option which replaces the path or paths specified by the CLASSPATH environment variable while the tool runs. This is the recommended option for changing class path settings, because each application can have the class path it needs without interfering with any other application.

The runtime tool java has a -cp option, as well. This option is an abbreviation for -classpath .

For very special cases, both java and javac have options that let you change the path they use to find their own class libraries. The vast majority of users will never to need to use those options, however.

Using the CLASSPATH environment variable

In general, you will want to use the -classpath command-line option, as explained in the previous section. This section shows you how to set the CLASSPATH environment variable if you want to do that, or clear settings left over from a previous installation.

Setting CLASSPATH

The CLASSPATH environment variable is modified with the set command. The format is:

The paths should begin with the letter specifying the drive, for example, C:\ . That way, the classes will still be found if you happen to switch to a different drive. (If the path entries start with backslash ( \ ) and you are on drive D: , for example, then the classes will be expected on D: , rather than C: .)

Clearing CLASSPATH

If your CLASSPATH environment variable has been set to a value that is not correct, or if your startup file or script is setting an incorrect path, you can unset CLASSPATH by using:

This command unsets CLASSPATH for the current command prompt window only. You should also delete or modify your startup settings to ensure that you have the right CLASSPATH settings in future sessions.

Changing Startup Settings

If the CLASSPATH variable is set at system startup, the place to look for it depends on your operating system:
Operating System Method
Windows 95 and 98 Examine autoexec.bat for the set command.
Other (Windows NT, Windows 2000, . ) The CLASSPATH environment variable can be set using the System utility in the Control Panel.

Understanding class path wildcards

Class path entries can contain the basename wildcard character *, which is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR . For example, the class path entry foo/* specifies all JAR files in the directory named foo . A classpath entry consisting simply of * expands to a list of all the jar files in the current directory.

A class path entry that contains * will not match class files. To match both classes and JAR files in a single directory foo , use either foo;foo/* or foo/*;foo . The order chosen determines whether the classes and resources in foo are loaded before JAR files in foo , or vice versa.

Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo , not in foo/bar , foo/baz , etc.

The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required then the JAR files can be enumerated explicitly in the class path.

Expansion of wildcards is done early, prior to the invocation of a program's main method, rather than late, during the class-loading process itself. Each element of the input class path containing a wildcard is replaced by the (possibly empty) sequence of elements generated by enumerating the JAR files in the named directory. For example, if the directory foo contains a.jar , b.jar , and c.jar , then the class path foo/* is expanded into foo/a.jar;foo/b.jar;foo/c.jar , and that string would be the value of the system property java.class.path .

The CLASSPATH environment variable is not treated any differently from the -classpath (or -cp ) command-line option. That is, wildcards are honored in all these cases. However, class path wildcards are not honored in the Class-Path jar-manifest header.

Understanding the class path and package names

Java classes are organized into packages which are mapped to directories in the file system. But, unlike the file system, whenever you specify a package name, you specify the whole package name -- never part of it. For example, the package name for java.awt.Button is always specified as java.awt .

For example, suppose you want the Java runtime to find a class named Cool.class in the package utility.myapp . If the path to that directory is C:\java\MyClasses\utility\myapp , you would set the class path so that it contains C:\java\MyClasses .

To run that app, you could use the following JVM command:

When the app runs, the JVM uses the class path settings to find any other classes defined in the utility.myapp package that are used by the Cool class.

Note that the entire package name is specified in the command. It is not possible, for example, to set the class path so it contains C:\java\MyClasses\utility and use the command java myapp.Cool . The class would not be found.

(You may be wondering what defines the package name for a class. The answer is that the package name is part of the class and cannot be modified, except by recompiling the class.)

Note: An interesting consequence of the package specification mechanism is that files which are part of the same package may actually exist in different directories. The package name will be the same for each class, but the path to each file may start from a different directory in the class path.

Folders and archive files

When classes are stored in a directory (folder), like c:\java\MyClasses\utility\myapp , then the class path entry points to the directory that contains the first element of the package name. (in this case, C:\java\MyClasses , since the package name is utility.myapp .)

But when classes are stored in an archive file (a .zip or .jar file) the class path entry is the path to and including the .zip or .jar file. For example, to use a class library that is in a .jar file, the command would look something like this:

Multiple specifications

To find class files in the directory C:\java\MyClasses as well as classes in C:\java\OtherClasses , you would set the class path to:

Note that the two paths are separated by a semicolon.

Specification order

The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the example above, the Java interpreter will first look for a needed class in the directory C:\java\MyClasses . Only if it doesn't find a class with the proper name in that directory will the interpreter look in the C:\java\OtherClasses directory.

The class path is the path that the Java Runtime Environment (JRE) searches for classes and other resource files.

This chapter covers the following topics:

Synopsis

The class search path (class path) can be set using either the -classpath option when calling a JDK tool (the preferred method) or by setting the CLASSPATH environment variable. The -classpath option is preferred because you can set it individually for each application without affecting other applications and without other applications modifying its value.

sdkTool -classpath classpath1;classpath2.

set CLASSPATH=classpath1;classpath2.

classpath1:classpath2

Class paths to the JAR, zip or class files. Each class path should end with a file name or directory depending on what you are setting the class path to, as follows:

For a JAR or zip file that contains class files, the class path ends with the name of the zip or JAR file.

For class files in an unnamed package, the class path ends with the directory that contains the class files.

For class files in a named package, the class path ends with the directory that contains the root package, which is the first package in the full package name.

Multiple path entries are separated by semicolons with no spaces around the equals sign (=) in Windows and colons in Oracle Solaris.

The default class path is the current directory. Setting the CLASSPATH variable or using the -classpath command-line option overrides that default, so if you want to include the current directory in the search path, then you must include a dot ( . ) in the new settings.

Class path entries that are neither directories nor archives (.zip or JAR files) nor the asterisk ( * ) wildcard character are ignored.

Description

The class path needs to find any classes you have compiled with the javac compiler. The default is the current directory to conveniently enable those classes to be found.

Class libraries for most applications use the extensions mechanism. You only need to set the class path when you want to load a class that is (a) not in the current directory or in any of its subdirectories, and (b) not in a location specified by the extensions mechanism.

If you upgrade from an earlier release of the JDK, then your startup settings might include CLASSPATH settings that are no longer needed. You should remove any settings that are not application-specific, such as classes.zip . Some third-party applications that use the Java Virtual Machine (JVM) can modify your CLASSPATH environment variable to include the libraries they use. Such settings can remain.

You can change the class path by using the -classpath or -cp option of some Java commands when you call the JVM or other JDK tools or by using the CLASSPATH environment variable. See JDK Commands Class Path Options. Using the -classpath option is preferred over setting the CLASSPATH environment variable because you can set it individually for each application without affecting other applications and without other applications modifying its value. See CLASSPATH Environment Variable.

Classes can be stored in directories (folders) or in archive files. The Java platform classes are stored in rt.jar. For more details about archives and information about how the class path works, see Class Path and Package Names.

Note: Some earlier releases of the JDK had a <jdk-dir>/classes entry in the default class path. That directory exists for use by the JDK software and should not be used for application classes. Application classes should be placed in a directory outside of the JDK directory hierarchy. That way, installing a new JDK does not force you to reinstall application classes. For compatibility with earlier releases, applications that use the <jdk-dir>/classes directory as a class library run in the current release, but there is no guarantee that they will run in future releases.

JDK Commands Class Path Options

The following commands have a -classpath option that replaces the path or paths specified by the CLASSPATH environment variable while the tool runs: java , jdb , javac , javah and jdeps .

The -classpath option is the recommended option for changing class path settings, because each application can have the class path it needs without interfering with any other application.The java command also has a -cp option that is an abbreviation for -classpath .

For very special cases, both the java and javac commands have options that let you change the path they use to find their own class libraries. Most users will never need to use those options.

CLASSPATH Environment Variable

As explained in JDK Commands Class Path Options, the -classpath command-line option is preferred over the CLASSPATH environment variable. However, if you decide to use the CLASSPATH environment variable, this section explains how to set and clear it.

Set CLASSPATH

The CLASSPATH environment variable is modified with the set command. The format is:

The paths should begin with the letter specifying the drive, for example, C:\. That way, the classes will still be found if you happen to switch to a different drive. If the path entries start with backslash (\) and you are on drive D:, for example, then the classes will be expected on D:, rather than C:.

Clear CLASSPATH

If your CLASSPATH environment variable was set to a value that is not correct, or if your startup file or script is setting an incorrect path, then you can unset CLASSPATH with:

This command unsets CLASSPATH for the current command prompt window only. You should also delete or modify your startup settings to ensure that you have the correct CLASSPATH settings in future sessions.

Change Startup Settings

If the CLASSPATH variable is set at system startup, then the place to look for it depends on your operating system:

Windows 95 and 98: Examine autoexec.bat for the set command.

Other (Windows NT, Windows 2000, . ): The CLASSPATH environment variable can be set with the System utility in the Control Panel.

If the CLASSPATH variable is set at system startup, then the place to look for it depends on the shell you are running:

The csh , tcsh shells : Examine your .cshrc file for the setenv command.

The sh , ksh shells : Examine your .profile file for the export command.

Class Path Wild Cards

Class path entries can contain the base name wildcard character (*), which is considered equivalent to specifying a list of all of the files in the directory with the extension .jar or .JAR . For example, the class path entry mydir/* specifies all JAR files in the directory named mydir . A class path entry consisting of * expands to a list of all the jar files in the current directory. Files are considered regardless of whether they are hidden (have names beginning with '.').

A class path entry that contains an asterisk (*) does not match class files. To match both classes and JAR files in a single directory mydir , use either mydir:mydir/* or mydir/*:mydir . The order chosen determines whether the classes and resources in mydir are loaded before JAR files in mydir or vice versa.

Subdirectories are not searched recursively. For example, mydir/* searches for JAR files only in mydir , not in mydir/subdir1 , mydir/subdir2 , and so on.

The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required, then the JAR files can be enumerated explicitly in the class path.

Expansion of wild cards is done early, before the invocation of a program's main method, rather than late, during the class-loading process. Each element of the input class path that contains a wildcard is replaced by the (possibly empty) sequence of elements generated by enumerating the JAR files in the named directory. For example, if the directory mydir contains a.jar, b.jar, and c.jar, then the class path mydir/* is expanded into mydir/a.jar:mydir/b.jar:mydir/c.jar , and that string would be the value of the system property java.class.path.

The CLASSPATH environment variable is not treated any differently from the -classpath or -cp options. Wild cards are honored in all of these cases. However, class path wild cards are not honored in the Class-Path jar-manifest header.

Class Path and Package Names

Java classes are organized into packages that are mapped to directories in the file system. But, unlike the file system, whenever you specify a package name, you specify the whole package name and never part of it. For example, the package name for java.awt.Button is always specified as java.awt .

For example, suppose you want the Java JRE to find a class named Cool.class in the package utility.myapp. If the path to that directory is C:\java\MyClasses\utility\myapp , then you would set the class path so that it contains C:\java\MyClasses . To run that application, you could use the following java command:

The entire package name is specified in the command. It is not possible, for example, to set the class path so it contains C:\java\MyClasses\ utility and use the command java myapp.Cool. The class would not be found.

You might wonder what defines the package name for a class. The answer is that the package name is part of the class and cannot be modified, except by recompiling the class.

An interesting consequence of the package specification mechanism is that files that are part of the same package can exist in different directories. The package name is the same for each class, but the path to each file might start from a different directory in the class path.

Folders and Archive Files

When classes are stored in a directory (folder), such as c:\java\MyClasses\utility\myapp , then the class path entry points to the directory that contains the first element of the package name (in this case, C:\java\MyClasses , because the package name is utility.myapp).

When classes are stored in an archive file (a zi p or JAR file) the class path entry is the path to and including the zip or JAR file. For example, the command to use a class library that is in a JAR file as follows:

Multiple Specifications

To find class files in the directory C:\java\MyClasses and classes in C:\java\OtherClasses , you would set the class path to the following. Note that the two paths are separated by a semicolon.

Specification Order

The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the previous example, the Java interpreter will first look for a needed class in the directory C:\java\MyClasses . Only when it does not find a class with the proper name in that directory will the interpreter look in the C:\java\OtherClasses directory.

This section explains how to use the PATH and CLASSPATH environment variables on Microsoft Windows, Solaris, and Linux. Consult the installation instructions included with your installation of the Java Development Kit (JDK) software bundle for current information.

After installing the software, the JDK directory will have the structure shown below.

The bin directory contains both the compiler and the launcher.

Update the PATH Environment Variable (Microsoft Windows)

You can run Java applications just fine without setting the PATH environment variable. Or, you can optionally set it as a convenience.

Set the PATH environment variable if you want to be able to conveniently run the executables ( javac.exe , java.exe , javadoc.exe , and so on) from any directory without having to type the full path of the command. If you do not set the PATH variable, you need to specify the full path to the executable every time you run it, such as:

The PATH environment variable is a series of directories separated by semicolons ( ; ). Microsoft Windows looks for programs in the PATH directories in order, from left to right. You should have only one bin directory for the JDK in the path at a time (those following the first are ignored), so if one is already present, you can update that particular entry.

The following is an example of a PATH environment variable:

It is useful to set the PATH environment variable permanently so it will persist after rebooting. To make a permanent change to the PATH variable, use the System icon in the Control Panel. The precise procedure varies depending on the version of Windows:

  1. Select Start, select Control Panel. double click System, and select the Advanced tab.
  2. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New .
  3. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
  1. From the desktop, right click the My Computer icon.
  2. Choose Properties from the context menu.
  3. Click the Advanced tab (Advanced system settings link in Vista).
  4. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New .
  5. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
  1. From the desktop, right click the Computer icon.
  2. Choose Properties from the context menu.
  3. Click the Advanced system settings link.
  4. Click Environment Variables. In the section System Variables, find the PATH environment variable and select it. Click Edit. If the PATH environment variable does not exist, click New .
  5. In the Edit System Variable (or New System Variable) window, specify the value of the PATH environment variable. Click OK. Close all remaining windows by clicking OK.
Note: You may see a PATH environment variable similar to the following when editing it from the Control Panel: Variables enclosed in percentage signs ( % ) are existing environment variables. If one of these variables is listed in the Environment Variables window from the Control Panel (such as JAVA_HOME ), then you can edit its value. If it does not appear, then it is a special environment variable that the operating system has defined. For example, SystemRoot is the location of the Microsoft Windows system folder. To obtain the value of a environment variable, enter the following at a command prompt. (This example obtains the value of the SystemRoot environment variable):

Update the PATH Variable (Solaris and Linux)

You can run the JDK just fine without setting the PATH variable, or you can optionally set it as a convenience. However, you should set the path variable if you want to be able to run the executables ( javac , java , javadoc , and so on) from any directory without having to type the full path of the command. If you do not set the PATH variable, you need to specify the full path to the executable every time you run it, such as:

To find out if the path is properly set, execute:

This will print the version of the java tool, if it can find it. If the version is old or you get the error java: Command not found, then the path is not properly set.

To set the path permanently, set the path in your startup file.

For C shell ( csh ), edit the startup file (

For bash , edit the startup file (

For ksh , the startup file is named by the environment variable, ENV . To set the path:

For sh , edit the profile file (

Then load the startup file and verify that the path is set by repeating the java command:

For C shell ( csh ):

For ksh , bash , or sh :

Checking the CLASSPATH variable (All platforms)

The CLASSPATH variable is one way to tell applications, including the JDK tools, where to look for user classes. (Classes that are part of the JRE, JDK platform, and extensions should be defined through other means, such as the bootstrap class path or the extensions directory.)

The preferred way to specify the class path is by using the -cp command line switch. This allows the CLASSPATH to be set individually for each application without affecting other applications. Setting the CLASSPATH can be tricky and should be performed with care.

The default value of the class path is ".", meaning that only the current directory is searched. Specifying either the CLASSPATH variable or the -cp command line switch overrides this value.

To check whether CLASSPATH is set on Microsoft Windows NT/2000/XP, execute the following:

On Solaris or Linux, execute the following:

If CLASSPATH is not set you will get a CLASSPATH: Undefined variable error (Solaris or Linux) or simply %CLASSPATH% (Microsoft Windows NT/2000/XP).

To modify the CLASSPATH , use the same procedure you used for the PATH variable.

Class path wildcards allow you to include an entire directory of .jar files in the class path without explicitly naming them individually. For more information, including an explanation of class path wildcards, and a detailed description on how to clean up the CLASSPATH environment variable, see the Setting the Class Path technical note.

Читайте также: