This week's book giveaways are in the Jython/Python and Object-Oriented programming forums.
We're giving away four copies each of Machine Learning for Business: Using Amazon SageMaker and Jupyter and Object Design Style Guide and have the authors on-line!
See this thread and this one for details.
Win a copy of Machine Learning for Business: Using Amazon SageMaker and JupyterE this week in the Jython/Python forum
or Object Design Style Guide in the Object-Oriented programming forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Paul Clapham
  • Jeanne Boyarsky
  • Knute Snortum
Sheriffs:
  • Liutauras Vilda
  • Tim Cooke
  • Junilu Lacar
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Joe Ess
  • salvin francis
  • fred rosenberger

Run Java Program using -cp with External Libraries

 
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm on Windows and I have a java class file called WebCrawler.class. I also have a jar file called commons-validator-1.6.jar, and WebCrawler uses functionality from that jar file. WebCrawler is part of a package called cloud.simplecrawl.

The following files are inside of .\cloud\simplecrawl:

WebCrawler.java
WebCrawler.class
commons-validator-1.6.jar

I navigate to that folder.

I compile with:


Compilation happens just fine, and creates WebCrawler.class.

Then, I want to run that program, WebCrawler.class, but I can't figure out the exact syntax for the java call, and I feel like I've tried everything. I know it should be some form of:


But I can't figure it out! Please help!
 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Figured it out! Don't know how to delete the thread.
 
Saloon Keeper
Posts: 2943
373
Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rather than thinking about deleting the thread, why not share what you found to help others?
 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can do!

So here's what I needed to do:

1) In the folder that I was in, I had to have 2 things. One was commons-validator-1.6.jar. The other was the entire package of which WebCrawler.java was a part. In my case, the package was cloud\simplecrawl\WebCrawler.

2) To compile, I had to use the following command: javac -cp commons-validator-1.6.jar cloud\simplecrawl\WebCrawler.java

3) Then, to run it, I had to use this command: java -cp .\;commons-validator-1.6.jar cloud.simplecrawl.WebCrawler

I think what's happening is that the "-cp" option is telling the java command where to look for all the things that it needs in order to run properly. If it needs to look in multiple places, you separate those places with a semicolon. In my case, I needed it to look for, I think, THE ENTIRE PACKAGE OF cloud.simplecrawl.WebCrawler and THEN ALSO commons-validator-1.6.jar. And so, giving it ".\" is saying to search in the current working directory for that stuff, and the non-package things (the validator) are right here, so here's the name of it.

I hope if I'm wrong someone can correct me!
 
Ranch Foreman
Posts: 76
9
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right! I was just posting on a related thread here. I think it might interest you, as it touches on the usage of the -cp option. Note that your current working directory is on the classpath by default, so you may not need the -cp option if your sources are all there.
 
Jj Roberts
Ranch Foreman
Posts: 76
9
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just a little trick I found interesting: using an asterisk '*' will specify all of the jars in a directory.
From the documentation for the java command:

As a special convenience, a class path element that contains a base name of an asterisk (*) is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. A Java program can’t tell the difference between the two invocations. For example, if the directory mydir contains a.jar and b.JAR, then the class path element mydir/* is expanded to A.jar:b.JAR, except that the order of JAR files is unspecified. All .jar files in the specified directory, even hidden ones, are included in the list. A class path entry consisting of an asterisk (*) expands to a list of all the jar files in the current directory. The CLASSPATH environment variable, where defined, is similarly expanded. Any class path wildcard expansion occurs before the Java VM is started. Java programs never see wildcards that aren’t expanded except by querying the environment, such as by calling System.getenv("CLASSPATH").

 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jj Roberts wrote:Note that your current working directory is on the classpath by default, so you may not need the -cp option if your sources are all there.



So, the interesting thing is that this is what I thought was the case, as well, but it seems not to be. If I try to use


it doesn't work, giving me the error "Could not find or load main class cloud.simplecrawl.WebCrawler."

However, if I do


then it works. So it seems I DO need to specify the current working directory. I'm not sure if this is required ONLY because of the package, or if it's required because of the .jar too.
 
Marshal
Posts: 24950
61
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Garbanz Wilkens wrote:So it seems I DO need to specify the current working directory. I'm not sure if this is required ONLY because of the package, or if it's required because of the .jar too.



Neither of those things. You need to specify the current working directory as part of the class path because it contains classes which are going to be used in the execution of the command. That's what the class path is for, after all. It just tells the java command where it can look to load classes. Trying to invent other rules about why it's needed is unnecessary and harmful.
 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Garbanz Wilkens wrote:So it seems I DO need to specify the current working directory. I'm not sure if this is required ONLY because of the package, or if it's required because of the .jar too.



Neither of those things. You need to specify the current working directory as part of the class path because it contains classes which are going to be used in the execution of the command. That's what the class path is for, after all. It just tells the java command where it can look to load classes. Trying to invent other rules about why it's needed is unnecessary and harmful.



So you mean, the classpath is saying "look in these places for the classes required/used by the file I'm about to execute" and, in my case, that means it needs to find the .jar file and the WebCrawler.class file. The .jar file is located in... the jar file, and the class file is located starting in the current working directory. Is that correct?
 
Paul Clapham
Marshal
Posts: 24950
61
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Garbanz Wilkens wrote:So you mean, the classpath is saying "look in these places for the classes required/used by the file I'm about to execute" and, in my case, that means it needs to find the .jar file and the WebCrawler.class file. The .jar file is located in... the jar file, and the class file is located starting in the current working directory. Is that correct?



Pretty much, yes. The classpath is a list of directories and jar files. When the Java runtime needs to load a class, it will look in those directories and those jar files for that class. In case it's not already clear, you have to name all of the jar files you plan to use in the classpath. Just having a jar file in a directory which is in the classpath isn't enough -- you specifically have to include the jar file in the classpath.
 
Jj Roberts
Ranch Foreman
Posts: 76
9
Firefox Browser MySQL Database Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul is right. I said may because I didn't know if jars are loaded automatically if they are in a directory on the classpath. I was testing that out now. Jars are not loaded with the classes in a directory, they have to be added to the classpath explicitly. If you use the -cp option or set the classpath, then the classpath is no longer set to the default, which is the current directory. Since the classpath is no longer set to the current directory, you have to explicitly add it.

java command docs: section on the -cp option
Specifying classpath overrides any setting of the CLASSPATH environment variable. If the class path option isn’t used and classpath isn’t set, then the user class path consists of the current directory (.)

 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, what confuses me is that last part about the default directory for the classpath, and this is why I didn't realize that when I used the -cp option, I needed to specify the current working directory. To me, it seems strange that the java command doesn't assume that it should look for packages/classes in the current working directory.
 
Saloon Keeper
Posts: 11188
244
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It makes quite a bit of sense if you think about it a bit: If you use the -cp switch to specify a directory where classes are located (or the -sourcepath switch to specify a directory where source files are located), chances are very high that you'll no longer want packages to be resolved against the current working directory. After all, these switches are mostly used for projects that use a more sophisticated directory layout that having all your source files and compiled classes mixed together in packages that are rooted directly in the project directory.

For instance, if I have a project directory MyProject that contains src, lib and bin directories, I will use MyProject as the current working directory and compile and run the application like this:

It would be tedious to switch to my src directory before compiling, and then to the bin directory before running the application, so I stay in the MyProject directory. It would be presumptuous of the compiler and JVM to also automatically add the current working directory on the classpath, because my main project directory isn't actually a root package for classes, and treating it like it is may be harmful.

If the developer REALLY intended to have the current working directory on the classpath while using the -cp switch to override the default, it's little effort to explicitly add it.
 
Garbanz Wilkens
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right, that makes a lot of sense!
 
Paul Clapham
Marshal
Posts: 24950
61
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Garbanz Wilkens wrote:To me, it seems strange that the java command doesn't assume that it should look for packages/classes in the current working directory.



Or to put it differently: Java doesn't force you to have the current working directory in your classpath.
 
To get a wish, you need a genie. To get a genie, you need a lamp. To get a lamp, you need a tiny ad:
Sauce Labs - World's Largest Continuous Testing Cloud for Websites and Mobile Apps
https://coderanch.com/t/722574/Sauce-Labs-World-Largest-Continuous
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!