You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Sergey Beryozkin (JIRA)" <ji...@apache.org> on 2017/05/12 10:13:04 UTC
[jira] [Resolved] (CXF-7368) JAXB provider is handling non-jaxb
classes
[ https://issues.apache.org/jira/browse/CXF-7368?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sergey Beryozkin resolved CXF-7368.
-----------------------------------
Resolution: Fixed
Assignee: Sergey Beryozkin
Fix Version/s: 3.0.14
3.1.12
3.2.0
> JAXB provider is handling non-jaxb classes
> ------------------------------------------
>
> Key: CXF-7368
> URL: https://issues.apache.org/jira/browse/CXF-7368
> Project: CXF
> Issue Type: Bug
> Components: JAX-RS
> Affects Versions: 3.1.11
> Reporter: Lukas Rohner
> Assignee: Sergey Beryozkin
> Fix For: 3.2.0, 3.1.12, 3.0.14
>
>
> The default JSONProvider is trying to marshal a non-jaxb class which results in a 500 response of my endpoint.
> One of my endpoints is returning a StreamingOutput object to the response object:
> {noformat}
> public static Response okJson(JValue json) {
> return Response.ok(new StreamingOutput() {
> @Override
> public void write(OutputStream s) throws IOException, WebApplicationException {
> try (final BufferedOutputStream bs = new BufferedOutputStream(s)) {
> serializer.fn.toJson(json).apply(bs);
> }
> }
> }, MediaType.APPLICATION_JSON_TYPE).build();
> }
> {noformat}
> Unfortunately, the default JSONProvider is trying to marshal this class because it thinks it is a jaxb supported class. This support check happens in the AbstractJAXBProvider class:
> {noformat}
> protected boolean isSupported(Class<?> type, Type genericType, Annotation[] anns) {
> if (jaxbElementClassMap != null && jaxbElementClassMap.containsKey(type.getName())
> || isSkipJaxbChecks()) {
> return true;
> }
> return isXmlRoot(type)
> || JAXBElement.class.isAssignableFrom(type)
> || objectFactoryOrIndexAvailable(type)
> || (type != genericType && objectFactoryForType(genericType))
> || org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(type, anns) != null;
>
> }
> protected boolean objectFactoryOrIndexAvailable(Class<?> type) {
> return type.getResource("ObjectFactory.class") != null
> || type.getResource("jaxb.index") != null;
> }
> {noformat}
> The issue is that the objectFactoryOrIndexAvailable is returning true which doesn't indicate that the type itself is a jaxb class. To fix the support method it should actually check if there is a jaxb.index file and if in the index file the current type is available. Then we can clearly say it's a jaxb supported class.
> Something like this:
> {noformat}
> return isXmlRoot(type)
> || JAXBElement.class.isAssignableFrom(type)
> || (objectFactoryOrIndexAvailable(type) && indexContainsType(type))
> || (type != genericType && objectFactoryForType(genericType))
> || org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(type, anns) != null;
> protected boolean indexContainsType(Class<?> type) {
> try (BufferedReader reader = new BufferedReader(new InputStreamReader(type.getResourceAsStream("jaxb.index")))) {
> String line = null;
> while((line = reader.readLine()) != null) {
> if(line.contains(type.getName()))
> return true;
> }
> }
> return false;
> }
> {noformat}
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)