0

I have put the .java files in a folder, e.g. /opt/program/ and a .jar file in a lib folder inside the main folder, e.g. /opt/program/lib/jsoup-1.10.3.jar. Then I ran these commands

javac -classpath lib/*jar *.java      # compile is OK
java TheFrame                         # program runs

In one of the java files, e.g. Tester.java, I have used an object defined in jsoup-1.10.3.jar. Something like this

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class Tester  {
   Document doc;
   public Tester()  { }
   public void doConnect(String name) throws Exception
   {
      doc = Jsoup.connect("http://somewhere.com").get();
      ...
   }
}

During the runtime, when it comes to Jsoup.connect, I get this error

java.lang.NoClassDefFoundError

UPDATE:

As suggested, I have to include the jar file in the java command as well. I did that but still get the same error

$ ls lib/
jsoup-1.10.3.jar
$ /opt/jdk1.8.0_131/bin/javac -classpath lib/*.jar *.java
$ /opt/jdk1.8.0_131/bin/java -classpath .:lib/*.jar TheFrame
phase_1
java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: org/jsoup/Jsoup
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at javax.swing.SwingWorker.get(SwingWorker.java:602)
    at TheFrame$10.propertyChange(TheFrame.java:481)
    at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
    ....
Caused by: java.lang.NoClassDefFoundError: org/jsoup/Jsoup
    at Tester.connectForTranscript(Tester.java:24)
    at ExcelFile.analyzeSeq(ExcelFile.java:706)
    at TheFrame$9.doInBackground(TheFrame.java:448)
    ....
Caused by: java.lang.ClassNotFoundException: org.jsoup.Jsoup
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    ....
Caused by: java.lang.NoClassDefFoundError: org/jsoup/Jsoup
    at Tester.doConnect(Tester.java:24)
    ...
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: org.jsoup.Jsoup
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 10 more

How can I fix that?

mahmood
  • 23,197
  • 49
  • 147
  • 242
  • you need to provide classpath when you run as well. The dependent classes are not put in the jar with your own code – Garr Godfrey Jul 18 '17 at 18:17

2 Answers2

2

You compile your class with the classpath set :

javac -classpath lib/*jar *.java 

but you don't launch the runnable class with the classpath set :

java TheFrame

Besides, the . and the extension .jar is not specified in the Setting the class path documentation to set a classpath with a wildcard.

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.

This should solve your problem if all your jar are located at the root of the lib folder:

java -classpath .:lib/*  TheFrame  

To compile your class, you should use the same synthax to set the classpath.
It is surprising that you have no compilation error when you execute :

 javac -classpath lib/*jar *.java 

I have tried :

javac -cp D:\repo\commons-lang3\3.1\*jar MyClass.java

I get a javac error :

javac: invalid flag: D:\repo\commons-lang3\3.1\commons-lang3-3.1-sources.jar

With

javac -cp D:\repo\commons-lang3\3.1\* MyClass.java

the compilation is fine.

I have exactly the same behavior with the java command.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • Actually `TheFrame` have to be placed before `classpath`. – mahmood Jul 18 '17 at 18:20
  • I don't think. The documentation state `java [-options] class [args...]` and `-classpath` is an option and not program args. – davidxxx Jul 18 '17 at 18:21
  • Otherwise it says `Could not find or load main class TheFrame` – mahmood Jul 18 '17 at 18:22
  • The current dir is not in the classpath when you set the classpath arg. Add it. You may try with `.:lib/*jar` for unix or `.;lib/*jar` for windows – davidxxx Jul 18 '17 at 18:24
  • So, `.:` method works fine but still I get the same error! Maybe a silly mistake is taking place. Can you please explain if there is a way to check if the symbols are loaded in the binary file? Please see the updated post for error. – mahmood Jul 18 '17 at 18:41
  • @mahmood The problem is certainly in the classpath. Can you show the command you are executing to run the class ? You miss probably something. – davidxxx Jul 18 '17 at 18:49
  • @mahmood The `.` and the extension `.jar` is not specified in the documentation for using a wildcard. Try without : `$ /opt/jdk1.8.0_131/bin/java -classpath .:lib/* TheFrame` and be sure that the JSoup.jar is at the root of the `lib` folder. – davidxxx Jul 18 '17 at 19:32
  • Thanks. removing `.` from `*.jar` was the solution. – mahmood Jul 18 '17 at 20:05
1

You will need to put the library jar in your classpath not only at compiletime but at runtime too as you did above. See http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html for details.

java -classpath lib/*jar TheFrame

shoud do the trick.

Mandraenke
  • 3,086
  • 1
  • 13
  • 26
  • _Maybe_ since it is jdk-8, I have to put `TheFrame` before `classpath`. – mahmood Jul 18 '17 at 18:23
  • You will need all paths in your classpath. Also "." for the current directory. `java -classpath .:lib/jar1.jar:lib/jar2.jar TheFrame"` - anything after the "TheFrame" should be program options that will be available in `args` from `public static void main(String [] args)` – Mandraenke Jul 18 '17 at 18:47
  • While doing compile and starting your programs on the cli is really good for learning, later on you should look at an IDE like Eclipse / IntelliJ / NetBeans which make your life easier (as they handle your classpath while developing) and some build tool like maven which handle your dependencies and ease building (executeable) jars. – Mandraenke Jul 18 '17 at 18:52