简体   繁体   English

javac编译文件和jar,但是java失败

[英]javac compiles files and jars but java fails

I have put the .java files in a folder, eg /opt/program/ and a .jar file in a lib folder inside the main folder, eg /opt/program/lib/jsoup-1.10.3.jar . 我已经将.java文件放在一个文件夹(例如/opt/program/并将一个.jar文件放在主文件夹(例如/opt/program/lib/jsoup-1.10.3.jar的lib文件夹中。 Then I ran these commands 然后我运行这些命令

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

In one of the java files, eg Tester.java , I have used an object defined in jsoup-1.10.3.jar . 在其中一个Java文件(例如Tester.java ,我使用了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 在运行时,涉及到Jsoup.connect时,出现此错误

java.lang.NoClassDefFoundError

UPDATE: 更新:

As suggested, I have to include the jar file in the java command as well. 根据建议,我还必须在Java命令中包含jar文件。 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? 我该如何解决?

You compile your class with the classpath set : 您可以使用classpath设置编译类:

javac -classpath lib/*jar *.java 

but you don't launch the runnable class with the classpath set : 但是您不要使用classpath设置来启动可运行类:

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. 并且在设置类路径文档中未指定扩展名.jar来设置带通配符的类路径。

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. 类路径条目可以包含基本名称通配符,该通配符被认为等同于指定扩展名为.jar或.JAR的目录中所有文件的列表。 For example, the class path entry foo/ specifies all JAR files in the directory named foo. 例如,类路径条目foo /指定目录foo中的所有JAR文件。 A classpath entry consisting simply of * expands to a list of all the jar files in the current directory . 仅由*组成的类路径条目将扩展为当前目录中所有jar文件的列表

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. 要在单个目录foo中匹配类和JAR文件,请使用foo; foo / *或foo / *; foo。 The order chosen determines whether the classes and resources in foo are loaded before JAR files in foo, or vice versa. 选择的顺序确定是否在foo中的JAR文件之前加载foo中的类和资源,反之亦然。

Subdirectories are not searched recursively. 子目录不是递归搜索的。 For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc. 例如,foo / *仅在foo中查找JAR文件,而不在foo / bar,foo / baz等中查找。

This should solve your problem if all your jar are located at the root of the lib folder: 如果您所有的jar都位于lib文件夹的根目录下,这应该可以解决您的问题:

java -classpath .:lib/*  TheFrame  

To compile your class, you should use the same synthax to set the classpath. 要编译您的类,您应该使用相同的synthax来设置类路径。
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错误:

javac: invalid flag: D:\\repo\\commons-lang3\\3.1\\commons-lang3-3.1-sources.jar javac:无效标志: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. 我与java命令的行为完全相同。

You will need to put the library jar in your classpath not only at compiletime but at runtime too as you did above. 您不仅需要在编译时,而且需要在运行时将库jar放在类路径中,就像上面一样。 See http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html for details. 有关详细信息,请参见http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html

java -classpath lib/*jar TheFrame

shoud do the trick. 应该做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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