You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Vjacheslav V. Borisov" <sl...@gmail.com> on 2016/03/21 07:05:14 UTC

catalogLocation in JAXB/JSON Provider and @SchemaValidation

Playing with xml catalogs,  found strage bug (or my misconfiguration, i
don't know)

When i place  my  catalog on default DEFAULT_CATALOG_LOCATION
(classpath:META-INF/jax-rs-catalog.xml),
it works in @SchemaValidation feature

but if I want to rename to custom location, eg
<bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
...
        <property name="catalogLocation"
value="classpath:schemas/jparestresource/catalog.xml"/>
    </bean>
(and same for <bean id="jsonProvider"
class="org.apache.cxf.jaxrs.provider.json.JSONProvider"> )


It stops working.

I see in debugger that my value of catalogLocation passed to both providers
(enter to org.apache.cxf.jaxrs.provider.setSchemaLocations twice), but then
it initializes third provider (!)
with catalogLocation is set to null
and @SchemaValidation initailization fails (Cannot resolve the name '...'
to a(n) 'type definition' component. - this is becouse of catalog
unavaliable)
(also see  WARN  o.a.cxf.jaxrs.utils.ResourceUtils - No resource
classpath:META-INF/jax-rs-catalog.xml is available)

I look at org.apache.cxf.jaxrs.provider.ProviderFactory.initProviders and
see that there two copies of both providers (JAXB and JSON)
one with configured catalogLocation, and second with set to null

This is my configuration
https://github.com/ilb/jparestresource/blob/master/jparestresource-ws/src/main/webapp/WEB-INF/beans.xml

I have only two providers,
<bean id="jaxbProvider" class="
org.apache.cxf.jaxrs.provider.JAXBElementProvider">
and
<bean id="jsonProvider" class="
org.apache.cxf.jaxrs.provider.json.JSONProvider">

why I see unconfigured copies of these providers? who is placing them?

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by "Vjacheslav V. Borisov" <sl...@gmail.com>.
2016-03-23 18:26 GMT+04:00 Sergey Beryozkin <sb...@gmail.com>:

>
> I'm not sure what happens when you use @SchemaValidation and no schema
> holder. Can you please put a breakpoint in AbstractJaxbProvider.init() and
> see how SchemaValidation is processed. I can imagine that a schema will be
> loaded 4 times in this case - twice for default providers and twice for the
> same providers loaded from Spring
>
Yes, it is. And third time I am geting exception due to unconfigured
catalog. Now I am understand.


>
> but also, as I mentioned it is really better to use a schema holder in
> this case - only user registered providers will be set-up with a shared
> schema reference.
>

I agree, I removed annotaion @SchemaValidation and configured SchemaHandler
in spring

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 23/03/16 15:04, Vjacheslav V. Borisov wrote:
> 2016-03-23 15:48 GMT+04:00 Sergey Beryozkin <sb...@gmail.com>:
>
>> Thanks for the analysis and the patch, I'm traveling so will look into it
>> in detail next week (though might apply the patch earlier), does your patch
>> addresses all of your concerns you raised in this thread ?
>>
>>
> Yes, counting that for first I found suitable workaround.
>
I applied your patch, thanks.

When you have both JAXB and JSON providers explicitly configured, using 
a schema holder is the most optimal approach, the schema is loaded once, 
and is shared between the two providers.

The JAX-RS runtime must support JAXB OOB, i.e, users should not be 
forced to register JAXB providers for JAXB to be supported, hence when 
you start the server JAXBElementProvider with the default settings is 
loaded. JSONProvider is only loaded if Jettison is on the classpath.

So you start the server and you have at least JAXBElementProvider and 
other required providers already loaded.

What you configure in Spring are different instances, these are 
user-registered providers which are often preferred to the default 
providers, as in the case of JAXB/etc.

I'm not sure what happens when you use @SchemaValidation and no schema 
holder. Can you please put a breakpoint in AbstractJaxbProvider.init() 
and see how SchemaValidation is processed. I can imagine that a schema 
will be loaded 4 times in this case - twice for default providers and 
twice for the same providers loaded from Spring

but also, as I mentioned it is really better to use a schema holder in 
this case - only user registered providers will be set-up with a shared 
schema reference.



Cheers, Sergey


Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by "Vjacheslav V. Borisov" <sl...@gmail.com>.
2016-03-23 15:48 GMT+04:00 Sergey Beryozkin <sb...@gmail.com>:

> Thanks for the analysis and the patch, I'm traveling so will look into it
> in detail next week (though might apply the patch earlier), does your patch
> addresses all of your concerns you raised in this thread ?
>
>
Yes, counting that for first I found suitable workaround.

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by Sergey Beryozkin <sb...@gmail.com>.
Thanks for the analysis and the patch, I'm traveling so will look into 
it in detail next week (though might apply the patch earlier), does your 
patch addresses all of your concerns you raised in this thread ?

Cheers, Sergey

On 23/03/16 08:21, Vjacheslav V. Borisov wrote:
>> Don't know, how should this fixed (or should not)
>> E.g. , code like this could fix that, but seems ugly:
>> resolvedLocation =
>> catalogResolver.resolvePublic(publicId!=null?publicId:namespaceURI,
>> systemId);
>>
>>
> Found where it takes place in case of cxf-wadl2java-plugin,
> please see SchemaCompilerImpl.bind(), it passes namespaceURI as publicId
> parameter, while SchemaHandler passes publicId as publicId, which is null,
> and resolve does not takes place.
> http://grepcode.com/file/repo1.maven.org/maven2/com.sun.xml.bind/jaxb-xjc/2.2.11/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java
>
> I submitted my patch  https://issues.apache.org/jira/browse/CXF-6840
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by "Vjacheslav V. Borisov" <sl...@gmail.com>.
> Don't know, how should this fixed (or should not)
> E.g. , code like this could fix that, but seems ugly:
> resolvedLocation =
> catalogResolver.resolvePublic(publicId!=null?publicId:namespaceURI,
> systemId);
>
>
Found where it takes place in case of cxf-wadl2java-plugin,
please see SchemaCompilerImpl.bind(), it passes namespaceURI as publicId
parameter, while SchemaHandler passes publicId as publicId, which is null,
and resolve does not takes place.
http://grepcode.com/file/repo1.maven.org/maven2/com.sun.xml.bind/jaxb-xjc/2.2.11/com/sun/tools/xjc/api/impl/s2j/SchemaCompilerImpl.java

I submitted my patch  https://issues.apache.org/jira/browse/CXF-6840

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by "Vjacheslav V. Borisov" <sl...@gmail.com>.
Also noticed following :

When wadl2java code generation  resolves <xsd:import
namespace="urn:ru:ilb:basicuuid:basicuuid"/>
using  xml-resolver, it resolves it using publicId using this record in
catalog.xml
<public publicId="urn:ru:ilb:basicuuid:basicuuid"
uri="classpath:schemas/basicuuid/basicuuid.xsd" />
This is the code:
class org.apache.xml.resolver.Catalog, method resolveLocalPublic,

    while (en.hasMoreElements()) {
...
      if (e.getEntryType() == PUBLIC
      && e.getEntryArg(0).equals(publicId)) {
    if (over || systemId == null) {
      return e.getEntryArg(1);
    }
      }
    }

and here publicId variable equals "urn:ru:ilb:basicuuid:basicuuid".

But in runtime, in org.apache.cxf.jaxrs.utils.schemas.SchemaHandler, method
createSchema
it resolves it using LSResourceResolver.resolveResource
and, surprisingly, publicId here is null, but
namespaceURI="urn:ru:ilb:basicuuid:basicuuid", and I can only resolve
schema using <uri> catalog entry
Don't  know why different processors resovle imports differently.
Looking here,
https://jaxb.java.net/guide/Fixing_broken_references_in_schema.html
it says that only public entry in catalog required.

But, to resolve schema import both in runtime and during class compilation,
i need to write in catalog.xml two entries:

    <!-- this is for xsd compilation -->
    <public publicId="urn:ru:ilb:basicuuid:basicuuid"
uri="classpath:schemas/basicuuid/basicuuid.xsd" />
    <!-- this is for SchemaHandler -->
    <uri name="urn:ru:ilb:basicuuid:basicuuid"
uri="classpath:schemas/basicuuid/basicuuid.xsd" />

Don't know, how should this fixed (or should not)
E.g. , code like this could fix that, but seems ugly:
resolvedLocation =
catalogResolver.resolvePublic(publicId!=null?publicId:namespaceURI,
systemId);

Re: catalogLocation in JAXB/JSON Provider and @SchemaValidation

Posted by "Vjacheslav V. Borisov" <sl...@gmail.com>.
Found workaround, removed @SchemaValidation annotaion and configured both
providers in spring, so unconfigured copies now do not crash.
Also noticed that
http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Schemavalidation
contains deprecated
<bean id="schemaHolder" class=
"org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
   <property name="schemas" ref="theSchemas"/>
</bean>

name="schemas" should be replaced with name="schemaLocations" (which has
catalogLocation support)


2016-03-21 10:05 GMT+04:00 Vjacheslav V. Borisov <sl...@gmail.com>:

> Playing with xml catalogs,  found strage bug (or my misconfiguration, i
> don't know)
>