jakarta.xml.bind.ContextFinder.handleClassCastException上的java.lang.NullPointerException [英] java.lang.NullPointerException at jakarta.xml.bind.ContextFinder.handleClassCastException

查看:46
本文介绍了jakarta.xml.bind.ContextFinder.handleClassCastException上的java.lang.NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对构建Rest API应用程序非常陌生.在这里,我试图使一个简单的方法返回模型对象Message

I am very new to building rest API application. Here I was trying to make a simple method return a response xml of a model object Message

这是我的web.xml

Here is my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.rest.messenger.service</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>
</web-app>

我有一个服务类,该服务类返回一个Message对象的硬编码列表.

I have a service class that returns a hard-coded list of Message objects.

package com.rest.messenger.service;

import java.util.ArrayList;
import java.util.List;

import com.rest.messenger.model.Message;

public class MessageService {


    public List<Message> getAllMessages(){

        Message m1 = new Message(1L, "message1", "mt");
        Message m2 = new Message( 2L, "message 2", "pt");
        List<Message> messages = new ArrayList<Message>();
        messages.add(m1);
        messages.add(m2);
        return messages;

    }
}

Message对象的定义如下(在这里,我使用了@XmlRootElement批注,让jaxb将其转换为xml,因为我希望由资源返回xml响应):

The Message object is defined as follows ( here I used @XmlRootElement annotation to let jaxb convert this into xml, as I wanted an xml response to be returned by resource):

package com.rest.messenger.model;

import java.util.Date;

import jakarta.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Message {

    private long id;
    private String message;
    private String author;
    private Date created;

    public Message() {

    }
    public Message(long id, String message, String author) {
        super();
        this.id = id;
        this.message = message;
        this.author = author;
        this.created = new Date();
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public Date getCreated() {
        return created;
    }
    public void setCreated(Date created) {
        this.created = created;
    }
}

我将传入的GET请求映射到资源,如下所示:

I mapped the incoming GET request to a resource as follows:

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/messages")
public class MessageResource {

    public MessageService messageService = new MessageService();
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public List<Message> getMessages() {

        return messageService.getAllMessages();
    }

}

现在,当我运行此命令并尝试访问URL http://localhost:8080/messenger.service/webapi/messages

Now when I run this and try to access the resource at URL http://localhost:8080/messenger.service/webapi/messages

我收到以下内部服务器错误:

I get the following internal server error:

May 06, 2020 1:28:14 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Jersey Web Application] in context with path [/messenger.service] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at jakarta.xml.bind.ContextFinder.handleClassCastException(ContextFinder.java:114)
    at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:254)
    at jakarta.xml.bind.ContextFinder.newInstance(ContextFinder.java:240)
    at jakarta.xml.bind.ContextFinder.find(ContextFinder.java:375)
    at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
    at jakarta.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
    at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getStoredJaxbContext(AbstractJaxbProvider.java:288)
    at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getJAXBContext(AbstractJaxbProvider.java:273)
    at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:240)
    at org.glassfish.jersey.jaxb.internal.AbstractJaxbProvider.getMarshaller(AbstractJaxbProvider.java:207)
    at org.glassfish.jersey.jaxb.internal.AbstractCollectionJaxbProvider.writeTo(AbstractCollectionJaxbProvider.java:243)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:242)

我遵循的教程使用javax,我相信它现在已迁移到jakarta. 不确定是否与@XmlRootElement有关 我还根据建议在pom.xml中添加了依赖项: 尝试返回XML时,球衣返回500

The tutorial that I followed used javax and I believe it is now migrated to jakarta. Not sure if it has to do with @XmlRootElement I also added dependencies in pom.xml as suggested on: jersey return 500 when trying return an XML

我建议,我将模型对象的字段的修饰符设置为私有.(使用jaxb的默认XML访问器类型可以在私有字段上工作)

I used the modifiers for fields of model object to be private, as was suggested.( the default XML accessor type used jaxb is able to work on private fields)

有人可以提出建议吗?

推荐答案

经过无数次尝试解决此问题后,我得到了解决方案:

After numerous attempts on resolving this, I got the solution:

因此,基本上,一次有多个用于JAXB的API副本.我的应用程序将Jakarta API作为球衣依赖项的一部分(Jakarta现在是Java EE的标准API),但直到JDK 8为止,JAXB还是classpath中Java扩展API的一部分(javax支持).我在使用jakarta api导入JAXB批注和类,但是也在使用jdk 8进行编译,因此引起了问题.开始使用jersey时,我正在使用Jersey 3.0.0的pom依赖关系实现REST API(这仍然是太新了",不能视为稳定版本)

So basically, there were more than one copies of APIs for JAXB at once. My application had Jakarta API as part of jersey dependency ( Jakarta is now standard API for Java EE) but again till JDK 8, JAXB was also part of Java extended APIs in classpath ( javax support). I was using jakarta api for imports of JAXB annotations and classes, but also was using jdk 8 for compilation, thus causing the issue. Coming to use of jersey, I was implementing the REST API using pom dependency of Jersey 3.0.0 ( which is still "too new" to be considered a stable release)

如果您要坚持使用JDK 8,则解决方案可能是将Javax用于所有的api和导入-并降级pom中的球衣版本(我使用的是2.3.1)[或使用外部JAR版本,如果您使用不是Maven)

Resolution could be the use of javax for all the api and imports if you are going to stick with JDK 8 - and downgrading jersey version in pom (I used 2.3.1) [ or the external JAR version if you are not on maven)

请注意,更高版本的球衣-3.0.0仅与jakarta API捆绑在一起,在这种情况下,您将把导入从javax转移到jakarta.

Note that a higher jersey version - 3.0.0 comes bundled with jakarta APIs only and you will have shift your imports from javax to jakarta in such cases.

第二个选项是,如果您打算将JDK版本升级到1.8以上,您应该得到一个NoClassDefFoundError,但是如果您仍在使用不大于10的JDK版本,则可以解决该问题.是Java EE的API,并且默认情况下classpath不包含它们.有一种启用它们的方法: 如何解决java.lang.NoClassDefFoundError :Java 9中的javax/xml/bind/JAXBException

Second option is if you intend to upgrade the JDK version higher than 1.8, you should get a NoClassDefFoundError, but that can be resolved if you are still using a JDK version not greater than 10. Jaxb API is now supposed to be an API of Java EE and classpath doesn't contain them by default. There is a way of enabling them however: How to resolve java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException in Java 9

就我而言,我通过在pom.xml中输入条目来提供对JAXB实现类的支持:

In my case, I provided support for JAXB implementation classes by making entry in pom.xml:

总而言之,我做了以下事情:

To summarize I did following:

  • 我继续将JDK 10与球衣2.3.1结合使用
  • 通过在POM中添加依赖项来提供对JAXB的支持:
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.1</version>
            <scope>runtime</scope>
        </dependency>

这篇关于jakarta.xml.bind.ContextFinder.handleClassCastException上的java.lang.NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆