简体   繁体   English

Java:NoClassDefFoundError:org / json / JSONException

[英]Java: NoClassDefFoundError: org/json/JSONException

So, I've spent the whole day with this problem. 因此,我整天都在解决这个问题。
I'm sure, that I'm using correct classpath. 我确定我使用的是正确的类路径。
Also, I have other packages as dependences, and they work perfectly. 另外,我还有其他软件包作为依赖项,它们可以完美地工作。

I have a class that uses org.json.* 我有一个使用org.json。*的类
Also there are some other outer packages used in this class. 另外,此类中还使用了其他一些外部软件包。
All this dependences are placed as jar files in my /path/to/libs/. 所有这些依赖关系都作为jar文件放在我的/ path / to / libs /中。
json-20160212.jar is among them. json-20160212.jar就在其中。

I'm compiling my sources with 我正在用

javac \
    -cp "src/:/path/to/libs/json-20160212.jar:/path/to/libs/other.jar:/path/to/libs/another.jar" \
    -d dst/ \
    src/com/example/Source.java

Compilation goes without issues. 编译没有问题。
Then, I'm creating jar from my class-files. 然后,我从类文件创建jar。
Manifest: 表现:

Main-Class: com.example.Source
Class-Path: /path/to/libs/json-20160212.jar
  /path/to/libs/other.jar
  /path/to/libs/another.jar

Command line: 命令行:
jar cfm output.jar manifest -C dst/ ./com

I'm getting jar with this manifest: 我得到这个清单的罐子:

Manifest-Version: 1.0
Class-Path: /path/to/libs/json-20160212.jar /path/to/libs/other.jar /p
 ath/to/libs/another.jar
Created-By: 1.7.0_101 (Oracle Corporation)
Main-Class: com.example.Source

As I've understood, this is ok for compiled manifest to have splitted lines. 据我了解,这对于已编译的清单具有分割行是可以的。

Now, I'm running my app from command line and get this error: 现在,我从命令行运行我的应用程序,并收到此错误:

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/json/JSONException
    at com.example.Source.run(Source.java:30)
Caused by: java.lang.ClassNotFoundException: org.json.JSONException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
    ... 1 more

As I know, that means, that org.json.JSONException was ok at compile time but missing at run time. 据我所知,这意味着org.json.JSONException在编译时可以,但在运行时会丢失。
But what must I do with this info? 但是我该怎么办?
I have that file. 我有那个文件。 It was at its place during compilation and at runtime. 它在编译期间和运行时都在它的位置。
Also there are other dependences, and their jars are also at that place. 另外还有其他依赖项,它们的罐子也在该位置。

If I remove JSON usage from my app, everything is working ok. 如果我从应用程序中删除JSON使用情况,则一切正常。
So, I can make conclusion, that it is the package org.json itself, that makes the problem. 因此,我可以得出结论,正是软件包org.json本身导致了问题。

What must I do, to make it work? 我必须怎么做才能使其正常工作?

UPDATE UPDATE

Now, I've made this changes: 现在,我进行了以下更改:

My directory structure: 我的目录结构:

libs/
    json-20160212.jar
    other.jar
    another.jar
src/
    com/
        example/
            Source.java
dst/

Manifest: 表现:

Main-Class: com.example.Source
Class-Path: libs/json-20160212.jar
  libs/other.jar
  libs/another.jar

Compilation: 汇编:

javac \
    -cp "src/:libs/json-20160212.jar:libs/other.jar:libs/another.jar" \
    -d dst/ \
    src/com/example/Source.java

Jarchiving: Jarchiving:

jar cfm dst/output.jar manifest -C dst/ ./com ./libs

I'm getting jar with the structure as excepted: 我正在使用结构除外的罐子:

META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/Source.class
libs/
libs/json-20160212.jar
libs/other.jar
libs/another.jar

And I'm running it with java -jar dst/output.jar . 我正在使用java -jar dst/output.jar运行它。
Result is the same: java.lang.NoClassDefFoundError: org/json/JSONException 结果是相同的: java.lang.NoClassDefFoundError: org/json/JSONException

The problem is your runtime classpath. 问题是您的运行时类路径。 There's no magic with this error. 这个错误是没有魔术的。 It quite simply means that org.json.JSONException is not on your runtime classpath. 这很简单地意味着org.json.JSONException不在您的运行时类路径上。 Find the jar that has this class in it and put it on your runtime classpath. 找到其中包含此类的jar,并将其放在您的运行时类路径中。

Note that the jars / classes needed for runtime are not necessarily the same as those needed for compiling. 请注意,运行时所需的jar /类不一定与编译所需的jar /类相同。 You quite often need more on your runtime classpath than your compile classpath. 在运行时类路径上比在编译类路径上经常需要更多的东西。 If JSONException isn't used explicitly in the code you are compiling, then it won't have to be on your compile classpath. 如果在要编译的代码中未明确使用JSONException,则不必在编译类路径中。 However, if one of the dependencies to your code needs JSONException and it's not on your runtime classpath, you will get a NoClassDefFoundError. 但是,如果代码的依赖项之一需要JSONException,并且不在运行时类路径中,则将出现NoClassDefFoundError。

One other issue that can possibly occur is that you have 2 different versions of the json jar on your classpath. 可能发生的另一个问题是,您的类路径上有2个不同版本的json jar。 Usually the first version of the class on the classpath gets loaded and the other ignored. 通常,类路径上的类的第一个版本会被加载,而另一个版本会被忽略。 If the first jar didn't have the version / signature of JSONException you needed in it but the second did, the correct class you would still get ignored, since it was further down on the classpath. 如果第一个jar没有所需的JSONException版本/签名,但第二个jar具有,则您仍将忽略正确的类,因为它在类路径中。

The issue would appear to be that you are not adding the dependent jars to your resultant jar. 问题似乎是您没有将依赖的jar添加到生成的jar中。

I have created a similar test jar, with the following structure (checking using jar tf)... 我创建了一个类似的测试jar,其结构如下(使用jar tf检查)...

META-INF/ META-INF /
META-INF/MANIFEST.MF META-INF / MANIFEST.MF
BeanIt.class BeanIt.class
TestBean.class TestBean.class
lib/ LIB /
lib/opencsv-3.7.jar LIB / opencsv-3.7.jar
lib/commons-lang3-3.4.jar LIB /公地lang3-3.4.jar

My manifest... 我的清单...

Main-Class: BeanIt 主类:BeanIt
Class-Path: lib/opencsv-3.7.jar lib/commons-lang3-3.4.jar 类路径:lib / opencsv-3.7.jar lib / commons-lang3-3.4.jar

In order to create this jar, you need to perform a command something similar to this... 为了创建这个罐子,您需要执行类似于此命令...

jar cfm App.jar MANIFEST.MF BeanIt.class TestBean.class lib

You can see that I've added my lib folder to the jar and referred to its contents on the classpath in the manifest. 您可以看到我已将我的lib文件夹添加到jar中,并在清单的类路径中引用了它的内容。

So, you can update your existing lib, like this... 因此,您可以像这样更新您现有的库...

jar uf App.jar path

Where path is the root path of your path/to/lib directory. 其中path是path / to / lib目录的根路径。 And it will simply add that to your jar. 它将简单地将其添加到您的jar中。

You can check your jar first using jar tf , to see what it contains. 您可以先使用jar tf检查jar,以查看其包含的内容。

If you are still having difficulties getting it to work, then you can look at a "FAT JAR" solution whereby you expand all the internal jars classes and flatten them all out to a single JAR containing all the necessary classes. 如果仍然难以使它正常工作,那么可以看一下“ FAT JAR”解决方案,其中您可以扩展所有内部jars类并将它们全部展平为包含所有必需类的单个JAR。 They use decision mechanisms to deal with class conflicts in different JARs. 他们使用决策机制来处理不同JAR中的类冲突。 Tools such as sbt-assembly or OneJar may be what you need here, if you are unable to get your JAR working the way you expect. 如果无法使JAR正常工作,则可能需要sbt-assemblyOneJar之类的工具。

So, the solution: 因此,解决方案:

As I've understand, the only way to access the content of the jar files that are inside your jar, is to write your own class loader. 据我了解,访问jar内jar文件内容的唯一方法是编写自己的类加载器。
Without it, jar files must be extracted and that extracted content must be included to output.jar. 没有它,必须提取jar文件,并且提取的内容必须包含在output.jar中。

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

相关问题 Intellij Java:java.lang.NoClassDefFoundError:org/json/JSONException - Intellij Java: java.lang.NoClassDefFoundError: org/json/JSONException JApplet java.lang.NoClassDefFoundError:org / json / JSONException - JApplet java.lang.NoClassDefFoundError: org/json/JSONException 泽西岛500错误NoClassDefFoundError:org / json / JSONException - Jersey 500 Error NoClassDefFoundError: org/json/JSONException 处女座服务器抛出java.lang.NoClassDefFoundError:org / json / JSONException部署Java包时出错 - Virgo Server Throwing java.lang.NoClassDefFoundError: org/json/JSONException Error while deploying a Java package 运行 java 类时,Tomcat 服务器不会在 Eclipse 中启动。 引起:java.lang.NoClassDefFoundError:org/json/JSONException - Tomcat server won't start in Eclipse when running java class. Caused by: java.lang.NoClassDefFoundError: org/json/JSONException org.json.JSONException: JSONArray[0] 不是 JSONObject - Java - org.json.JSONException: JSONArray[0] is not a JSONObject - Java Java应用程序中的org.JSON.JSONException - org.JSON.JSONException in Java Application java.lang.ClassNotFoundException:org.codehaus.jettison.json.JSONException - java.lang.ClassNotFoundException: org.codehaus.jettison.json.JSONException 解析数据时出错org.json.JSONException - Java - Error parsing data org.json.JSONException - Java org.json.JSONException:{…}没有值 - org.json.JSONException: No value for {…}
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM