使用gradle时出现"java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ObjectMapper"错误

4

我正在编写一个简单的测试程序,使用jackson 2将json转换为java对象。

我的代码是:

package test;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URL;

public class UseJson{

    public static void main(String[] args){

        ObjectMapper mapper = new ObjectMapper();
        try{
            SomeClass obj = mapper.readValue(new URL("http://someurl"), SomeClass.class);
        }
        catch(Exception ex){
            System.out.println(ex.toString());
        }
    }
}

而build.gradle文件如下:

repositories {
    mavenCentral()
}

apply plugin: 'java'

dependencies{
    compile('com.fasterxml.jackson.core:jackson-databind:2.8.6')
    compile('com.fasterxml.jackson.core:jackson-core:2.8.6')
    compile('com.fasterxml.jackson.core:jackson-annotations:2.8.6')
}

jar {
        manifest {
                attributes 'Main-Class': 'test.UseJson'
        }
}

但是当我尝试执行程序时,出现了异常。
java -jar ./build/libs/JsonTest.jar
Exception in thread "main" java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ObjectMapper
        at test.UseJson.main(UseJson.java:10)
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.ObjectMapper
        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)
        ... 1 more

相关的帖子java.lang.ClassNotFoundException / NoClassDefFoundError for com/fasterxml/jackson/databind/ObjectMapper with Maven使用Jackson mapper的正确依赖设置并不能解决这个问题。


编辑: 当我尝试使用javac手动编译程序并使用依赖项的jar文件时,它可以工作。问题必须出现在Gradle构建文件中。


嗯,当你运行jar文件时没有在classpath中添加Jackson,所以它在classpath中不可用。你为什么认为它应该存在呢?使用application插件,可以生成一个包含所有依赖项列表的Class-Path清单项的可运行的jar文件,并生成一个包含所需内容(包括启动脚本)的应用程序分发版。 - JB Nizet
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Registered User
应用程序插件更好。Uber-jar 是一种 hack,往往人们开始使用 uber-jar 作为库,并想知道为什么什么都不能正常工作。 - JB Nizet
@JBNizet 好的,谢谢! - Registered User
@InjuredThePatient 看起来我忘记接受答案了。 - Registered User
1个回答

4
你需要将库与应用程序一起打包。
jar {
archiveName = 'Name.jar'

manifest {
    attributes 'Main-Class': 'Main',
            'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' '),
            'Implementation-Version': project.version (if any)
}

from(configurations.compile.collect { it.isDirectory() ? it : zipTree(it) })
}

另一种解决方案是使用Shadow jar插件。

最推荐的解决方案是使用application插件。为什么?它得到支持,它是Gradle,大多数开发人员都在使用它。


唯一让我成功的方法是使用Shadow jar插件... 我想知道如何正确配置应用程序插件... - skryvets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接