How do I configure Glassfish 5 to use Moxy as the default Provider?

不想你离开。 提交于 2021-02-20 02:20:06

问题


I’m migrating our web application from Glassfish 3 to Glassfish 5, and during the migration I ran across this error for a request.

[2019-09-17T15:57:30.732-0600] [glassfish 5.0] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=241 _ThreadName=http-listener-2(27)] [timeMillis: 1568757450732] [levelValue: 900] [[
 StandardWrapperValve[ClientControllers]: Servlet.service() for servlet ClientControllers threw exception
java.lang.ClassCastException: [Z cannot be cast to [Ljava.lang.Object;
   at org.eclipse.yasson.internal.serializer.ObjectArraySerializer.serializeInternal(ObjectArraySerializer.java:27)
   at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
   at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
   at org.eclipse.yasson.internal.serializer.ObjectSerializer.marshallProperty(ObjectSerializer.java:92)
   at org.eclipse.yasson.internal.serializer.ObjectSerializer.serializeInternal(ObjectSerializer.java:59)
   at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
   at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serializerCaptor(AbstractContainerSerializer.java:91)
   at org.eclipse.yasson.internal.serializer.ObjectArraySerializer.serializeInternal(ObjectArraySerializer.java:46)
   at org.eclipse.yasson.internal.serializer.ObjectArraySerializer.serializeInternal(ObjectArraySerializer.java:27)
   at org.eclipse.yasson.internal.serializer.AbstractContainerSerializer.serialize(AbstractContainerSerializer.java:60)
   at org.eclipse.yasson.internal.Marshaller.serializeRoot(Marshaller.java:118)
   at org.eclipse.yasson.internal.Marshaller.marshall(Marshaller.java:76)
   at org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:98)
   at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.writeTo(JsonBindingProvider.java:118)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:251)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
   at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:109)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
   at org.glassfish.jersey.spi.ContentEncoder.aroundWriteTo(ContentEncoder.java:137)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
   at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:85)
   at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:163)
   at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1135)
   at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662)
   at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:395)
   at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:385)
   at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:280)
   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:272)
   at org.glassfish.jersey.internal.Errors$1.call(Errors.java:268)
   at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
   at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
   at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
   at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
   at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
   at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
   at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
   at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
   at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
   at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
   at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
   at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:368)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
   at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
   at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
   at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224)
   at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
   at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
   at java.lang.Thread.run(Thread.java:745)
]]

It appears Glassfish 5 is using JSON-B serialization. Glassfish 5 ignores JAXB @XmlJavaTypeAdapter annotation?

In the past we used moxy and jaxb for json binding, and as a result I’ve been trying to register Moxy as the default provider in Glassfish 5. I’ve followed the instructions here with no luck.

https://howtodoinjava.com/jersey/jax-rs-jersey-moxy-json-example/

I also read the Glassfish 5 documentation, but did not find any similar examples for registering a default provider. If someone could shed some light on what I’m doing wrong in the configuration that would be greatly appreciated. I’ve provided samples of my configuration below.

How do I configure Glassfish 5 to use Moxy as the default Provider?

Notes:

  • When I start glassfish, I've debugged the JsonServicesContextResolver.java class and verified the constructor and getContext method are hit during initialization.
  • I've tried removing the GridApplication.java class and removing its references in the web.xml, thinking the jersey.config.server.provider.packages may already register any providers in those packages. I still had the same errors.

JsonServicesContextResolver.java

package com.lnka.eng.grid.jersey;

import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

@Provider
public class JsonServicesContextResolver
    implements ContextResolver<MoxyJsonConfig>
{
  private MoxyJsonConfig config;

  public JsonServicesContextResolver()
  {
    config = new MoxyJsonConfig()
        .setNamespaceSeparator(':')
        .setAttributePrefix("")
        .setValueWrapper("value")
        .property(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, true)
        .setFormattedOutput(true)
        .setIncludeRoot(true)
        .setMarshalEmptyCollections(true);
  }

  @Override
  public MoxyJsonConfig getContext(Class<?> objectType)
  {
    return config;
  }
}

ProgramsController.java

package com.lnka.eng.view.controller;

@Path("/mgmt/programs/")
@Stateless
@Transactional(Transactional.TxType.NOT_SUPPORTED)
public class ProgramsController extends Controller
{
 @GET
  @Path("/list/")
  @Produces(MediaType.APPLICATION_JSON)
  public Response getProgramsList()
  {
    List<Program> programs = getPrograms();

    return Response.ok(programs).build();    
  }
}

GridApplication.java

package com.lnka.eng.grid.jersey;

import com.lnka.eng.view.controller.ProgramsController;

import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

public class GridApplication extends Application
{
  //Add Service APIs
  @Override
  public Set<Class<?>> getClasses()
  {
    Set<Class<?>> resources = new HashSet<Class<?>>();

    //register REST modules
    resources.add(ProgramsController.class);

    //Manually adding MOXyJSONFeature
    resources.add(org.glassfish.jersey.moxy.json.MoxyJsonFeature.class);

    //Configure Moxy behavior
    resources.add(JsonServicesContextResolver.class);

    return resources;
  }
}

web.xml

I've removed some of the config in this file that I thought irrelevant (security, ejb config, etc)

<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">

  <display-name>Grid</display-name>  
  <servlet>
    <servlet-name>JerseyServiceApplications</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.core.Application</param-name>
      <param-value>com.lnka.eng.grid.jersey.GridApplication</param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.lnka.eng.grid.service;com.lnka.eng.grid.jersey</param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.classnames</param-name>
      <param-value>org.glassfish.jersey.message.GZipEncoder</param-value>
    </init-param>
    <init-param>
      <param-name>debug</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <servlet-name>ClientControllers</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.core.Application</param-name>
      <param-value>com.lnka.eng.grid.jersey.GridApplication</param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>
        com.lnka.eng.view.controller,
        com.lnka.eng.grid.jersey
      </param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.classnames</param-name>
      <param-value>
        org.glassfish.jersey.message.GZipEncoder
      </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>ClientControllers</servlet-name>
    <url-pattern>/client/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>JerseyServiceApplications</servlet-name>
    <url-pattern>/resources/*</url-pattern>
  </servlet-mapping>

  <session-config>
    <session-timeout>480</session-timeout>
  </session-config>
</web-app>

回答1:


The issue was we needed to update the web.xml to include the MoxyConfig in the session-config scope. I was also missing some configuration for one of our listeners, but the relevant code is below.

The following was placed inside each of the <servlet>...</servlet> tags.

<init-param>
      <param-name>jersey.config.server.jsonFeature</param-name>
      <param-value>MoxyJsonFeature</param-value>
</init-param>


来源:https://stackoverflow.com/questions/58083386/how-do-i-configure-glassfish-5-to-use-moxy-as-the-default-provider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!