问题
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