I was trying to get something like this:

 

<entries>

  <entry key="c">d</entry>

  <entry key="a">b</entry>

</entries>

 

What I get with the workaround is this:

 

<entries>

  <entry>

    <key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xsi:type="xs:string">c</key>

    <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xsi:type="xs:string">d</value>

  </entry>

  <entry>

    <key xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xsi:type="xs:string">a</key>

    <value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
xmlns:xs="http://www.w3.org/2001/XMLSchema";
xsi:type="xs:string">b</value>

  </entry>

</entries>

 

I imagine there should be a straightforward way to get those namespaces
on the root element, instead of repeated here, but I haven't looked at
that yet.

 

From: Sergey Beryozkin [mailto:[email protected]] 
Sent: Monday, March 14, 2011 2:36 PM
To: [email protected]
Cc: KARR, DAVID (ATTSI)
Subject: Re: Getting NPE without stack trace while rendering, with no
Spring context

 

Great, can you post please the original structure expected and the
structure produced after the workaround ?

Just would like to see if the transformation feature [1] can be applied
or not...I'm still planning to investigate, at least to make sure the
stack trace is available...

Cheers, Sergey

[1] http://cxf.apache.org/docs/transformationfeature.html

On Mon, Mar 14, 2011 at 6:32 PM, KARR, DAVID (ATTSI) <[email protected]>
wrote:

> -----Original Message-----
> From: KARR, DAVID (ATTSI)
> Sent: Monday, March 14, 2011 8:45 AM
> To: [email protected]

> Subject: RE: Getting NPE without stack trace while rendering, with no
> Spring context
>
> > -----Original Message-----
> > From: Sergey Beryozkin [mailto:[email protected]]
> > Sent: Monday, March 14, 2011 5:29 AM
> > To: [email protected]
> > Subject: Re: Getting NPE without stack trace while rendering, with
no
> > Spring context
> >
> > > Can you please try and register a custom JAXBElementProvider with
> the
> > > JAXRSServerFactoryBean ? This provider will only extend
> > writeTo/ReadFrom and
> > > will have a try/catch block around super.writeFrom and readFrom ?
> > > I'll check the JAXBElementProvider, I think it has few catches for
> > > different types of exceptions including the Exception class - and
> in
> > this
> > > case it should indeed print a stacktrace...Letting users to
> configure
> > the
> > > default WebApplicationExceptionMapper for it to print the
> stacktraces
> > is
> > > another option...
> > >
> > >
> > I updated the code accordingly, but in meantime the easiest option
to
> > catch
> > the origin of the exception is to actually register a custom
> > WebAplicationExceptionMapper, i.e,
> > ExceptionMapper<WebApplicationException>
> > implementation (as a provider on the JAXRSServerFactoryBean) and
then
> > just
> > print the stack trace
>
> I'll implement this.
>
> In the meantime, I set a breakpoint on NPE in my debugger, so I at
> least
> know where this is happening, but I don't know why yet.
>
> This is mostly an excerpt from the post I sent to the jaxb-users list.
>
> I found that it was throwing the NPE at line 165 in class
> "com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor<BeanT>".
>
> That line is in this function (decompiled from class):
>
> /*     */   public static <T> TransducedAccessor<T>
get(JAXBContextImpl
> context, RuntimeNonElementRef ref)
> /*     */   {
> /* 153 */     Transducer xducer =
> RuntimeModelBuilder.createTransducer(ref);
> /* 154 */     RuntimePropertyInfo prop = ref.getSource();
> /*     */
> /* 156 */     if (prop.isCollection()) {
> /* 157 */       return new ListTransducedAccessorImpl(xducer,
> prop.getAccessor(),
> Lister.create(Navigator.REFLECTION.erasure(prop.getRawType()),
> prop.id(), prop.getAdapter()));
> /*     */     }
> /*     */
> /* 162 */     if (prop.id() == ID.IDREF) {
> /* 163 */       return new
> IDREFTransducedAccessorImpl(prop.getAccessor());
> /*     */     }
> /* 165 */     if ((xducer.isDefault()) && (!(context.fastBoot))) {
> /* 166 */       TransducedAccessor xa =
> OptimizedTransducedAccessorFactory.get(prop);
> /* 167 */       if (xa != null) return xa;
> /*     */     }
> /*     */
> /* 170 */     if (xducer.useNamespace()) {
> /* 171 */       return new
> CompositeContextDependentTransducedAccessorImpl(context, xducer,
> prop.getAccessor());
> /*     */     }
> /* 173 */     return new CompositeTransducedAccessorImpl(context,
> xducer, prop.getAccessor());
> /*     */   }
>
> The NPE happens because "xducer" is null.
>
> I googled this class, method, and line number, and I found one person
> on
> StackOverflow who got an NPE on the same line, but his situation seems
> to be slightly different.
>
> So, I figure I must have made a mistake in setting up the XmlAdapter.
>
> The following is where I declared the field I'm annotating:
>
>     @XmlElement(name = "myMap")
>     @XmlJavaTypeAdapter(HashMapStringStringAdapter.class)
>     private HashMap<String, String>     myMap;
>
> Here's the adapter class:
>
> public class HashMapStringStringAdapter extends
> XmlAdapter<HashMapType<String,String>,HashMap<String,String>> {
>
>     @Override
>     public HashMap<String, String> unmarshal(HashMapType<String,
> String>
> value) throws Exception {
>         HashMap<String, String> result  = new HashMap<String,
> String>();
>         for (HashMapEntryType<String, String> hashMapEntry :
> value.getEntries())
>             result.put(hashMapEntry.key, hashMapEntry.value);
>         return result;
>     }
>
>     @Override
>     public HashMapType<String, String> marshal(HashMap<String, String>
> value) throws Exception {
>         HashMapType<String, String> result  = new HashMapType<String,
> String>();
>         for (Map.Entry<String, String> entry : value.entrySet())
>             result.put(entry.getKey(), entry.getValue());
>         return result;
>     }
> }
>
> Here's the HashMapType:
>
> public class HashMapType<K,V> {
>     private List<HashMapEntryType<K,V>> entries = new
> ArrayList<HashMapEntryType<K,V>>();
>     public List<HashMapEntryType<K,V>> getEntries() { return entries;
}
>     public void setEntries(List<HashMapEntryType<K,V>> entries) {
> this.entries = entries; }
>     public void put(K key, V value) {
>         getEntries().add(new HashMapEntryType<K,V>(key, value));
>     }
> }
>
> And the HashMapEntryType:
>
> public class HashMapEntryType<K,V> {
>     @XmlAttribute
>     public K   key;
>     @XmlValue
>     public V   value;
>     public HashMapEntryType() {}
>     public HashMapEntryType(K key, V value) {
>         this.key    = key;
>         this.value  = value;
>     }
> }
>
> Anyone have any idea what I might be doing wrong?

I've found a workaround for this.  I changed the two annotations in
HashMapEntryType to both be @XmlElement. It's not the structure I
wanted, but I also need it to work.  Changing only one of them to
@XmlElement doesn't fix the problem.




-- 
Sergey Beryozkin

Application Integration Division of Talend <http://www.talend.com> 
http://sberyozkin.blogspot.com

Reply via email to