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

Reply via email to