当前位置: 首页 > 知识库问答 >
问题:

NoClassDefFoundError在应用程序中,类路径是正确的(乍一看)。为什么?

蒲昀
2023-03-14

我将app.jar作为java-jar app.jar运行,并看到下一个错误:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/thrift/transport/TTransportException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.apache.thrift.transport.TTransportException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more

app.jar结构:

    .
    ├── lib
    │   ├── ... (some *.jar files)
    │   ├── libthrift-0.9.3.jar
    │   └── ... (some *.jar files)
    ├── META-INF
    │   ├── MANIFEST.MF
    │   └── maven
    │       └── groupId-name
    │           └── artifactId-name
    │               ├── pom.properties
    │               └── pom.xml
    └── ... *.class files of app

META-INF/manifest.mf中,将类路径声明为:

Class-Path: lib/libthrift-0.9.3.jar lib/...(other *.jar's from lib/ folder)

libthrift-0.9.3.jar结构:

    .
    ├── META-INF
    │   ├── LICENSE.txt
    │   ├── MANIFEST.MF
    │   └── NOTICE.txt
    └── org
        └── apache
            └── ... some packages with files
                ├── transport
                │   ├── ... some files
                │   ├── TTransportException.class
                │   └── ...
                └── ...

正如您所看到的,类org.apache.transport.tTransportException存在并且必须在运行时可访问。但不要。为什么这样?

共有1个答案

罗飞宇
2023-03-14

首先:默认情况下,在java中,如果您没有使用任何特殊的工具/框架(如spring-boot),您就不能在JAR中使用JAR。

第二:清单文件中的条目(如class-path:lib/libthrift-0.9.3.jar等)不引用jar内部的jar,而是引用jar附近文件系统中的jar。也就是说,使用java-jar app.jar运行应用程序的文件结构应该是:

./
 /libs --> all 3-d party jars here
 app.jar

如果您想在一个jar中拥有所有内容,其中一个变体是使用所谓的“Uber-jar”--在这种情况下,所有的3-D party类都从它们的jar中提取出来,并与您自己的类一起打包在一个jar中。

例如,对于maven构建,可以使用阴影插件。

 类似资料:
  • 问题内容: persistence.xml看起来像这样: 这是一个Web项目,因此部署单元是一个war文件。我尝试引用的jar文件位于 WEB-INF / lib / 文件夹中, persistence.xml 位于 WEB-INF / classes / META-INF 文件夹中。部署时,它只是告诉我 “警告:无法找到文件(忽略):file:… / .. / lib / app-service

  • 尝试运行spring项目时出现以下错误: 我认为这个错误可能是由于某些依赖项的版本冲突造成的,但我不是很确定。这是我的第一个Spring项目。 这是我更新的pom。xml文件 如果您发现任何错误,请随时指出并解释原因。尽可能多地学习。

  • 我的spring boot微服务有一些问题,我已经能够成功地将我的微服务连接到运行在Google Cloud上的SQL实例,但出于某种原因,当我试图使用简单返回字符串“working”的示例endpoint测试控制器是否工作时,我得到了一个404 not found错误,我也尝试了一个示例空白项目,除了启动和运行Spring Boot所需的依赖项之外,没有其他依赖项,但我仍然面临同样的问题,即我得

  • 我已经通过安装插件准备了我的第一个vaadin应用程序,并创建了vaadin项目。构建成功并部署到wildFly后,尝试使用下面的localhost:port/myapp/和localhost:port//myapp/myuiservlet运行应用程序时也不起作用

  • 问题内容: 对于具有所有带有公共静态方法的实用程序类,正确的方法是什么? 我应该使用最终班还是抽象班? 请提出建议。 例如: 要么 问题答案: 有自己的目的。如果您希望其他类()实现某些类功能,则可以使用abstract。 如果它只是实用程序类,但是您不希望其他类将其子类化,那么我将选择类。如果实用程序类只有方法,则您无法以任何方式覆盖它们,因此将它们也包含在类中也没有区别。

  • 我有个问题。尝试改变版本(就像它在互联网上说的),但没有帮助。我已经读过了,这些答案修正了应用程序的类路径,使它包含一个单一的、兼容的org.springframework.plugin.core.pluginregistry版本,但它也没有帮助。 问题: 更正应用程序的类路径,使其包含Org.SpringFramework.http.Converter.Support.AllEncompassi