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