Hi again

There are some typical cases depending on the way your customers are supposed to execute your application and a simple recommendation: try to keep the classpath as short as possible (at some time, the JVM will have to scan all the directories or jar in the classpath to find the classes, so, even if it is quick, it cannot be but quicker if the classpath is shorter) - for e.g. avoid to add to the classpath jar libraries that are not used and directories for "just in case".

Now, your application is supposed to be build around a root directory "myapp" containing the packages. And you might wish to write a .bat (for Windows users) and/or a .sh (for Unix/Linux/OS-X ones) that starts your application. And the entry point of your application is the

1. If your customers have just to click on an icon to start the application, your .bat or .sh might look just like this:
   java -cp . main.Main
or
   java main.Main (as the classpath "." is the default)
as long as the shortcut associated to the icon starts in the directory "myapp" (the root directory of your application).

Of course, there might be things in the .bat that I eluded here, such as:
   @echo off
   set JAVAHOME=C:\Javainst\somedirectorywithjavaexe
   set PATH=%JAVAHOME%\bin;%PATH%
   java main.Main

2. Your customer may need to start the application using a command line (as it is started as a service or by another application and so on). Then your .bat or .sh must include the full path of your application. Something like:
   @echo off
   .... (as above to include "java.exe" in your PATH)
   set MYAPPHOME=C:\somedir\myapp
   java -cp %MYAPPHOME% main.Main

3. Real world application use some .jar libraries written by other persons. In this case, your classpath must include the list of the third party libraries. Something like:
   ....
java -cp %MYAPPHOME%;%MYAPPHOME%\lib\lib1.jar;%MYAPPHOME%\lib2.jar main.Main

4. Real world application may use very many third party libraries. If I use "ps" to display the command line for NetBeans, the whole cannot be seen on a 25x80 characters display. Under Unix/Linux/OS-X you can have huge command lines, but under DOS they used to be limited (to 256 characters previous to Vista I think). So you would prefer to use a CLASSPATH variable:
   ....
   set CLASSPATH=%MYAPPHOME%;%MYAPPHOME%\lib\lib1.jar;%MYAPPHOME%\lib2.jar
   set CLASSPATH=%CLASSPATH%;%MYAPPHOME%\lib\lib3.jar;%MYAPPHOME%\lib4.jar
   ... and so on ...
   java main.Main

If your application is very important for the user of the computer - it is the main reason for which that computer is run (such as the accounting application on the desktop of the bookkeeper of the company), then you may add java.exe in the PATH and define the CLASSPATH environment variable somewhere in the system settings.

5. You would like to deploy your application as a jar file "myapp.jar" plus the libraries in a "lib" directory. Then your command line might look like:
   ....
   java -cp myapp.jar;lib\lib1.jar;lib\lib2.jar main.Main
(or the equivalent using CLASSPATH and/or full directory pathnames).

6. You can record the relative classpath in the manifest file of your jar file. You can also specify there that the entry point is main.Main.

So the files in your current directory might be:
   .
   |- myapp.jar
   |- lib
        |- lib1.jar
        |- lib2.jar
        ...
and lib/lib1.jar, lib/lib2.jar and so on are recorded in the classpath declared in the manifest file of myapp.jar.

Then your customers can execute your application like:
   ....
   java -jar myapp.jar

or simple double-click on myapp.jar (with no .bat or .sh necessary as long as the ".jar" extension is recorded to be used with the Java executable).

This execution style is compatible with the jnlp (WebStart) deployment (automatic deployment of your jar and the associated libraries).

I think the 6 cases resume the typical situations (maybe someone can imagine other cases) - calling them "patterns" would be too much.

Hope it helps
Mihai

PS: You cannot use: "java -cp ...some-classpath... -jar myapp.jar" - it will not work. The "-cp" option or the CLASSPATH environment variable CANNOT OVERRIDE the classpath set in the manifest file. To override it, you must use the case 5 syntax.

ooo.stephen a écrit :
thanks, that helps.
its purpose seems clear, but its utility less so.  is there a best
practice or design pattern regarding -cp you can recommend?


ooo.stephen
===========

On Aug 26, 1:46 pm, Mihai DINCA <[email protected]> wrote:
Hi ooo.stephen

This is a good question, because it worth to understand the "classpath"
philosophy in the beginning, once for all.

In brief, Java CLASSPATH is a list of directories representing the place
where Java looks for the (fully qualified with the package name) .class
files, in about the same way Unix/Linux looks for its programs in $PATH
and Windows in %PATH%. The difference is that Java classes use a package.

A .java file use a "package" statement in the beginning of the code to
specify its package. After compiling, the ".class" file "knows" that it
can be called only by specifying the package. For e.g. "java -cp C:\foo
bar.test" will execute the "main" static method of the file
"C:\foo\bar\test.class".

But "java -cp C:\     foo.bar.test" will not work and "java -cp
C:\foo\bar test" neither because "test.class" "knows" that it should be
called as "bar.test" only (as the file "test.java" contains "package
bar" at the beginning).

Now, where should "java bar.test" look for a subdirectory "bar"
containing a file "test.class"? The answer is in the CLASSPATH.

The CLASSPATH is a list of directories separated by ":" under Unix/Linux
(and OS-X I think) and by ";" under Windows. The Java loader will scan
each of the directories in the CLASSPATH, in sequence, to find the
requested files.

You can set the CLASSPATH by defining an environment variable containing
the list of directories. Such as:
-- Unix/Linux/OS-X
    export CLASSPATH=/usr/tst:/var/lib:/var/tst
    java bar.test

-- Windows
    set CLASSPATH=C:\libs;D:\Users\myself\Documents\tests
    java bar.test

You can override the value of the currently defined CLASSPATH variable
on the command line. Such as:
-- Unix/Linux/OS-X
    export CLASSPATH=/usr/tst:/var/lib:/var/tst
    java -cp /home/myself/tst:/home/myself/lib bar.test

-- Windows
    set CLASSPATH=C:\libs;D:\Users\myself\Documents\tests
    java -cp
D:\Users\myself\Documents\proj;D:\Users\myself\Documents\proj\lib bar.test

(No need to say that "cp" stands for CLASSPATH).

If no CLASSPATH variable is used and no -cp command line option, then
Java use some default classpath (that can be modified too, but that is
another matter) that is usually ".".

The classpath (the variable or the -cp option and so on) may also
contain a .jar file too (or more), allowing to look for the requested
package/file.class in the .jar file(s) too.

Hope it helps
Mihai

ooo.stephen a crit :

my grasp of this is a little shaky.  please correct me if i'm wrong,
but my understanding (and maybe my articulation will help others), is
the following:
1- -cp statement essentially counter acts/accommodates the package
path statement.  this is because the package statement is a directive
to look for .class files in the path stated in the package, starting
in the current dir the file is being executed from.  in order to
compile from the command line, you need to set the -cp path to a dir
that would allow the package path to be true, i.e.:
E:\Programming\Java Passion\basic\10_classpath\homework\foodpackage
\fruitpackage>
java -cp ../../ foodpackage.fruitpackage.FoodMain
2- -cp is not necessary when running the 'java' command with a true
package path. that is, if you run 'java' from two dirs above, the
following is true;
E:\Programming\Java Passion\basic\10_classpath\homework>
java foodpackage.fruitpackage.FoodMain
same as:
E:\Programming\Java Passion\basic\10_classpath\homework>
java -cp . foodpackage.fruitpackage.FoodMain
i'm having a hard time conceptualizing a real world example or need
for dealing with the class path.  because the package statement must
match the dir structure, changing the class path seems undesirable,
and would require recompiling the .class file.
thanks kindly,
ooo.stephen


--
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/javaprogrammingwithpassion?hl=en

Reply via email to