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

Reply via email to